X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=engine.cpp;h=f5dbd2c076156e9c74d07e44be76b514c6f8e291;hb=5fbbed253192e59fc5471b04474cb1e08b65eaa1;hp=7202adf6aff336fc871d73c445070bf9ee159cb4;hpb=8b37a07125f1584affc27b1b5fb55221665ac7e3;p=yamy%2Fyamy.git diff --git a/engine.cpp b/engine.cpp index 7202adf..f5dbd2c 100644 --- a/engine.cpp +++ b/engine.cpp @@ -289,13 +289,7 @@ void Engine::generateKeyEvent(Key *i_key, bool i_doPress, bool i_isByAssign) kid.Flags = sc[i].m_flags; if (!i_doPress) kid.Flags |= KEYBOARD_INPUT_DATA::BREAK; -#ifdef NO_DRIVER injectInput(&kid, NULL); -#else // !NO_DRIVER - DWORD len; - WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol); - CHECK_TRUE( GetOverlappedResult(m_device, &m_ol, &len, TRUE) ); -#endif // !NO_DRIVER } m_lastGeneratedKey = i_doPress ? i_key : NULL; @@ -606,64 +600,126 @@ void Engine::beginGeneratingKeyboardEvents( } -#ifdef NO_DRIVER unsigned int Engine::injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHOOKSTRUCT *i_kidRaw) { - INPUT kid; if (i_kid->Flags & KEYBOARD_INPUT_DATA::E1) { - kid.type = INPUT_MOUSE; - { - Acquire a(&m_cskidq); - kid.mi.dx = m_msllHookCurrent.pt.x; - kid.mi.dy = m_msllHookCurrent.pt.y; - kid.mi.time = m_msllHookCurrent.time; - } - kid.mi.mouseData = 0; - kid.mi.dwExtraInfo = 0; - kid.mi.dwFlags = MOUSEEVENTF_ABSOLUTE; + INPUT kid[2]; + int count = 1; + + kid[0].type = INPUT_MOUSE; + kid[0].mi.dx = 0; + kid[0].mi.dy = 0; + kid[0].mi.time = 0; + kid[0].mi.mouseData = 0; + kid[0].mi.dwExtraInfo = 0; switch (i_kid->MakeCode) { case 1: if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { - kid.mi.dwFlags |= MOUSEEVENTF_LEFTUP; + kid[0].mi.dwFlags = MOUSEEVENTF_LEFTUP; } else { - kid.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN; + kid[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; } break; case 2: if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { - kid.mi.dwFlags |= MOUSEEVENTF_RIGHTUP; + kid[0].mi.dwFlags = MOUSEEVENTF_RIGHTUP; } else { - kid.mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN; + kid[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN; } break; case 3: if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { - kid.mi.dwFlags |= MOUSEEVENTF_MIDDLEUP; + kid[0].mi.dwFlags = MOUSEEVENTF_MIDDLEUP; } else { - kid.mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN; + kid[0].mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN; } break; case 4: if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { return 1; } else { - kid.mi.mouseData = WHEEL_DELTA; - kid.mi.dwFlags |= MOUSEEVENTF_WHEEL; + kid[0].mi.mouseData = WHEEL_DELTA; + kid[0].mi.dwFlags = MOUSEEVENTF_WHEEL; } break; case 5: if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { return 1; } else { - kid.mi.mouseData = -WHEEL_DELTA; - kid.mi.dwFlags |= MOUSEEVENTF_WHEEL; + kid[0].mi.mouseData = -WHEEL_DELTA; + kid[0].mi.dwFlags = MOUSEEVENTF_WHEEL; + } + break; + case 6: + kid[0].mi.mouseData = XBUTTON1; + if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { + kid[0].mi.dwFlags = MOUSEEVENTF_XUP; + } else { + kid[0].mi.dwFlags = MOUSEEVENTF_XDOWN; + } + break; + case 7: + kid[0].mi.mouseData = XBUTTON2; + if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { + kid[0].mi.dwFlags = MOUSEEVENTF_XUP; + } else { + kid[0].mi.dwFlags = MOUSEEVENTF_XDOWN; + } + break; + case 8: + if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { + return 1; + } else { + kid[0].mi.mouseData = WHEEL_DELTA; + kid[0].mi.dwFlags = MOUSEEVENTF_HWHEEL; + } + break; + case 9: + if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) { + return 1; + } else { + kid[0].mi.mouseData = -WHEEL_DELTA; + kid[0].mi.dwFlags = MOUSEEVENTF_HWHEEL; } break; default: return 1; break; } + if (!(i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) && + i_kid->MakeCode != 4 && i_kid->MakeCode != 5 && + i_kid->MakeCode != 8 && i_kid->MakeCode != 9) { + HWND hwnd; + POINT pt; + + if (GetCursorPos(&pt) && (hwnd = WindowFromPoint(pt))) { + _TCHAR className[GANA_MAX_ATOM_LENGTH]; + if (GetClassName(hwnd, className, NUMBER_OF(className))) { + if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0) { + SetForegroundWindow(hwnd); + } + } + } + if (m_dragging) { + kid[0].mi.dx = 65535 * m_msllHookCurrent.pt.x / GetSystemMetrics(SM_CXVIRTUALSCREEN); + kid[0].mi.dy = 65535 * m_msllHookCurrent.pt.y / GetSystemMetrics(SM_CYVIRTUALSCREEN); + kid[0].mi.dwFlags |= MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; + + kid[1].type = INPUT_MOUSE; + kid[1].mi.dx = 65535 * pt.x / GetSystemMetrics(SM_CXVIRTUALSCREEN); + kid[1].mi.dy = 65535 * pt.y / GetSystemMetrics(SM_CYVIRTUALSCREEN); + kid[1].mi.time = 0; + kid[1].mi.mouseData = 0; + kid[1].mi.dwExtraInfo = 0; + kid[1].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; + + count = 2; + } + } + SendInput(count, &kid[0], sizeof(kid[0])); } else { + INPUT kid; + kid.type = INPUT_KEYBOARD; kid.ki.wVk = 0; kid.ki.wScan = i_kid->MakeCode; @@ -676,11 +732,10 @@ unsigned int Engine::injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHO if (i_kid->Flags & KEYBOARD_INPUT_DATA::E0) { kid.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; } + SendInput(1, &kid, sizeof(kid)); } - SendInput(1, &kid, sizeof(kid)); return 1; } -#endif // NO_DRIVER // pop all pressed key on win32 @@ -694,7 +749,6 @@ void Engine::keyboardResetOnWin32() } -#ifdef NO_DRIVER unsigned int WINAPI Engine::keyboardDetour(Engine *i_this, WPARAM i_wParam, LPARAM i_lParam) { return i_this->keyboardDetour(reinterpret_cast(i_lParam)); @@ -709,7 +763,7 @@ unsigned int Engine::keyboardDetour(KBDLLHOOKSTRUCT *i_kid) << _T(" scanCode=") << i_kid->scanCode << _T(" flags=") << i_kid->flags << std::endl; #endif - if (i_kid->flags & LLKHF_INJECTED) { + if ((i_kid->flags & LLKHF_INJECTED) || !m_isEnabled) { return 0; } else { Key key; @@ -727,9 +781,10 @@ unsigned int Engine::keyboardDetour(KBDLLHOOKSTRUCT *i_kid) kid.Reserved = 0; kid.ExtraInformation = 0; - Acquire a(&m_cskidq); - m_kidq.push_back(kid); + WaitForSingleObject(m_queueMutex, INFINITE); + m_inputQueue->push_back(kid); SetEvent(m_readEvent); + ReleaseMutex(m_queueMutex); return 1; } } @@ -741,7 +796,7 @@ unsigned int WINAPI Engine::mouseDetour(Engine *i_this, WPARAM i_wParam, LPARAM unsigned int Engine::mouseDetour(WPARAM i_message, MSLLHOOKSTRUCT *i_mid) { - if (i_mid->flags & LLMHF_INJECTED || !m_setting->m_mouseEvent) { + if (i_mid->flags & LLMHF_INJECTED || !m_isEnabled || !m_setting || !m_setting->m_mouseEvent) { return 0; } else { KEYBOARD_INPUT_DATA kid; @@ -773,35 +828,134 @@ unsigned int Engine::mouseDetour(WPARAM i_message, MSLLHOOKSTRUCT *i_mid) kid.MakeCode = 4; } break; + case WM_XBUTTONUP: + kid.Flags |= KEYBOARD_INPUT_DATA::BREAK; + case WM_XBUTTONDOWN: + switch ((i_mid->mouseData >> 16) & 0xFFFFU) { + case XBUTTON1: + kid.MakeCode = 6; + break; + case XBUTTON2: + kid.MakeCode = 7; + break; + default: + return 0; + break; + } + break; + case WM_MOUSEHWHEEL: + if (i_mid->mouseData & (1<<31)) { + kid.MakeCode = 9; + } else { + kid.MakeCode = 8; + } + break; + case WM_MOUSEMOVE: { + LONG dx = i_mid->pt.x - g_hookData->m_mousePos.x; + LONG dy = i_mid->pt.y - g_hookData->m_mousePos.y; + HWND target = reinterpret_cast(g_hookData->m_hwndMouseHookTarget); + + LONG dr = 0; + dr += (i_mid->pt.x - m_msllHookCurrent.pt.x) * (i_mid->pt.x - m_msllHookCurrent.pt.x); + dr += (i_mid->pt.y - m_msllHookCurrent.pt.y) * (i_mid->pt.y - m_msllHookCurrent.pt.y); + if (m_buttonPressed && !m_dragging && m_setting->m_dragThreshold && + (m_setting->m_dragThreshold * m_setting->m_dragThreshold < dr)) { + kid.MakeCode = 0; + WaitForSingleObject(m_queueMutex, INFINITE); + m_dragging = true; + m_inputQueue->push_back(kid); + SetEvent(m_readEvent); + ReleaseMutex(m_queueMutex); + } + + switch (g_hookData->m_mouseHookType) { + case MouseHookType_Wheel: + // For this type, g_hookData->m_mouseHookParam means + // translate rate mouse move to wheel. + mouse_event(MOUSEEVENTF_WHEEL, 0, 0, + g_hookData->m_mouseHookParam * dy, 0); + return 1; + break; + case MouseHookType_WindowMove: { + RECT curRect; + + if (!GetWindowRect(target, &curRect)) + return 0; + + // g_hookData->m_mouseHookParam < 0 means + // target window to move is MDI. + if (g_hookData->m_mouseHookParam < 0) { + HWND parent = GetParent(target); + POINT p = {curRect.left, curRect.top}; + + if (parent == NULL || !ScreenToClient(parent, &p)) + return 0; + + curRect.left = p.x; + curRect.top = p.y; + } + + SetWindowPos(target, NULL, + curRect.left + dx, + curRect.top + dy, + 0, 0, + SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | + SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER); + g_hookData->m_mousePos = i_mid->pt; + return 0; + break; + } + case MouseHookType_None: + default: + return 0; + break; + } + } case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_MBUTTONDBLCLK: - case WM_MOUSEHWHEEL: - case WM_XBUTTONDOWN: - case WM_XBUTTONUP: case WM_XBUTTONDBLCLK: - case WM_MOUSEMOVE: default: return 0; break; } - Acquire a(&m_cskidq); + WaitForSingleObject(m_queueMutex, INFINITE); + + if (kid.Flags & KEYBOARD_INPUT_DATA::BREAK) { + m_buttonPressed = false; + if (m_dragging) { + KEYBOARD_INPUT_DATA kid2; - m_msllHookCurrent.pt.x = i_mid->pt.x; - m_msllHookCurrent.pt.y = i_mid->pt.y; - m_msllHookCurrent.mouseData = i_mid->mouseData; - m_msllHookCurrent.flags = i_mid->flags; - m_msllHookCurrent.time = i_mid->time; - m_msllHookCurrent.dwExtraInfo = i_mid->dwExtraInfo; + m_dragging = false; + kid2.UnitId = 0; + kid2.Flags = KEYBOARD_INPUT_DATA::E1 | KEYBOARD_INPUT_DATA::BREAK; + kid2.Reserved = 0; + kid2.ExtraInformation = 0; + kid2.MakeCode = 0; + m_inputQueue->push_back(kid2); + } + } else if (i_message != WM_MOUSEWHEEL && i_message != WM_MOUSEHWHEEL) { + m_buttonPressed = true; + m_msllHookCurrent = *i_mid; + } + + m_inputQueue->push_back(kid); + + if (i_message == WM_MOUSEWHEEL || i_message == WM_MOUSEHWHEEL) { + kid.UnitId = 0; + kid.Flags |= KEYBOARD_INPUT_DATA::BREAK; + kid.Reserved = 0; + kid.ExtraInformation = 0; + m_inputQueue->push_back(kid); + } - m_kidq.push_back(kid); SetEvent(m_readEvent); + ReleaseMutex(m_queueMutex); return 1; } } -#endif // NO_DRIVER // keyboard handler thread unsigned int WINAPI Engine::keyboardHandler(void *i_this) @@ -812,88 +966,32 @@ unsigned int WINAPI Engine::keyboardHandler(void *i_this) } void Engine::keyboardHandler() { - // initialize ok - CHECK_TRUE( SetEvent(m_threadEvent) ); - // loop Key key; - while (!m_doForceTerminate) { + while (1) { KEYBOARD_INPUT_DATA kid; -#ifndef NO_DRIVER - DWORD len; -#endif // !NO_DRIVER - { - Acquire a(&m_log, 1); - m_log << _T("begin ReadFile();") << std::endl; - } -#ifdef NO_DRIVER - if (1) { -#else // !NO_DRIVER - if (!ReadFile(m_device, &kid, sizeof(kid), &len, &m_ol)) { - if (GetLastError() != ERROR_IO_PENDING) - continue; -#endif // !NO_DRIVER - - HANDLE handles[] = { m_readEvent, m_interruptThreadEvent }; -rewait: - switch (MsgWaitForMultipleObjects(NUMBER_OF(handles), &handles[0], - FALSE, INFINITE, QS_POSTMESSAGE)) { - case WAIT_OBJECT_0: // m_readEvent -#ifdef NO_DRIVER - { - Acquire a(&m_cskidq); - if (m_kidq.empty()) { - goto rewait; - } - kid = m_kidq.front(); - m_kidq.pop_front(); - if (!m_kidq.empty()) { - SetEvent(m_readEvent); - } - } -#else // !NO_DRIVER - if (!GetOverlappedResult(m_device, &m_ol, &len, FALSE)) - continue; -#endif // !NO_DRIVER - break; - - case WAIT_OBJECT_0 + 1: // m_interruptThreadEvent - CancelIo(m_device); - switch (m_interruptThreadReason) { - default: { - ASSERT( false ); - Acquire a(&m_log, 0); - m_log << _T("internal error: m_interruptThreadReason == ") - << m_interruptThreadReason << std::endl; - break; - } - - case InterruptThreadReason_Terminate: - goto break_while; + WaitForSingleObject(m_queueMutex, INFINITE); + while (SignalObjectAndWait(m_queueMutex, m_readEvent, INFINITE, true) == WAIT_OBJECT_0) { + if (m_inputQueue == NULL) { + ReleaseMutex(m_queueMutex); + return; + } - case InterruptThreadReason_Pause: { - CHECK_TRUE( SetEvent(m_threadEvent) ); - while (WaitForMultipleObjects(1, &m_interruptThreadEvent, - FALSE, INFINITE) != WAIT_OBJECT_0) - ; - switch (m_interruptThreadReason) { - case InterruptThreadReason_Terminate: - goto break_while; + if (m_inputQueue->empty()) { + ResetEvent(m_readEvent); + continue; + } - case InterruptThreadReason_Resume: - break; + kid = m_inputQueue->front(); + m_inputQueue->pop_front(); + if (m_inputQueue->empty()) { + ResetEvent(m_readEvent); + } - default: - ASSERT( false ); - break; - } - CHECK_TRUE( SetEvent(m_threadEvent) ); - break; - } - } - break; + break; +#if 0 case WAIT_OBJECT_0 + NUMBER_OF(handles): { MSG message; @@ -918,16 +1016,9 @@ rewait: } goto rewait; } - - default: - ASSERT( false ); - continue; - } - } - { - Acquire a(&m_log, 1); - m_log << _T("end ReadFile();") << std::endl; +#endif } + ReleaseMutex(m_queueMutex); checkFocusWindow(); @@ -937,13 +1028,12 @@ rewait: Key key; key.addScanCode(ScanCode(kid.MakeCode, kid.Flags)); outputToLog(&key, ModifiedKey(), 0); + if (kid.Flags & KEYBOARD_INPUT_DATA::E1) { + // through mouse event even if log mode + injectInput(&kid, NULL); + } } else { -#ifdef NO_DRIVER injectInput(&kid, NULL); -#else // !NO_DRIVER - WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol); - GetOverlappedResult(m_device, &m_ol, &len, TRUE); -#endif // !NO_DRIVER } updateLastPressedKey(NULL); continue; @@ -953,10 +1043,7 @@ rewait: if (!m_currentFocusOfThread || !m_currentKeymap) { -#ifndef NO_DRIVER - WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol); - GetOverlappedResult(m_device, &m_ol, &len, TRUE); -#endif // !NO_DRIVER + injectInput(&kid, NULL); Acquire a(&m_log, 0); if (!m_currentFocusOfThread) m_log << _T("internal error: m_currentFocusOfThread == NULL") @@ -1062,13 +1149,18 @@ rewait: m_oneShotKey.m_key = NULL; m_oneShotRepeatableRepeatCount = 0; } - } else if (c.m_mkey.m_key) + } else if (c.m_mkey.m_key) { // normal key - { outputToLog(&key, c.m_mkey, 1); if (isPhysicallyPressed) m_oneShotKey.m_key = NULL; beginGeneratingKeyboardEvents(c, isModifier); + } else { + // undefined key + if (kid.Flags & KEYBOARD_INPUT_DATA::E1) { + // through mouse event even if undefined for fail safe + injectInput(&kid, NULL); + } } // if counter is zero, reset modifiers and keys on win32 @@ -1090,25 +1182,21 @@ rewait: key.initialize(); updateLastPressedKey(isPhysicallyPressed ? c.m_mkey.m_key : NULL); } -break_while: - CHECK_TRUE( SetEvent(m_threadEvent) ); } Engine::Engine(tomsgstream &i_log) : m_hwndAssocWindow(NULL), m_setting(NULL), - m_device(INVALID_HANDLE_VALUE), - m_didMayuStartDevice(false), - m_threadEvent(NULL), - m_mayudVersion(_T("unknown")), + m_buttonPressed(false), + m_dragging(false), m_keyboardHandler(installKeyboardHook, Engine::keyboardDetour), m_mouseHandler(installMouseHook, Engine::mouseDetour), + m_inputQueue(NULL), m_readEvent(NULL), - m_interruptThreadEvent(NULL), + m_queueMutex(NULL), m_sts4mayu(NULL), m_cts4mayu(NULL), - m_doForceTerminate(false), m_isLogMode(false), m_isEnabled(true), m_isSynchronizing(false), @@ -1125,6 +1213,13 @@ Engine::Engine(tomsgstream &i_log) m_afShellExecute(NULL), m_variable(0), m_log(i_log) { + BOOL (WINAPI *pChangeWindowMessageFilter)(UINT, DWORD) = + reinterpret_cast(GetProcAddress(GetModuleHandle(_T("user32.dll")), "ChangeWindowMessageFilter")); + + if(pChangeWindowMessageFilter != NULL) { + pChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD); + } + for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i) m_lastPressedKey[i] = NULL; @@ -1134,24 +1229,6 @@ Engine::Engine(tomsgstream &i_log) for (int i = Modifier::Type_Lock0; i <= Modifier::Type_Lock9; ++ i) m_currentLock.release(static_cast(i)); -#ifndef NO_DRIVER - if (!open()) { - throw ErrorMessage() << loadString(IDS_driverNotInstalled); - } -#endif // !NO_DRIVER - -#ifndef NO_DRIVER - { - TCHAR versionBuf[256]; - DWORD length = 0; - - if (DeviceIoControl(m_device, IOCTL_MAYU_GET_VERSION, NULL, 0, - versionBuf, sizeof(versionBuf), &length, NULL) - && length - && length < sizeof(versionBuf)) // fail safe - m_mayudVersion = tstring(versionBuf, length / 2); - } -#endif // !NO_DRIVER // create event for sync CHECK_TRUE( m_eSync = CreateEvent(NULL, FALSE, FALSE, NULL) ); // create named pipe for &SetImeString @@ -1170,138 +1247,41 @@ Engine::Engine(tomsgstream &i_log) } -// open mayu device -bool Engine::open() { - // open mayu m_device -#ifndef NO_DRIVER - m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); -#endif // !NO_DRIVER - - if (m_device != INVALID_HANDLE_VALUE) { - return true; - } - -#ifndef NO_DRIVER - // start mayud - SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); - if (hscm) { - SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_START); - if (hs) { - StartService(hs, 0, NULL); - CloseServiceHandle(hs); - m_didMayuStartDevice = true; - } - CloseServiceHandle(hscm); - } - - // open mayu m_device - m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); -#endif // !NO_DRIVER - return (m_device != INVALID_HANDLE_VALUE); -} - - -// close mayu device -void Engine::close() { - if (m_device != INVALID_HANDLE_VALUE) { -#ifndef NO_DRIVER - CHECK_TRUE( CloseHandle(m_device) ); -#endif // !NO_DRIVER - } - m_device = INVALID_HANDLE_VALUE; -} // start keyboard handler thread void Engine::start() { m_keyboardHandler.start(this); m_mouseHandler.start(this); - CHECK_TRUE( m_threadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ); - CHECK_TRUE( m_readEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ); - CHECK_TRUE( m_interruptThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ); + CHECK_TRUE( m_inputQueue = new std::deque ); + CHECK_TRUE( m_queueMutex = CreateMutex(NULL, FALSE, NULL) ); + CHECK_TRUE( m_readEvent = CreateEvent(NULL, TRUE, FALSE, NULL) ); m_ol.Offset = 0; m_ol.OffsetHigh = 0; m_ol.hEvent = m_readEvent; CHECK_TRUE( m_threadHandle = (HANDLE)_beginthreadex(NULL, 0, keyboardHandler, this, 0, &m_threadId) ); - CHECK( WAIT_OBJECT_0 ==, WaitForSingleObject(m_threadEvent, INFINITE) ); } // stop keyboard handler thread void Engine::stop() { - if (m_threadEvent) { - m_doForceTerminate = true; - do { - m_interruptThreadReason = InterruptThreadReason_Terminate; - SetEvent(m_interruptThreadEvent); - //DWORD buf; - //M_DeviceIoControl(m_device, IOCTL_MAYU_DETOUR_CANCEL, - // &buf, sizeof(buf), &buf, sizeof(buf), &buf, NULL); - - // wait for message handler thread terminate - } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0); - CHECK_TRUE( CloseHandle(m_threadEvent) ); - m_threadEvent = NULL; - WaitForSingleObject(m_threadHandle, 100); - CHECK_TRUE( CloseHandle(m_threadHandle) ); - m_threadHandle = NULL; - - // stop mayud - if (m_didMayuStartDevice) { - SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); - if (hscm) { - SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_STOP); - if (hs) { - SERVICE_STATUS ss; - ControlService(hs, SERVICE_CONTROL_STOP, &ss); - CloseServiceHandle(hs); - } - CloseServiceHandle(hscm); - } - } - - CHECK_TRUE( CloseHandle(m_readEvent) ); - m_readEvent = NULL; - CHECK_TRUE( CloseHandle(m_interruptThreadEvent) ); - m_interruptThreadEvent = NULL; - } m_mouseHandler.stop(); m_keyboardHandler.stop(); -} -bool Engine::pause() { - if (m_device != INVALID_HANDLE_VALUE) { - do { - m_interruptThreadReason = InterruptThreadReason_Pause; - SetEvent(m_interruptThreadEvent); - } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0); -#ifndef NO_DRIVER - close(); -#endif // !NO_DRIVER - } - return true; -} + WaitForSingleObject(m_queueMutex, INFINITE); + delete m_inputQueue; + m_inputQueue = NULL; + SetEvent(m_readEvent); + ReleaseMutex(m_queueMutex); + WaitForSingleObject(m_threadHandle, 2000); + CHECK_TRUE( CloseHandle(m_threadHandle) ); + m_threadHandle = NULL; -bool Engine::resume() { - if (m_device == INVALID_HANDLE_VALUE) { -#ifndef NO_DRIVER - if (!open()) { - return false; // FIXME - } -#endif // !NO_DRIVER - do { - m_interruptThreadReason = InterruptThreadReason_Resume; - SetEvent(m_interruptThreadEvent); - } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0); - } - return true; + CHECK_TRUE( CloseHandle(m_readEvent) ); + m_readEvent = NULL; } @@ -1316,13 +1296,8 @@ bool Engine::prepairQuit() { Engine::~Engine() { - stop(); CHECK_TRUE( CloseHandle(m_eSync) ); - // close m_device -#ifndef NO_DRIVER - close(); -#endif // !NO_DRIVER // destroy named pipe for &SetImeString if (m_hookPipe && m_hookPipe != INVALID_HANDLE_VALUE) { DisconnectNamedPipe(m_hookPipe); @@ -1621,83 +1596,6 @@ void Engine::getHelpMessages(tstring *o_helpMessage, tstring *o_helpTitle) { } -// command notify -void Engine::commandNotify( - HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam) { - Acquire b(&m_log, 0); - HWND hf = m_hwndFocus; - if (!hf) - return; - - if (GetWindowThreadProcessId(hf, NULL) == - GetWindowThreadProcessId(m_hwndAssocWindow, NULL)) - return; // inhibit the investigation of MADO TSUKAI NO YUUTSU - - const _TCHAR *target = NULL; - int number_target = 0; - - if (i_hwnd == hf) - target = _T("ToItself"); - else if (i_hwnd == GetParent(hf)) - target = _T("ToParentWindow"); - else { - // Function::toMainWindow - HWND h = hf; - while (true) { - HWND p = GetParent(h); - if (!p) - break; - h = p; - } - if (i_hwnd == h) - target = _T("ToMainWindow"); - else { - // Function::toOverlappedWindow - HWND h = hf; - while (h) { -#ifdef MAYU64 - LONG_PTR style = GetWindowLongPtr(h, GWL_STYLE); -#else - LONG style = GetWindowLong(h, GWL_STYLE); -#endif - if ((style & WS_CHILD) == 0) - break; - h = GetParent(h); - } - if (i_hwnd == h) - target = _T("ToOverlappedWindow"); - else { - // number - HWND h = hf; - for (number_target = 0; h; number_target ++, h = GetParent(h)) - if (i_hwnd == h) - break; - return; - } - } - } - - m_log << _T("&PostMessage("); - if (target) - m_log << target; - else - m_log << number_target; - m_log << _T(", ") << i_message - << _T(", 0x") << std::hex << i_wParam - << _T(", 0x") << i_lParam << _T(") # hwnd = ") - << reinterpret_cast(i_hwnd) << _T(", ") - << _T("message = ") << std::dec; - if (i_message == WM_COMMAND) - m_log << _T("WM_COMMAND, "); - else if (i_message == WM_SYSCOMMAND) - m_log << _T("WM_SYSCOMMAND, "); - else - m_log << i_message << _T(", "); - m_log << _T("wNotifyCode = ") << HIWORD(i_wParam) << _T(", ") - << _T("wID = ") << LOWORD(i_wParam) << _T(", ") - << _T("hwndCtrl = 0x") << std::hex << i_lParam << std::dec << std::endl; -} - unsigned int WINAPI Engine::InputHandler::run(void *i_this) { reinterpret_cast(i_this)->run();