kid.Flags = sc[i].m_flags;\r
if (!i_doPress)\r
kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
-#ifdef NO_DRIVER\r
injectInput(&kid, NULL);\r
-#else // !NO_DRIVER\r
- DWORD len;\r
- WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);\r
- CHECK_TRUE( GetOverlappedResult(m_device, &m_ol, &len, TRUE) );\r
-#endif // !NO_DRIVER\r
}\r
\r
m_lastGeneratedKey = i_doPress ? i_key : NULL;\r
}\r
\r
\r
-#ifdef NO_DRIVER\r
unsigned int Engine::injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHOOKSTRUCT *i_kidRaw)\r
{\r
if (i_kid->Flags & KEYBOARD_INPUT_DATA::E1) {\r
}\r
return 1;\r
}\r
-#endif // NO_DRIVER\r
\r
\r
// pop all pressed key on win32\r
}\r
\r
\r
-#ifdef NO_DRIVER\r
unsigned int WINAPI Engine::keyboardDetour(Engine *i_this, WPARAM i_wParam, LPARAM i_lParam)\r
{\r
return i_this->keyboardDetour(reinterpret_cast<KBDLLHOOKSTRUCT*>(i_lParam));\r
kid.Reserved = 0;\r
kid.ExtraInformation = 0;\r
\r
- Acquire a(&m_cskidq);\r
- m_kidq.push_back(kid);\r
+ WaitForSingleObject(m_queueMutex, INFINITE);\r
+ m_inputQueue->push_back(kid);\r
SetEvent(m_readEvent);\r
+ ReleaseMutex(m_queueMutex);\r
return 1;\r
}\r
}\r
dr += (i_mid->pt.y - m_msllHookCurrent.pt.y) * (i_mid->pt.y - m_msllHookCurrent.pt.y);\r
if (m_buttonPressed && !m_dragging && m_setting->m_dragThreshold &&\r
(m_setting->m_dragThreshold * m_setting->m_dragThreshold < dr)) {\r
- Acquire a(&m_cskidq);\r
-\r
- m_dragging = true;\r
kid.MakeCode = 0;\r
- m_kidq.push_back(kid);\r
+ WaitForSingleObject(m_queueMutex, INFINITE);\r
+ m_dragging = true;\r
+ m_inputQueue->push_back(kid);\r
SetEvent(m_readEvent);\r
+ ReleaseMutex(m_queueMutex);\r
}\r
\r
switch (g_hookData->m_mouseHookType) {\r
break;\r
}\r
\r
- Acquire a(&m_cskidq);\r
+ WaitForSingleObject(m_queueMutex, INFINITE);\r
\r
if (kid.Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
m_buttonPressed = false;\r
kid2.Reserved = 0;\r
kid2.ExtraInformation = 0;\r
kid2.MakeCode = 0;\r
- m_kidq.push_back(kid2);\r
- SetEvent(m_readEvent);\r
+ m_inputQueue->push_back(kid2);\r
}\r
} else if (i_message != WM_MOUSEWHEEL && i_message != WM_MOUSEHWHEEL) {\r
m_buttonPressed = true;\r
m_msllHookCurrent = *i_mid;\r
}\r
\r
- m_kidq.push_back(kid);\r
- SetEvent(m_readEvent);\r
+ m_inputQueue->push_back(kid);\r
\r
if (i_message == WM_MOUSEWHEEL || i_message == WM_MOUSEHWHEEL) {\r
kid.UnitId = 0;\r
kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
kid.Reserved = 0;\r
kid.ExtraInformation = 0;\r
- m_kidq.push_back(kid);\r
- SetEvent(m_readEvent);\r
+ m_inputQueue->push_back(kid);\r
}\r
\r
+ SetEvent(m_readEvent);\r
+ ReleaseMutex(m_queueMutex);\r
+\r
return 1;\r
}\r
}\r
-#endif // NO_DRIVER\r
\r
// keyboard handler thread\r
unsigned int WINAPI Engine::keyboardHandler(void *i_this)\r
}\r
void Engine::keyboardHandler()\r
{\r
- // initialize ok\r
- CHECK_TRUE( SetEvent(m_threadEvent) );\r
-\r
// loop\r
Key key;\r
- while (!m_doForceTerminate) {\r
+ while (1) {\r
KEYBOARD_INPUT_DATA kid;\r
\r
-#ifndef NO_DRIVER\r
- DWORD len;\r
-#endif // !NO_DRIVER\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("begin ReadFile();") << std::endl;\r
- }\r
-#ifdef NO_DRIVER\r
- if (1) {\r
-#else // !NO_DRIVER\r
- if (!ReadFile(m_device, &kid, sizeof(kid), &len, &m_ol)) {\r
- if (GetLastError() != ERROR_IO_PENDING)\r
- continue;\r
-#endif // !NO_DRIVER\r
-\r
- HANDLE handles[] = { m_readEvent, m_interruptThreadEvent };\r
-rewait:\r
- switch (MsgWaitForMultipleObjects(NUMBER_OF(handles), &handles[0],\r
- FALSE, INFINITE, QS_POSTMESSAGE)) {\r
- case WAIT_OBJECT_0: // m_readEvent\r
-#ifdef NO_DRIVER\r
- {\r
- Acquire a(&m_cskidq);\r
- if (m_kidq.empty()) {\r
- goto rewait;\r
- }\r
- kid = m_kidq.front();\r
- m_kidq.pop_front();\r
- if (!m_kidq.empty()) {\r
- SetEvent(m_readEvent);\r
- }\r
- }\r
-#else // !NO_DRIVER\r
- if (!GetOverlappedResult(m_device, &m_ol, &len, FALSE))\r
- continue;\r
-#endif // !NO_DRIVER\r
- break;\r
-\r
- case WAIT_OBJECT_0 + 1: // m_interruptThreadEvent\r
- CancelIo(m_device);\r
- switch (m_interruptThreadReason) {\r
- default: {\r
- ASSERT( false );\r
- Acquire a(&m_log, 0);\r
- m_log << _T("internal error: m_interruptThreadReason == ")\r
- << m_interruptThreadReason << std::endl;\r
- break;\r
- }\r
-\r
- case InterruptThreadReason_Terminate:\r
- goto break_while;\r
+ WaitForSingleObject(m_queueMutex, INFINITE);\r
+ while (SignalObjectAndWait(m_queueMutex, m_readEvent, INFINITE, true) == WAIT_OBJECT_0) {\r
+ if (m_inputQueue == NULL) {\r
+ ReleaseMutex(m_queueMutex);\r
+ return;\r
+ }\r
\r
- case InterruptThreadReason_Pause: {\r
- CHECK_TRUE( SetEvent(m_threadEvent) );\r
- while (WaitForMultipleObjects(1, &m_interruptThreadEvent,\r
- FALSE, INFINITE) != WAIT_OBJECT_0)\r
- ;\r
- switch (m_interruptThreadReason) {\r
- case InterruptThreadReason_Terminate:\r
- goto break_while;\r
+ if (m_inputQueue->empty()) {\r
+ ResetEvent(m_readEvent);\r
+ continue;\r
+ }\r
\r
- case InterruptThreadReason_Resume:\r
- break;\r
+ kid = m_inputQueue->front();\r
+ m_inputQueue->pop_front();\r
+ if (m_inputQueue->empty()) {\r
+ ResetEvent(m_readEvent);\r
+ }\r
\r
- default:\r
- ASSERT( false );\r
- break;\r
- }\r
- CHECK_TRUE( SetEvent(m_threadEvent) );\r
- break;\r
- }\r
- }\r
- break;\r
+ break;\r
\r
+#if 0\r
case WAIT_OBJECT_0 + NUMBER_OF(handles): {\r
MSG message;\r
\r
}\r
goto rewait;\r
}\r
-\r
- default:\r
- ASSERT( false );\r
- continue;\r
- }\r
- }\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("end ReadFile();") << std::endl;\r
+#endif\r
}\r
+ ReleaseMutex(m_queueMutex);\r
\r
checkFocusWindow();\r
\r
injectInput(&kid, NULL);\r
}\r
} else {\r
-#ifdef NO_DRIVER\r
injectInput(&kid, NULL);\r
-#else // !NO_DRIVER\r
- WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);\r
- GetOverlappedResult(m_device, &m_ol, &len, TRUE);\r
-#endif // !NO_DRIVER\r
}\r
updateLastPressedKey(NULL);\r
continue;\r
\r
if (!m_currentFocusOfThread ||\r
!m_currentKeymap) {\r
-#ifdef NO_DRIVER\r
injectInput(&kid, NULL);\r
-#else\r
- WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);\r
- GetOverlappedResult(m_device, &m_ol, &len, TRUE);\r
-#endif // !NO_DRIVER\r
Acquire a(&m_log, 0);\r
if (!m_currentFocusOfThread)\r
m_log << _T("internal error: m_currentFocusOfThread == NULL")\r
key.initialize();\r
updateLastPressedKey(isPhysicallyPressed ? c.m_mkey.m_key : NULL);\r
}\r
-break_while:\r
- CHECK_TRUE( SetEvent(m_threadEvent) );\r
}\r
\r
\r
Engine::Engine(tomsgstream &i_log)\r
: m_hwndAssocWindow(NULL),\r
m_setting(NULL),\r
- m_device(INVALID_HANDLE_VALUE),\r
- m_didMayuStartDevice(false),\r
- m_threadEvent(NULL),\r
- m_mayudVersion(_T("unknown")),\r
m_buttonPressed(false),\r
m_dragging(false),\r
m_keyboardHandler(installKeyboardHook, Engine::keyboardDetour),\r
m_mouseHandler(installMouseHook, Engine::mouseDetour),\r
+ m_inputQueue(NULL),\r
m_readEvent(NULL),\r
- m_interruptThreadEvent(NULL),\r
+ m_queueMutex(NULL),\r
m_sts4mayu(NULL),\r
m_cts4mayu(NULL),\r
- m_doForceTerminate(false),\r
m_isLogMode(false),\r
m_isEnabled(true),\r
m_isSynchronizing(false),\r
for (int i = Modifier::Type_Lock0; i <= Modifier::Type_Lock9; ++ i)\r
m_currentLock.release(static_cast<Modifier::Type>(i));\r
\r
-#ifndef NO_DRIVER\r
- if (!open()) {\r
- throw ErrorMessage() << loadString(IDS_driverNotInstalled);\r
- }\r
-#endif // !NO_DRIVER\r
-\r
-#ifndef NO_DRIVER\r
- {\r
- TCHAR versionBuf[256];\r
- DWORD length = 0;\r
-\r
- if (DeviceIoControl(m_device, IOCTL_MAYU_GET_VERSION, NULL, 0,\r
- versionBuf, sizeof(versionBuf), &length, NULL)\r
- && length\r
- && length < sizeof(versionBuf)) // fail safe\r
- m_mayudVersion = tstring(versionBuf, length / 2);\r
- }\r
-#endif // !NO_DRIVER\r
// create event for sync\r
CHECK_TRUE( m_eSync = CreateEvent(NULL, FALSE, FALSE, NULL) );\r
// create named pipe for &SetImeString\r
}\r
\r
\r
-// open mayu device\r
-bool Engine::open() {\r
- // open mayu m_device\r
-#ifndef NO_DRIVER\r
- m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE,\r
- 0, NULL, OPEN_EXISTING,\r
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);\r
-#endif // !NO_DRIVER\r
-\r
- if (m_device != INVALID_HANDLE_VALUE) {\r
- return true;\r
- }\r
-\r
-#ifndef NO_DRIVER\r
- // start mayud\r
- SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);\r
- if (hscm) {\r
- SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_START);\r
- if (hs) {\r
- StartService(hs, 0, NULL);\r
- CloseServiceHandle(hs);\r
- m_didMayuStartDevice = true;\r
- }\r
- CloseServiceHandle(hscm);\r
- }\r
-\r
- // open mayu m_device\r
- m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE,\r
- 0, NULL, OPEN_EXISTING,\r
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);\r
-#endif // !NO_DRIVER\r
- return (m_device != INVALID_HANDLE_VALUE);\r
-}\r
-\r
-\r
-// close mayu device\r
-void Engine::close() {\r
- if (m_device != INVALID_HANDLE_VALUE) {\r
-#ifndef NO_DRIVER\r
- CHECK_TRUE( CloseHandle(m_device) );\r
-#endif // !NO_DRIVER\r
- }\r
- m_device = INVALID_HANDLE_VALUE;\r
-}\r
\r
\r
// start keyboard handler thread\r
void Engine::start() {\r
m_keyboardHandler.start(this);\r
m_mouseHandler.start(this);\r
- CHECK_TRUE( m_threadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );\r
\r
- CHECK_TRUE( m_readEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );\r
- CHECK_TRUE( m_interruptThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );\r
+ CHECK_TRUE( m_inputQueue = new std::deque<KEYBOARD_INPUT_DATA> );\r
+ CHECK_TRUE( m_queueMutex = CreateMutex(NULL, FALSE, NULL) );\r
+ CHECK_TRUE( m_readEvent = CreateEvent(NULL, TRUE, FALSE, NULL) );\r
m_ol.Offset = 0;\r
m_ol.OffsetHigh = 0;\r
m_ol.hEvent = m_readEvent;\r
\r
CHECK_TRUE( m_threadHandle = (HANDLE)_beginthreadex(NULL, 0, keyboardHandler, this, 0, &m_threadId) );\r
- CHECK( WAIT_OBJECT_0 ==, WaitForSingleObject(m_threadEvent, INFINITE) );\r
}\r
\r
\r
// stop keyboard handler thread\r
void Engine::stop() {\r
- if (m_threadEvent) {\r
- m_doForceTerminate = true;\r
- do {\r
- m_interruptThreadReason = InterruptThreadReason_Terminate;\r
- SetEvent(m_interruptThreadEvent);\r
- //DWORD buf;\r
- //M_DeviceIoControl(m_device, IOCTL_MAYU_DETOUR_CANCEL,\r
- // &buf, sizeof(buf), &buf, sizeof(buf), &buf, NULL);\r
-\r
- // wait for message handler thread terminate\r
- } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);\r
- CHECK_TRUE( CloseHandle(m_threadEvent) );\r
- m_threadEvent = NULL;\r
- WaitForSingleObject(m_threadHandle, 100);\r
- CHECK_TRUE( CloseHandle(m_threadHandle) );\r
- m_threadHandle = NULL;\r
-\r
- // stop mayud\r
- if (m_didMayuStartDevice) {\r
- SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);\r
- if (hscm) {\r
- SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_STOP);\r
- if (hs) {\r
- SERVICE_STATUS ss;\r
- ControlService(hs, SERVICE_CONTROL_STOP, &ss);\r
- CloseServiceHandle(hs);\r
- }\r
- CloseServiceHandle(hscm);\r
- }\r
- }\r
-\r
- CHECK_TRUE( CloseHandle(m_readEvent) );\r
- m_readEvent = NULL;\r
- CHECK_TRUE( CloseHandle(m_interruptThreadEvent) );\r
- m_interruptThreadEvent = NULL;\r
- }\r
m_mouseHandler.stop();\r
m_keyboardHandler.stop();\r
-}\r
\r
-bool Engine::pause() {\r
- if (m_device != INVALID_HANDLE_VALUE) {\r
- do {\r
- m_interruptThreadReason = InterruptThreadReason_Pause;\r
- SetEvent(m_interruptThreadEvent);\r
- } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);\r
-#ifndef NO_DRIVER\r
- close();\r
-#endif // !NO_DRIVER\r
- }\r
- return true;\r
-}\r
+ WaitForSingleObject(m_queueMutex, INFINITE);\r
+ delete m_inputQueue;\r
+ m_inputQueue = NULL;\r
+ SetEvent(m_readEvent);\r
+ ReleaseMutex(m_queueMutex);\r
\r
+ WaitForSingleObject(m_threadHandle, 20000);\r
+ CHECK_TRUE( CloseHandle(m_threadHandle) );\r
+ m_threadHandle = NULL;\r
\r
-bool Engine::resume() {\r
- if (m_device == INVALID_HANDLE_VALUE) {\r
-#ifndef NO_DRIVER\r
- if (!open()) {\r
- return false; // FIXME\r
- }\r
-#endif // !NO_DRIVER\r
- do {\r
- m_interruptThreadReason = InterruptThreadReason_Resume;\r
- SetEvent(m_interruptThreadEvent);\r
- } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);\r
- }\r
- return true;\r
+ CHECK_TRUE( CloseHandle(m_readEvent) );\r
+ m_readEvent = NULL;\r
}\r
\r
\r
stop();\r
CHECK_TRUE( CloseHandle(m_eSync) );\r
\r
- // close m_device\r
-#ifndef NO_DRIVER\r
- close();\r
-#endif // !NO_DRIVER\r
// destroy named pipe for &SetImeString\r
if (m_hookPipe && m_hookPipe != INVALID_HANDLE_VALUE) {\r
DisconnectNamedPipe(m_hookPipe);\r