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