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:		// 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(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