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.4 2007/11/26 13:56:27 iwai_yuma 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: // Establish connection
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: // Receive data
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 // Create a thread to run CHioIf -> ReadFree() within a set period
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 call CHioIf->Read
226 //
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 // Because NNGC opens Receive (Send for PC) with priority
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_s( l_szStatus, sizeof(l_szStatus), "%s CHAN : %s PC%d, NNGC %s",
319 ((nType == 0) ? "SEND" : "RECV"), lpszStatus, nPcChan, lpszExiDev );
320 // sprintf(l_szStatus,"%s CHAN : %s, PC%d, NNGC %s",
321 // ((nType == 0) ? "SEND" : "RECV"), lpszStatus, nPcChan, lpszExiDev);
322
323 return l_szStatus;
324 }
325
326 //-----------------------------------------------------------------------------
Disconnect(HIO2IF_ID id)327 void CDualApp::Disconnect(HIO2IF_ID id)
328 {
329 if ( id == HIO2IF_INVALID_ID ) return ;
330
331 CDualView* pView;
332
333 // Send ID
334 if ( id == m_nSendID )
335 {
336 m_pHioIf->Close(m_nSendID);
337 m_nSendID = HIO2IF_INVALID_ID;
338 if ( (pView=GetActiveView()) != NULL )
339 {
340 pView->PostMessage(WM_USER, CDualView::EVENT_SET_SEND_STATUS,
341 CDualView::EVENT_DISCONNECT);
342 }
343 }
344 // Receive ID
345 else if ( id == m_nRecvID )
346 {
347 StopReadFreeThread();
348 m_pHioIf->Close(m_nRecvID);
349 m_nRecvID = HIO2IF_INVALID_ID;
350
351 if ( (pView=GetActiveView()) != NULL )
352 {
353 pView->PostMessage(WM_USER, CDualView::EVENT_SET_RECV_STATUS,
354 CDualView::EVENT_DISCONNECT);
355 pView->PostMessage(WM_USER, CDualView::EVENT_INVALID_RECV_COLOR,
356 CDualView::EVENT_DISCONNECT);
357 }
358 }
359 }
360
361 ///////////////////////////////////////////////////////////////////////////////
362 //
363 // CDualApp
364 //
365
BEGIN_MESSAGE_MAP(CDualApp,CWinApp)366 BEGIN_MESSAGE_MAP(CDualApp, CWinApp)
367 ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
368 // Standard file based document commands
369 ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
370 ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
371 END_MESSAGE_MAP()
372
373
374 // CDualApp construction
375
376 CDualApp::CDualApp()
377 {
378 ////////// for dualApp //////////
379 m_pHioIf = NULL;
380 m_bSync = FALSE;
381 m_nIDCount = 0;
382 m_nSendID = m_nRecvID = HIO2IF_INVALID_ID;
383 m_nOpenID[0] = m_nOpenID[1] = HIO2IF_INVALID_ID;
384 }
385
386
387 // The one and only CDualApp object
388
389 CDualApp theApp;
390
391 // CDualApp initialization
392
InitInstance()393 BOOL CDualApp::InitInstance()
394 {
395 // InitCommonControls() is required on Windows XP if an application
396 // manifest specifies use of ComCtl32.dll version 6 or later to enable
397 // visual styles. Otherwise, any window creation will fail.
398 InitCommonControls();
399
400 CWinApp::InitInstance();
401
402 // Initialize OLE libraries
403 if (!AfxOleInit())
404 {
405 AfxMessageBox(IDP_OLE_INIT_FAILED);
406 return FALSE;
407 }
408 AfxEnableControlContainer();
409 // Standard initialization
410 // If you are not using these features and wish to reduce the size
411 // of your final executable, you should remove from the following
412 // the specific initialization routines you do not need
413 // Change the registry key under which our settings are stored
414 // TODO: You should modify this string to be something appropriate
415 // such as the name of your company or organization
416 SetRegistryKey(_T("Local AppWizard-Generated Applications"));
417 LoadStdProfileSettings(0); // Load standard INI file options (including MRU)
418
419 ////////// for dualApp //////////
420 // Initialization
421 m_pHioIf = Hio2CreateInterface();
422 if ( !HioIfInit() )
423 {
424 MessageBox(NULL, m_pHioIf->GetMessage(), "ERROR", (MB_OK | MB_ICONWARNING));
425 return FALSE;
426 }
427
428 // Register the application's document templates. Document templates
429 // serve as the connection between documents, frame windows and views
430 CSingleDocTemplate* pDocTemplate;
431 pDocTemplate = new CSingleDocTemplate(
432 IDR_MAINFRAME,
433 RUNTIME_CLASS(CDualDoc),
434 RUNTIME_CLASS(CMainFrame), // main SDI frame window
435 RUNTIME_CLASS(CDualView));
436 if (!pDocTemplate)
437 return FALSE;
438 AddDocTemplate(pDocTemplate);
439 // Parse command line for standard shell commands, DDE, file open
440 CCommandLineInfo cmdInfo;
441 ParseCommandLine(cmdInfo);
442 // Dispatch commands specified on the command line. Will return FALSE if
443 // app was launched with /RegServer, /Register, /Unregserver or /Unregister.
444 if (!ProcessShellCommand(cmdInfo))
445 return FALSE;
446
447 ////////// for dualApp //////////
448 // Default settings for send/receive status
449 POSITION pos = pDocTemplate->GetFirstDocPosition();
450 CDualDoc* pDoc = static_cast<CDualDoc *>(pDocTemplate->GetNextDoc(pos));
451 pos = pDoc->GetFirstViewPosition();
452 CDualView* pView = static_cast<CDualView *>(pDoc->GetNextView(pos));
453 pView->PostMessage(WM_USER, CDualView::EVENT_SET_SEND_STATUS, 0);
454 pView->PostMessage(WM_USER, CDualView::EVENT_SET_RECV_STATUS, 0);
455
456 // The one and only window has been initialized, so show and update it
457 m_pMainWnd->ShowWindow(SW_SHOW);
458 m_pMainWnd->UpdateWindow();
459 // Call DragAcceptFiles only if there's a suffix
460 // In an SDI app, this should occur after ProcessShellCommand
461 return TRUE;
462 }
463
464 // CDualApp message handlers
465
466
ExitInstance()467 int CDualApp::ExitInstance()
468 {
469 ////////// for dualApp //////////
470 HioIfExit();
471 Hio2ReleaseInterface(m_pHioIf);
472
473 return CWinApp::ExitInstance();
474 }
475
476 // CAboutDlg dialog used for App About
477
478 class CAboutDlg : public CDialog
479 {
480 public:
481 CAboutDlg();
482
483 // Dialog Data
484 enum { IDD = IDD_ABOUTBOX };
485
486 protected:
487 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
488
489 // Implementation
490 protected:
491 DECLARE_MESSAGE_MAP()
492 };
493
CAboutDlg()494 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
495 {
496 }
497
DoDataExchange(CDataExchange * pDX)498 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
499 {
500 CDialog::DoDataExchange(pDX);
501 }
502
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)503 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
504 END_MESSAGE_MAP()
505
506 // App command to run the dialog
507 void CDualApp::OnAppAbout()
508 {
509 CAboutDlg aboutDlg;
510 aboutDlg.DoModal();
511 }
512
513