1 /*---------------------------------------------------------------------------*
2 Project: HIO2 demos - dual
3 File: dual.cpp
4
5 (C)2005 HUDSON SOFT
6
7 $Header: /home/cvsroot/SDK/build/demos/hio2demo/vc++/dual/dual.cpp,v 1.3 2006/03/15 06:31:26 mitu Exp $
8
9 $NoKeywords: $
10 *---------------------------------------------------------------------------*/
11
12 // dual.cpp : Defines the class behaviors for the application.
13 //
14
15 #include "stdafx.h"
16 #include "dual.h"
17 #include "MainFrm.h"
18
19 #include "dualDoc.h"
20 #include "dualView.h"
21 #include ".\dual.h"
22
23 #ifdef _DEBUG
24 #define new DEBUG_NEW
25 #endif
26
27 ///////// for dualApp /////////
28
29 ///////////////////////////////////////////////////////////////////////////////
30 //
31 // local function and thread function definition
32 //
33
34 // Get active view
35 static
GetActiveView()36 CDualView* GetActiveView()
37 {
38 POSITION pos;
39 CDocTemplate* pDocTemplate;
40 CDualDoc* pDoc;
41
42 // Document Template
43 pos = GetApp()->GetFirstDocTemplatePosition();
44 if ( pos == NULL ) return NULL;
45 pDocTemplate = GetApp()->GetNextDocTemplate(pos);
46
47 // Document
48 pos = pDocTemplate->GetFirstDocPosition();
49 if ( pos == NULL ) return NULL;
50 pDoc = static_cast<CDualDoc *>(pDocTemplate->GetNextDoc(pos));
51
52 // View
53 pos = pDoc->GetFirstViewPosition();
54 if ( pos == NULL ) return NULL;
55 return static_cast<CDualView *>(pDoc->GetNextView(pos));
56 }
57
58 // CHioIf::HIOIF_EVENT_CALLBACK
59 static
HioIfEventCallback(HIO2IF_ID id,HIO2IF_EVENT event)60 void HioIfEventCallback(HIO2IF_ID id, HIO2IF_EVENT event)
61 {
62 CDualView* pView;
63 if ( (pView=GetActiveView()) == NULL ) return ;
64
65 CDualApp* pApp = GetApp();
66
67 switch ( event )
68 {
69 case HIO2IF_EVENT_CONNECT: // connection established
70 {
71 BYTE clearBuf[DUAL_BUFFER_SIZE];
72 DWORD dwAddr;
73
74 // activate the View static text and button when connected to NNGC
75
76 // when open mode is write only
77 if ( pApp->m_pHioIf->GetOpenMode(id) == HIO2IF_MODE_WRONLY )
78 {
79 pApp->m_nSendID = id;
80 dwAddr = DUAL_PC2NNGC_ADDR;
81 if ( (pView=GetActiveView()) != NULL )
82 {
83 pView->PostMessage(WM_USER, CDualView::EVENT_SET_SEND_STATUS,
84 CDualView::EVENT_CONNECT);
85 }
86 }
87 else
88 {
89 pApp->m_nRecvID = id;
90 dwAddr = DUAL_NNGC2PC_ADDR;
91 if ( (pView=GetActiveView()) != NULL )
92 {
93 pView->PostMessage(WM_USER, CDualView::EVENT_SET_RECV_STATUS,
94 CDualView::EVENT_CONNECT);
95
96 pView->PostMessage(WM_USER, CDualView::EVENT_VALID_RECV_COLOR, 0);
97 }
98 }
99
100 // clear the RGB data settings region
101 ZeroMemory(clearBuf, sizeof(clearBuf));
102 pApp->m_pHioIf->WriteFree(id, dwAddr, clearBuf, DUAL_BUFFER_SIZE, FALSE);
103 }
104 break;
105 case HIO2IF_EVENT_DISCONNECT: // connection released
106 GetApp()->Disconnect(id);
107 break;
108 case HIO2IF_EVENT_RECEIVED: // Data reception
109 {
110 HIO2IF_RESULT result;
111
112 if ( pApp->m_nRecvID != HIO2IF_INVALID_ID )
113 {
114 result = pApp->m_pHioIf->Read(pApp->m_nRecvID,
115 DUAL_NNGC2PC_ADDR, pApp->m_byRecvBuf,
116 DUAL_BUFFER_SIZE, pApp->m_bSync);
117
118 if ( HIO2IF_SUCCESS(result) && !pApp->m_bSync )
119 {
120 if ( (pView=GetActiveView()) != NULL )
121 {
122 pView->PostMessage(WM_USER, CDualView::EVENT_UPDATE_COLOR, (LPARAM)
123 RGB(
124 pApp->m_byRecvBuf[DUAL_DATA_IDX_RED],
125 pApp->m_byRecvBuf[DUAL_DATA_IDX_GREEN],
126 pApp->m_byRecvBuf[DUAL_DATA_IDX_BLUE]
127 )
128 );
129 }
130 }
131 }
132 }
133 break;
134 case HIO2IF_EVENT_READ_ASYNC_DONE:
135 if ( (pView=GetActiveView()) != NULL )
136 {
137 pView->PostMessage(WM_USER, CDualView::EVENT_UPDATE_COLOR, (LPARAM)
138 RGB(
139 pApp->m_byRecvBuf[DUAL_DATA_IDX_RED],
140 pApp->m_byRecvBuf[DUAL_DATA_IDX_GREEN],
141 pApp->m_byRecvBuf[DUAL_DATA_IDX_BLUE]
142 )
143 );
144 }
145 break;
146 case HIO2IF_EVENT_WRITE_ASYNC_DONE:
147 case HIO2IF_EVENT_SEND_POSSIBLE: // send possible
148 default:
149 break;
150 }
151 }
152
153 // ReadFree thread
154 static
ReadFreeThread(LPVOID pHandle)155 DWORD WINAPI ReadFreeThread( LPVOID pHandle )
156 {
157 CDualApp* pApp = static_cast<CDualApp *>(pHandle);
158
159 pApp->m_bThreadBreak = FALSE;
160 while ( !pApp->m_bThreadBreak )
161 {
162 HIO2IF_RESULT result;
163
164 if ( pApp->m_nRecvID != HIO2IF_INVALID_ID )
165 {
166 result = pApp->m_pHioIf->ReadFree(pApp->m_nRecvID,
167 DUAL_NNGC2PC_ADDR, pApp->m_byRecvBuf,
168 DUAL_BUFFER_SIZE, pApp->m_bSync);
169
170 if ( HIO2IF_SUCCESS(result) )
171 {
172 // reflect the received RGB data in View
173 CDualView* pView = GetActiveView();
174 if ( (pView != NULL) && !pApp->m_bSync )
175 {
176 pView->PostMessage(WM_USER, CDualView::EVENT_UPDATE_COLOR,
177 (LPARAM)RGB(
178 pApp->m_byRecvBuf[DUAL_DATA_IDX_RED],
179 pApp->m_byRecvBuf[DUAL_DATA_IDX_GREEN],
180 pApp->m_byRecvBuf[DUAL_DATA_IDX_BLUE]
181 )
182 );
183 }
184 }
185 }
186
187 // Read for roughly each 1V
188 Sleep(1000 / 60);
189 }
190
191 return 0;
192 }
193
194 //-----------------------------------------------------------------------------
HioIfInit()195 BOOL CDualApp::HioIfInit()
196 {
197 // initialization
198 if ( HIO2IF_FAILED(m_pHioIf->Init()) ) return FALSE;
199
200 m_nIDCount = 0;
201 m_nSendID = m_nRecvID = HIO2IF_INVALID_ID;
202 m_nOpenID[0] = m_nOpenID[1] = HIO2IF_INVALID_ID;
203
204 // open the detected number of channels or the APP_HIOIF_MAX number of channels
205 for (int i=0; (i<m_pHioIf->GetDeviceCount() && i<APP_HIOIF_MAX); i++)
206 {
207 if ( HIO2IF_FAILED(m_pHioIf->Open(m_pHioIf->GetDevicePath(i),
208 HioIfEventCallback, (int)m_nOpenID[i])) )
209 return FALSE;
210 m_nIDCount++;
211 }
212
213 #ifndef PROTOCOL_USED
214 // within a set period create a dummy thread to run CHioIf -> ReadFree()
215 DWORD dwTmp;
216
217 m_bThreadBreak = TRUE;
218 m_hThread = ::CreateThread(NULL, 0, ReadFreeThread, (LPVOID)this, 0, &dwTmp);
219
220 // wait until thread launches
221 // set m_bThreadBreak to FALSE within the ReadFreeThread function)
222 while ( m_bThreadBreak ) ;
223
224 #endif // PROTOCOL_USED
225 // when protocol communication is taking place, use HIOIF_EVENT_CALLBACK to go from CHioIf to Read
226 // to Read
227
228 return TRUE;
229 }
230
231 //-----------------------------------------------------------------------------
HioIfExit()232 BOOL CDualApp::HioIfExit()
233 {
234 // terminate thread if ReadFreeThread is valid
235 StopReadFreeThread();
236
237 m_pHioIf->EnterCriticalSection();
238 m_pHioIf->Exit(); // HIO termination
239 m_pHioIf->LeaveCriticalSection();
240
241 return TRUE;
242 }
243
244 //-----------------------------------------------------------------------------
StopReadFreeThread()245 void CDualApp::StopReadFreeThread()
246 {
247 #ifndef PROTOCOL_USED
248 // terminate thread if ReadFreeThread is valid
249 if ( m_hThread != INVALID_HANDLE_VALUE )
250 {
251 // halt the EXI thread
252 m_bThreadBreak = TRUE;
253 WaitForSingleObject(m_hThread,1000*30);
254 CloseHandle(m_hThread);
255 m_hThread = INVALID_HANDLE_VALUE;
256 }
257 #endif // PROTOCOL_USED
258 }
259
260 //-----------------------------------------------------------------------------
SendRGB(LPRGBQUAD pRGB)261 HIO2IF_RESULT CDualApp::SendRGB(LPRGBQUAD pRGB)
262 {
263 HIO2IF_RESULT ret;
264 m_bySendBuf[DUAL_DATA_IDX_RED] = pRGB->rgbRed;
265 m_bySendBuf[DUAL_DATA_IDX_GREEN] = pRGB->rgbGreen;
266 m_bySendBuf[DUAL_DATA_IDX_BLUE] = pRGB->rgbBlue;
267
268 m_pHioIf->EnterCriticalSection();
269 #ifdef PROTOCOL_USED
270 ret = m_pHioIf->Write(m_nSendID, DUAL_PC2NNGC_ADDR, m_bySendBuf,
271 DUAL_BUFFER_SIZE, m_bSync);
272 #else // PROTOCOL_USED
273 ret = m_pHioIf->WriteFree(m_nSendID, DUAL_PC2NNGC_ADDR, m_bySendBuf,
274 DUAL_BUFFER_SIZE, m_bSync);
275 #endif // PROTOCOL_USED
276 m_pHioIf->LeaveCriticalSection();
277
278 return ret;
279 }
280
281
282 //-----------------------------------------------------------------------------
GetStatus(APP_HIOIF_TYPE nType)283 LPCSTR CDualApp::GetStatus(APP_HIOIF_TYPE nType)
284 {
285 // get the status of send, receive channels as text strings
286
287 static TCHAR l_szStatus[128];
288 static LPCSTR l_lpszDeviceName[HIO2_CHAN_MAX + 2] =
289 { "UNKOWN", "EXI2USB0", "EXI2USB1", "MrEXI" };
290
291 LPCSTR lpszStatus, lpszExiDev;
292 int nPcChan;
293 HIO2IF_ID nID;
294
295 nID = (nType == APP_HIOIF_SEND) ? m_nSendID : m_nRecvID;
296
297 // receive channel state
298 if ( nID != HIO2IF_INVALID_ID)
299 {
300 lpszStatus = "CONNECT";
301 nPcChan = m_pHioIf->GetPcChan(nID);
302 lpszExiDev = l_lpszDeviceName[m_pHioIf->GetDeviceType(nID) + 1];
303 }
304 // to open with a priority for NNGC receive (PC send)
305 else if ( m_nIDCount > nType )
306 {
307 lpszStatus = "DISCONNECT";
308 nPcChan = m_pHioIf->GetPcChan(m_nOpenID[nType]);
309 lpszExiDev = l_lpszDeviceName[m_pHioIf->GetDeviceType(nID) + 1];
310 }
311 else
312 {
313 lpszStatus = "NOT FIND";
314 nPcChan = -1;
315 lpszExiDev = "UNKOWN";
316 }
317
318 sprintf(l_szStatus,"%s CHAN : %s, PC%d, NNGC %s",
319 ((nType == 0) ? "SEND" : "RECV"), lpszStatus, nPcChan, lpszExiDev);
320
321 return l_szStatus;
322 }
323
324 //-----------------------------------------------------------------------------
Disconnect(HIO2IF_ID id)325 void CDualApp::Disconnect(HIO2IF_ID id)
326 {
327 if ( id == HIO2IF_INVALID_ID ) return ;
328
329 CDualView* pView;
330
331 // send ID
332 if ( id == m_nSendID )
333 {
334 m_pHioIf->Close(m_nSendID);
335 m_nSendID = HIO2IF_INVALID_ID;
336 if ( (pView=GetActiveView()) != NULL )
337 {
338 pView->PostMessage(WM_USER, CDualView::EVENT_SET_SEND_STATUS,
339 CDualView::EVENT_DISCONNECT);
340 }
341 }
342 // receive ID
343 else if ( id == m_nRecvID )
344 {
345 StopReadFreeThread();
346 m_pHioIf->Close(m_nRecvID);
347 m_nRecvID = HIO2IF_INVALID_ID;
348
349 if ( (pView=GetActiveView()) != NULL )
350 {
351 pView->PostMessage(WM_USER, CDualView::EVENT_SET_RECV_STATUS,
352 CDualView::EVENT_DISCONNECT);
353 pView->PostMessage(WM_USER, CDualView::EVENT_INVALID_RECV_COLOR,
354 CDualView::EVENT_DISCONNECT);
355 }
356 }
357 }
358
359 ///////////////////////////////////////////////////////////////////////////////
360 //
361 // CDualApp
362 //
363
BEGIN_MESSAGE_MAP(CDualApp,CWinApp)364 BEGIN_MESSAGE_MAP(CDualApp, CWinApp)
365 ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
366 // Standard file based document commands
367 ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
368 ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
369 END_MESSAGE_MAP()
370
371
372 // CDualApp construction
373
374 CDualApp::CDualApp()
375 {
376 ////////// for dualApp //////////
377 m_pHioIf = NULL;
378 m_bSync = FALSE;
379 m_nIDCount = 0;
380 m_nSendID = m_nRecvID = HIO2IF_INVALID_ID;
381 m_nOpenID[0] = m_nOpenID[1] = HIO2IF_INVALID_ID;
382 }
383
384
385 // The one and only CDualApp object
386
387 CDualApp theApp;
388
389 // CDualApp initialization
390
InitInstance()391 BOOL CDualApp::InitInstance()
392 {
393 // InitCommonControls() is required on Windows XP if an application
394 // manifest specifies use of ComCtl32.dll version 6 or later to enable
395 // visual styles. Otherwise, any window creation will fail.
396 InitCommonControls();
397
398 CWinApp::InitInstance();
399
400 // Initialize OLE libraries
401 if (!AfxOleInit())
402 {
403 AfxMessageBox(IDP_OLE_INIT_FAILED);
404 return FALSE;
405 }
406 AfxEnableControlContainer();
407 // Standard initialization
408 // If you are not using these features and wish to reduce the size
409 // of your final executable, you should remove from the following
410 // the specific initialization routines you do not need
411 // Change the registry key under which our settings are stored
412 // TODO : You should modify this string to be something appropriate
413 // such as the name of your company or organization
414 SetRegistryKey(_T("Local AppWizard-Generated Applications"));
415 LoadStdProfileSettings(0); // Load standard INI file options (including MRU)
416
417 ////////// for dualApp //////////
418 // initialization
419 m_pHioIf = Hio2CreateInterface();
420 if ( !HioIfInit() )
421 {
422 MessageBox(NULL, m_pHioIf->GetMessage(), "ERROR", (MB_OK | MB_ICONWARNING));
423 return FALSE;
424 }
425
426 // Register the application's document templates. Document templates
427 // serve as the connection between documents, frame windows and views
428 CSingleDocTemplate* pDocTemplate;
429 pDocTemplate = new CSingleDocTemplate(
430 IDR_MAINFRAME,
431 RUNTIME_CLASS(CDualDoc),
432 RUNTIME_CLASS(CMainFrame), // main SDI frame window
433 RUNTIME_CLASS(CDualView));
434 if (!pDocTemplate)
435 return FALSE;
436 AddDocTemplate(pDocTemplate);
437 // Parse command line for standard shell commands, DDE, file open
438 CCommandLineInfo cmdInfo;
439 ParseCommandLine(cmdInfo);
440 // Dispatch commands specified on the command line. Will return FALSE if
441 // app was launched with /RegServer, /Register, /Unregserver or /Unregister.
442 if (!ProcessShellCommand(cmdInfo))
443 return FALSE;
444
445 ////////// for dualApp //////////
446 // default settings for send/receive status
447 POSITION pos = pDocTemplate->GetFirstDocPosition();
448 CDualDoc* pDoc = static_cast<CDualDoc *>(pDocTemplate->GetNextDoc(pos));
449 pos = pDoc->GetFirstViewPosition();
450 CDualView* pView = static_cast<CDualView *>(pDoc->GetNextView(pos));
451 pView->PostMessage(WM_USER, CDualView::EVENT_SET_SEND_STATUS, 0);
452 pView->PostMessage(WM_USER, CDualView::EVENT_SET_RECV_STATUS, 0);
453
454 // The one and only window has been initialized, so show and update it
455 m_pMainWnd->ShowWindow(SW_SHOW);
456 m_pMainWnd->UpdateWindow();
457 // call DragAcceptFiles only if there's a suffix
458 // In an SDI app, this should occur after ProcessShellCommand
459 return TRUE;
460 }
461
462 // CDualApp message handlers
463
464
ExitInstance()465 int CDualApp::ExitInstance()
466 {
467 ////////// for dualApp //////////
468 HioIfExit();
469 Hio2ReleaseInterface(m_pHioIf);
470
471 return CWinApp::ExitInstance();
472 }
473
474 // CAboutDlg dialog used for App About
475
476 class CAboutDlg : public CDialog
477 {
478 public:
479 CAboutDlg();
480
481 // Dialog Data
482 enum { IDD = IDD_ABOUTBOX };
483
484 protected:
485 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
486
487 // Implementation
488 protected:
489 DECLARE_MESSAGE_MAP()
490 };
491
CAboutDlg()492 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
493 {
494 }
495
DoDataExchange(CDataExchange * pDX)496 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
497 {
498 CDialog::DoDataExchange(pDX);
499 }
500
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)501 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
502 END_MESSAGE_MAP()
503
504 // App command to run the dialog
505 void CDualApp::OnAppAbout()
506 {
507 CAboutDlg aboutDlg;
508 aboutDlg.DoModal();
509 }
510
511