// check focus window\r
void Engine::checkFocusWindow()\r
{\r
- int count = 0;\r
- \r
- restart:\r
- count ++;\r
- \r
- HWND hwndFore = GetForegroundWindow();\r
- DWORD threadId = GetWindowThreadProcessId(hwndFore, NULL);\r
-\r
- if (hwndFore)\r
- {\r
- {\r
- Acquire a(&m_cs);\r
- if (m_currentFocusOfThread &&\r
- m_currentFocusOfThread->m_threadId == threadId &&\r
- m_currentFocusOfThread->m_hwndFocus == m_hwndFocus)\r
- return;\r
+ int count = 0;\r
\r
- m_emacsEditKillLine.reset();\r
- \r
- // erase dead thread\r
- if (!m_detachedThreadIds.empty())\r
- {\r
- for (DetachedThreadIds::iterator i = m_detachedThreadIds.begin();\r
- i != m_detachedThreadIds.end(); i ++)\r
- {\r
- FocusOfThreads::iterator j = m_focusOfThreads.find((*i));\r
- if (j != m_focusOfThreads.end())\r
- {\r
- FocusOfThread *fot = &((*j).second);\r
- Acquire a(&m_log, 1);\r
- m_log << _T("RemoveThread") << std::endl;\r
- m_log << _T("\tHWND:\t") << std::hex << (int)fot->m_hwndFocus\r
- << std::dec << std::endl;\r
- m_log << _T("\tTHREADID:") << fot->m_threadId << std::endl;\r
- m_log << _T("\tCLASS:\t") << fot->m_className << std::endl;\r
- m_log << _T("\tTITLE:\t") << fot->m_titleName << std::endl;\r
- m_log << std::endl;\r
- m_focusOfThreads.erase(j);\r
- }\r
+restart:\r
+ count ++;\r
+\r
+ HWND hwndFore = GetForegroundWindow();\r
+ DWORD threadId = GetWindowThreadProcessId(hwndFore, NULL);\r
+\r
+ if (hwndFore) {\r
+ {\r
+ Acquire a(&m_cs);\r
+ if (m_currentFocusOfThread &&\r
+ m_currentFocusOfThread->m_threadId == threadId &&\r
+ m_currentFocusOfThread->m_hwndFocus == m_hwndFocus)\r
+ return;\r
+\r
+ m_emacsEditKillLine.reset();\r
+\r
+ // erase dead thread\r
+ if (!m_detachedThreadIds.empty()) {\r
+ for (DetachedThreadIds::iterator i = m_detachedThreadIds.begin();\r
+ i != m_detachedThreadIds.end(); i ++) {\r
+ FocusOfThreads::iterator j = m_focusOfThreads.find((*i));\r
+ if (j != m_focusOfThreads.end()) {\r
+ FocusOfThread *fot = &((*j).second);\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("RemoveThread") << std::endl;\r
+ m_log << _T("\tHWND:\t") << std::hex << (int)fot->m_hwndFocus\r
+ << std::dec << std::endl;\r
+ m_log << _T("\tTHREADID:") << fot->m_threadId << std::endl;\r
+ m_log << _T("\tCLASS:\t") << fot->m_className << std::endl;\r
+ m_log << _T("\tTITLE:\t") << fot->m_titleName << std::endl;\r
+ m_log << std::endl;\r
+ m_focusOfThreads.erase(j);\r
+ }\r
+ }\r
+ m_detachedThreadIds.erase\r
+ (m_detachedThreadIds.begin(), m_detachedThreadIds.end());\r
+ }\r
+\r
+ FocusOfThreads::iterator i = m_focusOfThreads.find(threadId);\r
+ if (i != m_focusOfThreads.end()) {\r
+ m_currentFocusOfThread = &((*i).second);\r
+ if (!m_currentFocusOfThread->m_isConsole || 2 <= count) {\r
+ if (m_currentFocusOfThread->m_keymaps.empty())\r
+ setCurrentKeymap(NULL);\r
+ else\r
+ setCurrentKeymap(*m_currentFocusOfThread->m_keymaps.begin());\r
+ m_hwndFocus = m_currentFocusOfThread->m_hwndFocus;\r
+ checkShow(m_hwndFocus);\r
+\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("FocusChanged") << std::endl;\r
+ m_log << _T("\tHWND:\t")\r
+ << std::hex << (int)m_currentFocusOfThread->m_hwndFocus\r
+ << std::dec << std::endl;\r
+ m_log << _T("\tTHREADID:")\r
+ << m_currentFocusOfThread->m_threadId << std::endl;\r
+ m_log << _T("\tCLASS:\t")\r
+ << m_currentFocusOfThread->m_className << std::endl;\r
+ m_log << _T("\tTITLE:\t")\r
+ << m_currentFocusOfThread->m_titleName << std::endl;\r
+ m_log << std::endl;\r
+ return;\r
+ }\r
+ }\r
+ }\r
+\r
+ _TCHAR className[GANA_MAX_ATOM_LENGTH];\r
+ if (GetClassName(hwndFore, className, NUMBER_OF(className))) {\r
+ if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0) {\r
+ _TCHAR titleName[1024];\r
+ if (GetWindowText(hwndFore, titleName, NUMBER_OF(titleName)) == 0)\r
+ titleName[0] = _T('\0');\r
+ setFocus(hwndFore, threadId, className, titleName, true);\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("HWND:\t") << std::hex << reinterpret_cast<int>(hwndFore)\r
+ << std::dec << std::endl;\r
+ m_log << _T("THREADID:") << threadId << std::endl;\r
+ m_log << _T("CLASS:\t") << className << std::endl;\r
+ m_log << _T("TITLE:\t") << titleName << std::endl << std::endl;\r
+ goto restart;\r
+ }\r
+ }\r
}\r
- m_detachedThreadIds.erase\r
- (m_detachedThreadIds.begin(), m_detachedThreadIds.end());\r
- }\r
- \r
- FocusOfThreads::iterator i = m_focusOfThreads.find(threadId);\r
- if (i != m_focusOfThreads.end())\r
- {\r
- m_currentFocusOfThread = &((*i).second);\r
- if (!m_currentFocusOfThread->m_isConsole || 2 <= count)\r
- {\r
- if (m_currentFocusOfThread->m_keymaps.empty())\r
- setCurrentKeymap(NULL);\r
- else\r
- setCurrentKeymap(*m_currentFocusOfThread->m_keymaps.begin());\r
- m_hwndFocus = m_currentFocusOfThread->m_hwndFocus;\r
- checkShow(m_hwndFocus);\r
- \r
- Acquire a(&m_log, 1);\r
- m_log << _T("FocusChanged") << std::endl;\r
- m_log << _T("\tHWND:\t")\r
- << std::hex << (int)m_currentFocusOfThread->m_hwndFocus\r
- << std::dec << std::endl;\r
- m_log << _T("\tTHREADID:")\r
- << m_currentFocusOfThread->m_threadId << std::endl;\r
- m_log << _T("\tCLASS:\t")\r
- << m_currentFocusOfThread->m_className << std::endl;\r
- m_log << _T("\tTITLE:\t")\r
- << m_currentFocusOfThread->m_titleName << std::endl;\r
- m_log << std::endl;\r
- return;\r
+\r
+ Acquire a(&m_cs);\r
+ if (m_globalFocus.m_keymaps.empty()) {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("NO GLOBAL FOCUS") << std::endl;\r
+ m_currentFocusOfThread = NULL;\r
+ setCurrentKeymap(NULL);\r
+ } else {\r
+ if (m_currentFocusOfThread != &m_globalFocus) {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("GLOBAL FOCUS") << std::endl;\r
+ m_currentFocusOfThread = &m_globalFocus;\r
+ setCurrentKeymap(m_globalFocus.m_keymaps.front());\r
+ }\r
}\r
- }\r
- }\r
- \r
- _TCHAR className[GANA_MAX_ATOM_LENGTH];\r
- if (GetClassName(hwndFore, className, NUMBER_OF(className)))\r
- {\r
- if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0)\r
- {\r
- _TCHAR titleName[1024];\r
- if (GetWindowText(hwndFore, titleName, NUMBER_OF(titleName)) == 0)\r
- titleName[0] = _T('\0');\r
- setFocus(hwndFore, threadId, className, titleName, true);\r
- Acquire a(&m_log, 1);\r
- m_log << _T("HWND:\t") << std::hex << reinterpret_cast<int>(hwndFore)\r
- << std::dec << std::endl;\r
- m_log << _T("THREADID:") << threadId << std::endl;\r
- m_log << _T("CLASS:\t") << className << std::endl;\r
- m_log << _T("TITLE:\t") << titleName << std::endl << std::endl;\r
- goto restart;\r
- }\r
- }\r
- }\r
- \r
- Acquire a(&m_cs);\r
- if (m_globalFocus.m_keymaps.empty())\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("NO GLOBAL FOCUS") << std::endl;\r
- m_currentFocusOfThread = NULL;\r
- setCurrentKeymap(NULL);\r
- }\r
- else\r
- {\r
- if (m_currentFocusOfThread != &m_globalFocus)\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("GLOBAL FOCUS") << std::endl;\r
- m_currentFocusOfThread = &m_globalFocus;\r
- setCurrentKeymap(m_globalFocus.m_keymaps.front());\r
- }\r
- }\r
- m_hwndFocus = NULL;\r
+ m_hwndFocus = NULL;\r
}\r
\r
\r
// is modifier pressed ?\r
bool Engine::isPressed(Modifier::Type i_mt)\r
{\r
- const Keymap::ModAssignments &ma = m_currentKeymap->getModAssignments(i_mt);\r
- for (Keymap::ModAssignments::const_iterator i = ma.begin();\r
- i != ma.end(); ++ i)\r
- if ((*i).m_key->m_isPressed)\r
- return true;\r
- return false;\r
+ const Keymap::ModAssignments &ma = m_currentKeymap->getModAssignments(i_mt);\r
+ for (Keymap::ModAssignments::const_iterator i = ma.begin();\r
+ i != ma.end(); ++ i)\r
+ if ((*i).m_key->m_isPressed)\r
+ return true;\r
+ return false;\r
}\r
\r
\r
// fix modifier key (if fixed, return true)\r
bool Engine::fixModifierKey(ModifiedKey *io_mkey, Keymap::AssignMode *o_am)\r
{\r
- // for all modifier ...\r
- for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i)\r
- {\r
- // get modifier assignments (list of modifier keys)\r
- const Keymap::ModAssignments &ma =\r
- m_currentKeymap->getModAssignments(static_cast<Modifier::Type>(i));\r
- \r
- for (Keymap::ModAssignments::const_iterator\r
- j = ma.begin(); j != ma.end(); ++ j)\r
- if (io_mkey->m_key == (*j).m_key) // is io_mkey a modifier ?\r
- {\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("* Modifier Key") << std::endl;\r
+ // for all modifier ...\r
+ for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i) {\r
+ // get modifier assignments (list of modifier keys)\r
+ const Keymap::ModAssignments &ma =\r
+ m_currentKeymap->getModAssignments(static_cast<Modifier::Type>(i));\r
+\r
+ for (Keymap::ModAssignments::const_iterator\r
+ j = ma.begin(); j != ma.end(); ++ j)\r
+ if (io_mkey->m_key == (*j).m_key) { // is io_mkey a modifier ?\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("* Modifier Key") << std::endl;\r
+ }\r
+ // set dontcare for this modifier\r
+ io_mkey->m_modifier.dontcare(static_cast<Modifier::Type>(i));\r
+ *o_am = (*j).m_assignMode;\r
+ return true;\r
+ }\r
}\r
- // set dontcare for this modifier\r
- io_mkey->m_modifier.dontcare(static_cast<Modifier::Type>(i));\r
- *o_am = (*j).m_assignMode;\r
- return true;\r
- }\r
- }\r
- *o_am = Keymap::AM_notModifier;\r
- return false;\r
+ *o_am = Keymap::AM_notModifier;\r
+ return false;\r
}\r
\r
\r
// output to m_log\r
void Engine::outputToLog(const Key *i_key, const ModifiedKey &i_mkey,\r
- int i_debugLevel)\r
+ int i_debugLevel)\r
{\r
- size_t i;\r
- Acquire a(&m_log, i_debugLevel);\r
-\r
- // output scan codes\r
- for (i = 0; i < i_key->getScanCodesSize(); ++ i)\r
- {\r
- if (i_key->getScanCodes()[i].m_flags & ScanCode::E0) m_log << _T("E0-");\r
- if (i_key->getScanCodes()[i].m_flags & ScanCode::E1) m_log << _T("E1-");\r
- if (!(i_key->getScanCodes()[i].m_flags & ScanCode::E0E1))\r
- m_log << _T(" ");\r
- m_log << _T("0x") << std::hex << std::setw(2) << std::setfill(_T('0'))\r
- << static_cast<int>(i_key->getScanCodes()[i].m_scan)\r
- << std::dec << _T(" ");\r
- }\r
- \r
- if (!i_mkey.m_key) // key corresponds to no phisical key\r
- {\r
- m_log << std::endl;\r
- return;\r
- }\r
- \r
- m_log << _T(" ") << i_mkey << std::endl;\r
+ size_t i;\r
+ Acquire a(&m_log, i_debugLevel);\r
+\r
+ // output scan codes\r
+ for (i = 0; i < i_key->getScanCodesSize(); ++ i) {\r
+ if (i_key->getScanCodes()[i].m_flags & ScanCode::E0) m_log << _T("E0-");\r
+ if (i_key->getScanCodes()[i].m_flags & ScanCode::E1) m_log << _T("E1-");\r
+ if (!(i_key->getScanCodes()[i].m_flags & ScanCode::E0E1))\r
+ m_log << _T(" ");\r
+ m_log << _T("0x") << std::hex << std::setw(2) << std::setfill(_T('0'))\r
+ << static_cast<int>(i_key->getScanCodes()[i].m_scan)\r
+ << std::dec << _T(" ");\r
+ }\r
+\r
+ if (!i_mkey.m_key) { // key corresponds to no phisical key\r
+ m_log << std::endl;\r
+ return;\r
+ }\r
+\r
+ m_log << _T(" ") << i_mkey << std::endl;\r
}\r
\r
\r
// describe bindings\r
void Engine::describeBindings()\r
{\r
- Acquire a(&m_log, 0);\r
+ Acquire a(&m_log, 0);\r
\r
- Keymap::DescribeParam dp;\r
- for (KeymapPtrList::iterator i = m_currentFocusOfThread->m_keymaps.begin();\r
- i != m_currentFocusOfThread->m_keymaps.end(); ++ i)\r
- (*i)->describe(m_log, &dp);\r
- m_log << std::endl;\r
+ Keymap::DescribeParam dp;\r
+ for (KeymapPtrList::iterator i = m_currentFocusOfThread->m_keymaps.begin();\r
+ i != m_currentFocusOfThread->m_keymaps.end(); ++ i)\r
+ (*i)->describe(m_log, &dp);\r
+ m_log << std::endl;\r
}\r
\r
\r
// update m_lastPressedKey\r
void Engine::updateLastPressedKey(Key *i_key)\r
{\r
- m_lastPressedKey[1] = m_lastPressedKey[0];\r
- m_lastPressedKey[0] = i_key;\r
+ m_lastPressedKey[1] = m_lastPressedKey[0];\r
+ m_lastPressedKey[0] = i_key;\r
}\r
\r
// set current keymap\r
void Engine::setCurrentKeymap(const Keymap *i_keymap, bool i_doesAddToHistory)\r
{\r
- if (i_doesAddToHistory)\r
- {\r
- m_keymapPrefixHistory.push_back(const_cast<Keymap *>(m_currentKeymap));\r
- if (MAX_KEYMAP_PREFIX_HISTORY < m_keymapPrefixHistory.size())\r
- m_keymapPrefixHistory.pop_front();\r
- }\r
- else\r
- m_keymapPrefixHistory.clear();\r
- m_currentKeymap = i_keymap;\r
+ if (i_doesAddToHistory) {\r
+ m_keymapPrefixHistory.push_back(const_cast<Keymap *>(m_currentKeymap));\r
+ if (MAX_KEYMAP_PREFIX_HISTORY < m_keymapPrefixHistory.size())\r
+ m_keymapPrefixHistory.pop_front();\r
+ } else\r
+ m_keymapPrefixHistory.clear();\r
+ m_currentKeymap = i_keymap;\r
}\r
\r
\r
// get current modifiers\r
Modifier Engine::getCurrentModifiers(Key *i_key, bool i_isPressed)\r
{\r
- Modifier cmods;\r
- cmods.add(m_currentLock);\r
-\r
- cmods.press(Modifier::Type_Shift , isPressed(Modifier::Type_Shift ));\r
- cmods.press(Modifier::Type_Alt , isPressed(Modifier::Type_Alt ));\r
- cmods.press(Modifier::Type_Control, isPressed(Modifier::Type_Control));\r
- cmods.press(Modifier::Type_Windows, isPressed(Modifier::Type_Windows));\r
- cmods.press(Modifier::Type_Up , !i_isPressed);\r
- cmods.press(Modifier::Type_Down , i_isPressed);\r
-\r
- cmods.press(Modifier::Type_Repeat , false);\r
- if (m_lastPressedKey[0] == i_key)\r
- {\r
- if (i_isPressed)\r
- cmods.press(Modifier::Type_Repeat, true);\r
- else\r
- if (m_lastPressedKey[1] == i_key)\r
- cmods.press(Modifier::Type_Repeat, true);\r
- }\r
-\r
- for (int i = Modifier::Type_Mod0; i <= Modifier::Type_Mod9; ++ i)\r
- cmods.press(static_cast<Modifier::Type>(i),\r
- isPressed(static_cast<Modifier::Type>(i)));\r
- \r
- return cmods;\r
+ Modifier cmods;\r
+ cmods.add(m_currentLock);\r
+\r
+ cmods.press(Modifier::Type_Shift , isPressed(Modifier::Type_Shift ));\r
+ cmods.press(Modifier::Type_Alt , isPressed(Modifier::Type_Alt ));\r
+ cmods.press(Modifier::Type_Control, isPressed(Modifier::Type_Control));\r
+ cmods.press(Modifier::Type_Windows, isPressed(Modifier::Type_Windows));\r
+ cmods.press(Modifier::Type_Up , !i_isPressed);\r
+ cmods.press(Modifier::Type_Down , i_isPressed);\r
+\r
+ cmods.press(Modifier::Type_Repeat , false);\r
+ if (m_lastPressedKey[0] == i_key) {\r
+ if (i_isPressed)\r
+ cmods.press(Modifier::Type_Repeat, true);\r
+ else\r
+ if (m_lastPressedKey[1] == i_key)\r
+ cmods.press(Modifier::Type_Repeat, true);\r
+ }\r
+\r
+ for (int i = Modifier::Type_Mod0; i <= Modifier::Type_Mod9; ++ i)\r
+ cmods.press(static_cast<Modifier::Type>(i),\r
+ isPressed(static_cast<Modifier::Type>(i)));\r
+\r
+ return cmods;\r
}\r
\r
\r
// generate keyboard event for a key\r
void Engine::generateKeyEvent(Key *i_key, bool i_doPress, bool i_isByAssign)\r
{\r
- // check if key is event\r
- bool isEvent = false;\r
- for (Key **e = Event::events; *e; ++ e)\r
- if (*e == i_key)\r
- {\r
- isEvent = true;\r
- break;\r
- }\r
-\r
- bool isAlreadyReleased = false;\r
- \r
- if (!isEvent)\r
- {\r
- if (i_doPress && !i_key->m_isPressedOnWin32)\r
- ++ m_currentKeyPressCountOnWin32;\r
- else if (!i_doPress)\r
- {\r
- if (i_key->m_isPressedOnWin32)\r
- -- m_currentKeyPressCountOnWin32;\r
- else\r
- isAlreadyReleased = true;\r
- }\r
- i_key->m_isPressedOnWin32 = i_doPress;\r
- \r
- if (i_isByAssign)\r
- i_key->m_isPressedByAssign = i_doPress;\r
-\r
- Key *sync = m_setting->m_keyboard.getSyncKey();\r
- \r
- if (!isAlreadyReleased || i_key == sync)\r
- {\r
- KEYBOARD_INPUT_DATA kid = { 0, 0, 0, 0, 0 };\r
- const ScanCode *sc = i_key->getScanCodes();\r
- for (size_t i = 0; i < i_key->getScanCodesSize(); ++ i)\r
- {\r
- kid.MakeCode = sc[i].m_scan;\r
- 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
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("\t\t =>\t");\r
- if (isAlreadyReleased)\r
- m_log << _T("(already released) ");\r
- }\r
- ModifiedKey mkey(i_key);\r
- mkey.m_modifier.on(Modifier::Type_Up, !i_doPress);\r
- mkey.m_modifier.on(Modifier::Type_Down, i_doPress);\r
- outputToLog(i_key, mkey, 1);\r
+ // check if key is event\r
+ bool isEvent = false;\r
+ for (Key **e = Event::events; *e; ++ e)\r
+ if (*e == i_key) {\r
+ isEvent = true;\r
+ break;\r
+ }\r
+\r
+ bool isAlreadyReleased = false;\r
+\r
+ if (!isEvent) {\r
+ if (i_doPress && !i_key->m_isPressedOnWin32)\r
+ ++ m_currentKeyPressCountOnWin32;\r
+ else if (!i_doPress) {\r
+ if (i_key->m_isPressedOnWin32)\r
+ -- m_currentKeyPressCountOnWin32;\r
+ else\r
+ isAlreadyReleased = true;\r
+ }\r
+ i_key->m_isPressedOnWin32 = i_doPress;\r
+\r
+ if (i_isByAssign)\r
+ i_key->m_isPressedByAssign = i_doPress;\r
+\r
+ Key *sync = m_setting->m_keyboard.getSyncKey();\r
+\r
+ if (!isAlreadyReleased || i_key == sync) {\r
+ KEYBOARD_INPUT_DATA kid = { 0, 0, 0, 0, 0 };\r
+ const ScanCode *sc = i_key->getScanCodes();\r
+ for (size_t i = 0; i < i_key->getScanCodesSize(); ++ i) {\r
+ kid.MakeCode = sc[i].m_scan;\r
+ kid.Flags = sc[i].m_flags;\r
+ if (!i_doPress)\r
+ kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
+ injectInput(&kid, NULL);\r
+ }\r
+\r
+ m_lastGeneratedKey = i_doPress ? i_key : NULL;\r
+ }\r
+ }\r
+\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("\t\t =>\t");\r
+ if (isAlreadyReleased)\r
+ m_log << _T("(already released) ");\r
+ }\r
+ ModifiedKey mkey(i_key);\r
+ mkey.m_modifier.on(Modifier::Type_Up, !i_doPress);\r
+ mkey.m_modifier.on(Modifier::Type_Down, i_doPress);\r
+ outputToLog(i_key, mkey, 1);\r
}\r
\r
\r
// genete event\r
void Engine::generateEvents(Current i_c, const Keymap *i_keymap, Key *i_event)\r
{\r
- // generate\r
- i_c.m_keymap = i_keymap;\r
- i_c.m_mkey.m_key = i_event;\r
- if (const Keymap::KeyAssignment *keyAssign =\r
- i_c.m_keymap->searchAssignment(i_c.m_mkey))\r
- {\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << std::endl << _T(" ")\r
- << i_event->getName() << std::endl;\r
- }\r
- generateKeySeqEvents(i_c, keyAssign->m_keySeq, Part_all);\r
- }\r
+ // generate\r
+ i_c.m_keymap = i_keymap;\r
+ i_c.m_mkey.m_key = i_event;\r
+ if (const Keymap::KeyAssignment *keyAssign =\r
+ i_c.m_keymap->searchAssignment(i_c.m_mkey)) {\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << std::endl << _T(" ")\r
+ << i_event->getName() << std::endl;\r
+ }\r
+ generateKeySeqEvents(i_c, keyAssign->m_keySeq, Part_all);\r
+ }\r
}\r
\r
\r
// genete modifier events\r
void Engine::generateModifierEvents(const Modifier &i_mod)\r
{\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("* Gen Modifiers\t{") << std::endl;\r
- }\r
-\r
- for (int i = Modifier::Type_begin; i < Modifier::Type_BASIC; ++ i)\r
- {\r
- Keyboard::Mods &mods =\r
- m_setting->m_keyboard.getModifiers(static_cast<Modifier::Type>(i));\r
-\r
- if (i_mod.isDontcare(static_cast<Modifier::Type>(i)))\r
- // no need to process\r
- ;\r
- else if (i_mod.isPressed(static_cast<Modifier::Type>(i)))\r
- // we have to press this modifier\r
- {\r
- bool noneIsPressed = true;\r
- bool noneIsPressedByAssign = true;\r
- for (Keyboard::Mods::iterator i = mods.begin(); i != mods.end(); ++ i)\r
- {\r
- if ((*i)->m_isPressedOnWin32)\r
- noneIsPressed = false;\r
- if ((*i)->m_isPressedByAssign)\r
- noneIsPressedByAssign = false;\r
- }\r
- if (noneIsPressed)\r
- {\r
- if (noneIsPressedByAssign)\r
- generateKeyEvent(mods.front(), true, false);\r
- else\r
- for (Keyboard::Mods::iterator\r
- i = mods.begin(); i != mods.end(); ++ i)\r
- if ((*i)->m_isPressedByAssign)\r
- generateKeyEvent((*i), true, false);\r
- }\r
- }\r
-\r
- else\r
- // we have to release this modifier\r
- {\r
- // avoid such sequences as "Alt U-ALt" or "Windows U-Windows"\r
- if (i == Modifier::Type_Alt || i == Modifier::Type_Windows)\r
- {\r
- for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j)\r
- if ((*j) == m_lastGeneratedKey)\r
- {\r
- Keyboard::Mods *mods =\r
- &m_setting->m_keyboard.getModifiers(Modifier::Type_Shift);\r
- if (mods->size() == 0)\r
- mods = &m_setting->m_keyboard.getModifiers(\r
- Modifier::Type_Control);\r
- if (0 < mods->size())\r
- {\r
- generateKeyEvent(mods->front(), true, false);\r
- generateKeyEvent(mods->front(), false, false);\r
- }\r
- break;\r
- }\r
- }\r
- \r
- for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j)\r
- {\r
- if ((*j)->m_isPressedOnWin32)\r
- generateKeyEvent((*j), false, false);\r
- }\r
- }\r
- }\r
- \r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("\t\t}") << std::endl;\r
- }\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("* Gen Modifiers\t{") << std::endl;\r
+ }\r
+\r
+ for (int i = Modifier::Type_begin; i < Modifier::Type_BASIC; ++ i) {\r
+ Keyboard::Mods &mods =\r
+ m_setting->m_keyboard.getModifiers(static_cast<Modifier::Type>(i));\r
+\r
+ if (i_mod.isDontcare(static_cast<Modifier::Type>(i)))\r
+ // no need to process\r
+ ;\r
+ else if (i_mod.isPressed(static_cast<Modifier::Type>(i)))\r
+ // we have to press this modifier\r
+ {\r
+ bool noneIsPressed = true;\r
+ bool noneIsPressedByAssign = true;\r
+ for (Keyboard::Mods::iterator i = mods.begin(); i != mods.end(); ++ i) {\r
+ if ((*i)->m_isPressedOnWin32)\r
+ noneIsPressed = false;\r
+ if ((*i)->m_isPressedByAssign)\r
+ noneIsPressedByAssign = false;\r
+ }\r
+ if (noneIsPressed) {\r
+ if (noneIsPressedByAssign)\r
+ generateKeyEvent(mods.front(), true, false);\r
+ else\r
+ for (Keyboard::Mods::iterator\r
+ i = mods.begin(); i != mods.end(); ++ i)\r
+ if ((*i)->m_isPressedByAssign)\r
+ generateKeyEvent((*i), true, false);\r
+ }\r
+ }\r
+\r
+ else\r
+ // we have to release this modifier\r
+ {\r
+ // avoid such sequences as "Alt U-ALt" or "Windows U-Windows"\r
+ if (i == Modifier::Type_Alt || i == Modifier::Type_Windows) {\r
+ for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j)\r
+ if ((*j) == m_lastGeneratedKey) {\r
+ Keyboard::Mods *mods =\r
+ &m_setting->m_keyboard.getModifiers(Modifier::Type_Shift);\r
+ if (mods->size() == 0)\r
+ mods = &m_setting->m_keyboard.getModifiers(\r
+ Modifier::Type_Control);\r
+ if (0 < mods->size()) {\r
+ generateKeyEvent(mods->front(), true, false);\r
+ generateKeyEvent(mods->front(), false, false);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j) {\r
+ if ((*j)->m_isPressedOnWin32)\r
+ generateKeyEvent((*j), false, false);\r
+ }\r
+ }\r
+ }\r
+\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("\t\t}") << std::endl;\r
+ }\r
}\r
\r
\r
// generate keyboard events for action\r
void Engine::generateActionEvents(const Current &i_c, const Action *i_a,\r
- bool i_doPress)\r
+ bool i_doPress)\r
{\r
- switch (i_a->getType())\r
- {\r
- // key\r
- case Action::Type_key:\r
- {\r
- const ModifiedKey &mkey\r
- = reinterpret_cast<ActionKey *>(\r
- const_cast<Action *>(i_a))->m_modifiedKey;\r
-\r
- // release\r
- if (!i_doPress &&\r
- (mkey.m_modifier.isOn(Modifier::Type_Up) ||\r
- mkey.m_modifier.isDontcare(Modifier::Type_Up)))\r
- generateKeyEvent(mkey.m_key, false, true);\r
-\r
- // press\r
- else if (i_doPress &&\r
- (mkey.m_modifier.isOn(Modifier::Type_Down) ||\r
- mkey.m_modifier.isDontcare(Modifier::Type_Down)))\r
- {\r
- Modifier modifier = mkey.m_modifier;\r
- modifier.add(i_c.m_mkey.m_modifier);\r
- generateModifierEvents(modifier);\r
- generateKeyEvent(mkey.m_key, true, true);\r
- }\r
- break;\r
- }\r
-\r
- // keyseq\r
- case Action::Type_keySeq:\r
- {\r
- const ActionKeySeq *aks = reinterpret_cast<const ActionKeySeq *>(i_a);\r
- generateKeySeqEvents(i_c, aks->m_keySeq,\r
- i_doPress ? Part_down : Part_up);\r
- break;\r
- }\r
-\r
- // function\r
- case Action::Type_function:\r
- {\r
- const ActionFunction *af = reinterpret_cast<const ActionFunction *>(i_a);\r
- bool is_up = (!i_doPress &&\r
- (af->m_modifier.isOn(Modifier::Type_Up) ||\r
- af->m_modifier.isDontcare(Modifier::Type_Up)));\r
- bool is_down = (i_doPress &&\r
- (af->m_modifier.isOn(Modifier::Type_Down) ||\r
- af->m_modifier.isDontcare(Modifier::Type_Down)));\r
-\r
- if (!is_down && !is_up)\r
- break;\r
- \r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("\t\t >\t") << af->m_functionData;\r
- }\r
- \r
- FunctionParam param;\r
- param.m_isPressed = i_doPress;\r
- param.m_hwnd = m_currentFocusOfThread->m_hwndFocus;\r
- param.m_c = i_c;\r
- param.m_doesNeedEndl = true;\r
- param.m_af = af;\r
- \r
- param.m_c.m_mkey.m_modifier.on(Modifier::Type_Up, !i_doPress);\r
- param.m_c.m_mkey.m_modifier.on(Modifier::Type_Down, i_doPress);\r
-\r
- af->m_functionData->exec(this, ¶m);\r
- \r
- if (param.m_doesNeedEndl)\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << std::endl;\r
- }\r
- break;\r
- }\r
- }\r
+ switch (i_a->getType()) {\r
+ // key\r
+ case Action::Type_key: {\r
+ const ModifiedKey &mkey\r
+ = reinterpret_cast<ActionKey *>(\r
+ const_cast<Action *>(i_a))->m_modifiedKey;\r
+\r
+ // release\r
+ if (!i_doPress &&\r
+ (mkey.m_modifier.isOn(Modifier::Type_Up) ||\r
+ mkey.m_modifier.isDontcare(Modifier::Type_Up)))\r
+ generateKeyEvent(mkey.m_key, false, true);\r
+\r
+ // press\r
+ else if (i_doPress &&\r
+ (mkey.m_modifier.isOn(Modifier::Type_Down) ||\r
+ mkey.m_modifier.isDontcare(Modifier::Type_Down))) {\r
+ Modifier modifier = mkey.m_modifier;\r
+ modifier.add(i_c.m_mkey.m_modifier);\r
+ generateModifierEvents(modifier);\r
+ generateKeyEvent(mkey.m_key, true, true);\r
+ }\r
+ break;\r
+ }\r
+\r
+ // keyseq\r
+ case Action::Type_keySeq: {\r
+ const ActionKeySeq *aks = reinterpret_cast<const ActionKeySeq *>(i_a);\r
+ generateKeySeqEvents(i_c, aks->m_keySeq,\r
+ i_doPress ? Part_down : Part_up);\r
+ break;\r
+ }\r
+\r
+ // function\r
+ case Action::Type_function: {\r
+ const ActionFunction *af = reinterpret_cast<const ActionFunction *>(i_a);\r
+ bool is_up = (!i_doPress &&\r
+ (af->m_modifier.isOn(Modifier::Type_Up) ||\r
+ af->m_modifier.isDontcare(Modifier::Type_Up)));\r
+ bool is_down = (i_doPress &&\r
+ (af->m_modifier.isOn(Modifier::Type_Down) ||\r
+ af->m_modifier.isDontcare(Modifier::Type_Down)));\r
+\r
+ if (!is_down && !is_up)\r
+ break;\r
+\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("\t\t >\t") << af->m_functionData;\r
+ }\r
+\r
+ FunctionParam param;\r
+ param.m_isPressed = i_doPress;\r
+ param.m_hwnd = m_currentFocusOfThread->m_hwndFocus;\r
+ param.m_c = i_c;\r
+ param.m_doesNeedEndl = true;\r
+ param.m_af = af;\r
+\r
+ param.m_c.m_mkey.m_modifier.on(Modifier::Type_Up, !i_doPress);\r
+ param.m_c.m_mkey.m_modifier.on(Modifier::Type_Down, i_doPress);\r
+\r
+ af->m_functionData->exec(this, ¶m);\r
+\r
+ if (param.m_doesNeedEndl) {\r
+ Acquire a(&m_log, 1);\r
+ m_log << std::endl;\r
+ }\r
+ break;\r
+ }\r
+ }\r
}\r
\r
\r
// generate keyboard events for keySeq\r
void Engine::generateKeySeqEvents(const Current &i_c, const KeySeq *i_keySeq,\r
- Part i_part)\r
+ Part i_part)\r
{\r
- const KeySeq::Actions &actions = i_keySeq->getActions();\r
- if (actions.empty())\r
- return;\r
- if (i_part == Part_up)\r
- generateActionEvents(i_c, actions[actions.size() - 1], false);\r
- else\r
- {\r
- size_t i;\r
- for (i = 0 ; i < actions.size() - 1; ++ i)\r
- {\r
- generateActionEvents(i_c, actions[i], true);\r
- generateActionEvents(i_c, actions[i], false);\r
- }\r
- generateActionEvents(i_c, actions[i], true);\r
- if (i_part == Part_all)\r
- generateActionEvents(i_c, actions[i], false);\r
- }\r
+ const KeySeq::Actions &actions = i_keySeq->getActions();\r
+ if (actions.empty())\r
+ return;\r
+ if (i_part == Part_up)\r
+ generateActionEvents(i_c, actions[actions.size() - 1], false);\r
+ else {\r
+ size_t i;\r
+ for (i = 0 ; i < actions.size() - 1; ++ i) {\r
+ generateActionEvents(i_c, actions[i], true);\r
+ generateActionEvents(i_c, actions[i], false);\r
+ }\r
+ generateActionEvents(i_c, actions[i], true);\r
+ if (i_part == Part_all)\r
+ generateActionEvents(i_c, actions[i], false);\r
+ }\r
}\r
\r
\r
// generate keyboard events for current key\r
void Engine::generateKeyboardEvents(const Current &i_c)\r
{\r
- if (++ m_generateKeyboardEventsRecursionGuard ==\r
- MAX_GENERATE_KEYBOARD_EVENTS_RECURSION_COUNT)\r
- {\r
- Acquire a(&m_log);\r
- m_log << _T("error: too deep keymap recursion. there may be a loop.")\r
- << std::endl;\r
- return;\r
- }\r
-\r
- const Keymap::KeyAssignment *keyAssign\r
- = i_c.m_keymap->searchAssignment(i_c.m_mkey);\r
- if (!keyAssign)\r
- {\r
- const KeySeq *keySeq = i_c.m_keymap->getDefaultKeySeq();\r
- ASSERT( keySeq );\r
- generateKeySeqEvents(i_c, keySeq, i_c.isPressed() ? Part_down : Part_up);\r
- }\r
- else\r
- {\r
- if (keyAssign->m_modifiedKey.m_modifier.isOn(Modifier::Type_Up) ||\r
- keyAssign->m_modifiedKey.m_modifier.isOn(Modifier::Type_Down))\r
- generateKeySeqEvents(i_c, keyAssign->m_keySeq, Part_all);\r
- else\r
- generateKeySeqEvents(i_c, keyAssign->m_keySeq,\r
- i_c.isPressed() ? Part_down : Part_up);\r
- }\r
- m_generateKeyboardEventsRecursionGuard --;\r
+ if (++ m_generateKeyboardEventsRecursionGuard ==\r
+ MAX_GENERATE_KEYBOARD_EVENTS_RECURSION_COUNT) {\r
+ Acquire a(&m_log);\r
+ m_log << _T("error: too deep keymap recursion. there may be a loop.")\r
+ << std::endl;\r
+ return;\r
+ }\r
+\r
+ const Keymap::KeyAssignment *keyAssign\r
+ = i_c.m_keymap->searchAssignment(i_c.m_mkey);\r
+ if (!keyAssign) {\r
+ const KeySeq *keySeq = i_c.m_keymap->getDefaultKeySeq();\r
+ ASSERT( keySeq );\r
+ generateKeySeqEvents(i_c, keySeq, i_c.isPressed() ? Part_down : Part_up);\r
+ } else {\r
+ if (keyAssign->m_modifiedKey.m_modifier.isOn(Modifier::Type_Up) ||\r
+ keyAssign->m_modifiedKey.m_modifier.isOn(Modifier::Type_Down))\r
+ generateKeySeqEvents(i_c, keyAssign->m_keySeq, Part_all);\r
+ else\r
+ generateKeySeqEvents(i_c, keyAssign->m_keySeq,\r
+ i_c.isPressed() ? Part_down : Part_up);\r
+ }\r
+ m_generateKeyboardEventsRecursionGuard --;\r
}\r
\r
\r
// generate keyboard events for current key\r
void Engine::beginGeneratingKeyboardEvents(\r
- const Current &i_c, bool i_isModifier)\r
+ const Current &i_c, bool i_isModifier)\r
{\r
- // (1) (2) (3) (4) (1)\r
- // up/down: D- U- D- U- D-\r
- // keymap: m_currentKeymap m_currentKeymap X X m_currentKeymap\r
- // memo: &Prefix(X) ... ... ... ...\r
- // m_isPrefix: false true true false false\r
-\r
- Current cnew(i_c);\r
-\r
- bool isPhysicallyPressed\r
- = cnew.m_mkey.m_modifier.isPressed(Modifier::Type_Down);\r
- \r
- // substitute\r
- ModifiedKey mkey = m_setting->m_keyboard.searchSubstitute(cnew.m_mkey);\r
- if (mkey.m_key)\r
- {\r
- cnew.m_mkey = mkey;\r
- if (isPhysicallyPressed)\r
- {\r
- cnew.m_mkey.m_modifier.off(Modifier::Type_Up);\r
- cnew.m_mkey.m_modifier.on(Modifier::Type_Down);\r
- }\r
- else\r
- {\r
- cnew.m_mkey.m_modifier.on(Modifier::Type_Up);\r
- cnew.m_mkey.m_modifier.off(Modifier::Type_Down);\r
- }\r
- for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i)\r
- {\r
- Modifier::Type type = static_cast<Modifier::Type>(i);\r
- if (cnew.m_mkey.m_modifier.isDontcare(type) &&\r
- !i_c.m_mkey.m_modifier.isDontcare(type))\r
- cnew.m_mkey.m_modifier.press(\r
- type, i_c.m_mkey.m_modifier.isPressed(type));\r
- }\r
- \r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("* substitute") << std::endl;\r
- }\r
- outputToLog(mkey.m_key, cnew.m_mkey, 1);\r
- }\r
- \r
- // for prefix key\r
- const Keymap *tmpKeymap = m_currentKeymap;\r
- if (i_isModifier || !m_isPrefix) ; \r
- else if (isPhysicallyPressed) // when (3)\r
- m_isPrefix = false;\r
- else if (!isPhysicallyPressed) // when (2)\r
- m_currentKeymap = m_currentFocusOfThread->m_keymaps.front();\r
- \r
- // for m_emacsEditKillLine function\r
- m_emacsEditKillLine.m_doForceReset = !i_isModifier;\r
-\r
- // generate key event !\r
- m_generateKeyboardEventsRecursionGuard = 0;\r
- if (isPhysicallyPressed)\r
- generateEvents(cnew, cnew.m_keymap, &Event::before_key_down);\r
- generateKeyboardEvents(cnew);\r
- if (!isPhysicallyPressed)\r
- generateEvents(cnew, cnew.m_keymap, &Event::after_key_up);\r
- \r
- // for m_emacsEditKillLine function\r
- if (m_emacsEditKillLine.m_doForceReset)\r
- m_emacsEditKillLine.reset();\r
-\r
- // for prefix key\r
- if (i_isModifier)\r
- ;\r
- else if (!m_isPrefix) // when (1), (4)\r
- m_currentKeymap = m_currentFocusOfThread->m_keymaps.front();\r
- else if (!isPhysicallyPressed) // when (2)\r
- m_currentKeymap = tmpKeymap;\r
+ // (1) (2) (3) (4) (1)\r
+ // up/down: D- U- D- U- D-\r
+ // keymap: m_currentKeymap m_currentKeymap X X m_currentKeymap\r
+ // memo: &Prefix(X) ... ... ... ...\r
+ // m_isPrefix: false true true false false\r
+\r
+ Current cnew(i_c);\r
+\r
+ bool isPhysicallyPressed\r
+ = cnew.m_mkey.m_modifier.isPressed(Modifier::Type_Down);\r
+\r
+ // substitute\r
+ ModifiedKey mkey = m_setting->m_keyboard.searchSubstitute(cnew.m_mkey);\r
+ if (mkey.m_key) {\r
+ cnew.m_mkey = mkey;\r
+ if (isPhysicallyPressed) {\r
+ cnew.m_mkey.m_modifier.off(Modifier::Type_Up);\r
+ cnew.m_mkey.m_modifier.on(Modifier::Type_Down);\r
+ } else {\r
+ cnew.m_mkey.m_modifier.on(Modifier::Type_Up);\r
+ cnew.m_mkey.m_modifier.off(Modifier::Type_Down);\r
+ }\r
+ for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i) {\r
+ Modifier::Type type = static_cast<Modifier::Type>(i);\r
+ if (cnew.m_mkey.m_modifier.isDontcare(type) &&\r
+ !i_c.m_mkey.m_modifier.isDontcare(type))\r
+ cnew.m_mkey.m_modifier.press(\r
+ type, i_c.m_mkey.m_modifier.isPressed(type));\r
+ }\r
+\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("* substitute") << std::endl;\r
+ }\r
+ outputToLog(mkey.m_key, cnew.m_mkey, 1);\r
+ }\r
+\r
+ // for prefix key\r
+ const Keymap *tmpKeymap = m_currentKeymap;\r
+ if (i_isModifier || !m_isPrefix) ;\r
+ else if (isPhysicallyPressed) // when (3)\r
+ m_isPrefix = false;\r
+ else if (!isPhysicallyPressed) // when (2)\r
+ m_currentKeymap = m_currentFocusOfThread->m_keymaps.front();\r
+\r
+ // for m_emacsEditKillLine function\r
+ m_emacsEditKillLine.m_doForceReset = !i_isModifier;\r
+\r
+ // generate key event !\r
+ m_generateKeyboardEventsRecursionGuard = 0;\r
+ if (isPhysicallyPressed)\r
+ generateEvents(cnew, cnew.m_keymap, &Event::before_key_down);\r
+ generateKeyboardEvents(cnew);\r
+ if (!isPhysicallyPressed)\r
+ generateEvents(cnew, cnew.m_keymap, &Event::after_key_up);\r
+\r
+ // for m_emacsEditKillLine function\r
+ if (m_emacsEditKillLine.m_doForceReset)\r
+ m_emacsEditKillLine.reset();\r
+\r
+ // for prefix key\r
+ if (i_isModifier)\r
+ ;\r
+ else if (!m_isPrefix) // when (1), (4)\r
+ m_currentKeymap = m_currentFocusOfThread->m_keymaps.front();\r
+ else if (!isPhysicallyPressed) // when (2)\r
+ m_currentKeymap = tmpKeymap;\r
}\r
\r
\r
-#ifdef NO_DRIVER\r
unsigned int Engine::injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHOOKSTRUCT *i_kidRaw)\r
{\r
- INPUT kid;\r
- kid.type = INPUT_KEYBOARD;\r
- kid.ki.wVk = 0;\r
- kid.ki.wScan = i_kid->MakeCode;\r
- kid.ki.dwFlags = KEYEVENTF_SCANCODE;\r
- kid.ki.time = i_kidRaw ? i_kidRaw->time : 0;\r
- kid.ki.dwExtraInfo = i_kidRaw ? i_kidRaw->dwExtraInfo : 0;\r
- if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK)\r
- {\r
- kid.ki.dwFlags |= KEYEVENTF_KEYUP;\r
- }\r
- if (i_kid->Flags & KEYBOARD_INPUT_DATA::E0)\r
- {\r
- kid.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;\r
- }\r
- SendInput(1, &kid, sizeof(kid));\r
- return 1;\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::E1) {\r
+ INPUT kid[2];\r
+ int count = 1;\r
+\r
+ kid[0].type = INPUT_MOUSE;\r
+ kid[0].mi.dx = 0;\r
+ kid[0].mi.dy = 0;\r
+ kid[0].mi.time = 0;\r
+ kid[0].mi.mouseData = 0;\r
+ kid[0].mi.dwExtraInfo = 0;\r
+ switch (i_kid->MakeCode) {\r
+ case 1:\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;\r
+ } else {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;\r
+ }\r
+ break;\r
+ case 2:\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_RIGHTUP;\r
+ } else {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;\r
+ }\r
+ break;\r
+ case 3:\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_MIDDLEUP;\r
+ } else {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;\r
+ }\r
+ break;\r
+ case 4:\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ return 1;\r
+ } else {\r
+ kid[0].mi.mouseData = WHEEL_DELTA;\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_WHEEL;\r
+ }\r
+ break;\r
+ case 5:\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ return 1;\r
+ } else {\r
+ kid[0].mi.mouseData = -WHEEL_DELTA;\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_WHEEL;\r
+ }\r
+ break;\r
+ case 6:\r
+ kid[0].mi.mouseData = XBUTTON1;\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_XUP;\r
+ } else {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_XDOWN;\r
+ }\r
+ break;\r
+ case 7:\r
+ kid[0].mi.mouseData = XBUTTON2;\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_XUP;\r
+ } else {\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_XDOWN;\r
+ }\r
+ break;\r
+ case 8:\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ return 1;\r
+ } else {\r
+ kid[0].mi.mouseData = WHEEL_DELTA;\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_HWHEEL;\r
+ }\r
+ break;\r
+ case 9:\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ return 1;\r
+ } else {\r
+ kid[0].mi.mouseData = -WHEEL_DELTA;\r
+ kid[0].mi.dwFlags = MOUSEEVENTF_HWHEEL;\r
+ }\r
+ break;\r
+ default:\r
+ return 1;\r
+ break;\r
+ }\r
+ if (!(i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) &&\r
+ i_kid->MakeCode != 4 && i_kid->MakeCode != 5 &&\r
+ i_kid->MakeCode != 8 && i_kid->MakeCode != 9) {\r
+ HWND hwnd;\r
+ POINT pt;\r
+\r
+ if (GetCursorPos(&pt) && (hwnd = WindowFromPoint(pt))) {\r
+ _TCHAR className[GANA_MAX_ATOM_LENGTH];\r
+ if (GetClassName(hwnd, className, NUMBER_OF(className))) {\r
+ if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0) {\r
+ SetForegroundWindow(hwnd);\r
+ }\r
+ }\r
+ }\r
+ if (m_dragging) {\r
+ kid[0].mi.dx = 65535 * m_msllHookCurrent.pt.x / GetSystemMetrics(SM_CXVIRTUALSCREEN);\r
+ kid[0].mi.dy = 65535 * m_msllHookCurrent.pt.y / GetSystemMetrics(SM_CYVIRTUALSCREEN);\r
+ kid[0].mi.dwFlags |= MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;\r
+\r
+ kid[1].type = INPUT_MOUSE;\r
+ kid[1].mi.dx = 65535 * pt.x / GetSystemMetrics(SM_CXVIRTUALSCREEN);\r
+ kid[1].mi.dy = 65535 * pt.y / GetSystemMetrics(SM_CYVIRTUALSCREEN);\r
+ kid[1].mi.time = 0;\r
+ kid[1].mi.mouseData = 0;\r
+ kid[1].mi.dwExtraInfo = 0;\r
+ kid[1].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;\r
+\r
+ count = 2;\r
+ }\r
+ }\r
+ SendInput(count, &kid[0], sizeof(kid[0]));\r
+ } else {\r
+ INPUT kid;\r
+\r
+ kid.type = INPUT_KEYBOARD;\r
+ kid.ki.wVk = 0;\r
+ kid.ki.wScan = i_kid->MakeCode;\r
+ kid.ki.dwFlags = KEYEVENTF_SCANCODE;\r
+ kid.ki.time = i_kidRaw ? i_kidRaw->time : 0;\r
+ kid.ki.dwExtraInfo = i_kidRaw ? i_kidRaw->dwExtraInfo : 0;\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ kid.ki.dwFlags |= KEYEVENTF_KEYUP;\r
+ }\r
+ if (i_kid->Flags & KEYBOARD_INPUT_DATA::E0) {\r
+ kid.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;\r
+ }\r
+ SendInput(1, &kid, sizeof(kid));\r
+ }\r
+ return 1;\r
}\r
-#endif // NO_DRIVER\r
\r
\r
// pop all pressed key on win32\r
void Engine::keyboardResetOnWin32()\r
{\r
- for (Keyboard::KeyIterator\r
- i = m_setting->m_keyboard.getKeyIterator(); *i; ++ i)\r
- {\r
- if ((*i)->m_isPressedOnWin32)\r
- generateKeyEvent((*i), false, true);\r
- }\r
+ for (Keyboard::KeyIterator\r
+ i = m_setting->m_keyboard.getKeyIterator(); *i; ++ i) {\r
+ if ((*i)->m_isPressedOnWin32)\r
+ generateKeyEvent((*i), false, true);\r
+ }\r
}\r
\r
\r
-#ifdef NO_DRIVER\r
-unsigned int WINAPI Engine::keyboardDetour(Engine *i_this, KBDLLHOOKSTRUCT *i_kid)\r
+unsigned int WINAPI Engine::keyboardDetour(Engine *i_this, WPARAM i_wParam, LPARAM i_lParam)\r
{\r
- return i_this->keyboardDetour(i_kid);\r
+ return i_this->keyboardDetour(reinterpret_cast<KBDLLHOOKSTRUCT*>(i_lParam));\r
}\r
\r
unsigned int Engine::keyboardDetour(KBDLLHOOKSTRUCT *i_kid)\r
{\r
#if 0\r
- Acquire a(&m_log, 1);\r
- m_log << std::hex\r
+ Acquire a(&m_log, 1);\r
+ m_log << std::hex\r
<< _T("keyboardDetour: vkCode=") << i_kid->vkCode\r
<< _T(" scanCode=") << i_kid->scanCode\r
<< _T(" flags=") << i_kid->flags << std::endl;\r
#endif\r
- if (i_kid->flags & LLKHF_INJECTED)\r
- {\r
- return 0;\r
- }\r
- else\r
- {\r
- Key key;\r
- KEYBOARD_INPUT_DATA kid;\r
-\r
- kid.UnitId = 0;\r
- kid.MakeCode = i_kid->scanCode;\r
- kid.Flags = 0;\r
- if (i_kid->flags & LLKHF_UP)\r
- {\r
- kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
- }\r
- if (i_kid->flags & LLKHF_EXTENDED)\r
- {\r
- kid.Flags |= KEYBOARD_INPUT_DATA::E0;\r
- }\r
- kid.Reserved = 0;\r
- kid.ExtraInformation = 0;\r
-\r
- Acquire a(&m_cskidq);\r
- m_kidq.push_back(kid);\r
- SetEvent(m_readEvent);\r
- return 1;\r
- }\r
+ if ((i_kid->flags & LLKHF_INJECTED) || !m_isEnabled) {\r
+ return 0;\r
+ } else {\r
+ Key key;\r
+ KEYBOARD_INPUT_DATA kid;\r
+\r
+ kid.UnitId = 0;\r
+ kid.MakeCode = i_kid->scanCode;\r
+ kid.Flags = 0;\r
+ if (i_kid->flags & LLKHF_UP) {\r
+ kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
+ }\r
+ if (i_kid->flags & LLKHF_EXTENDED) {\r
+ kid.Flags |= KEYBOARD_INPUT_DATA::E0;\r
+ }\r
+ kid.Reserved = 0;\r
+ kid.ExtraInformation = 0;\r
+\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
-#endif // NO_DRIVER\r
\r
-// keyboard handler thread\r
-unsigned int WINAPI Engine::keyboardHandler(void *i_this)\r
+unsigned int WINAPI Engine::mouseDetour(Engine *i_this, WPARAM i_wParam, LPARAM i_lParam)\r
{\r
- reinterpret_cast<Engine *>(i_this)->keyboardHandler();\r
- _endthreadex(0);\r
- return 0;\r
+ return i_this->mouseDetour(i_wParam, reinterpret_cast<MSLLHOOKSTRUCT*>(i_lParam));\r
}\r
-void Engine::keyboardHandler()\r
+\r
+unsigned int Engine::mouseDetour(WPARAM i_message, MSLLHOOKSTRUCT *i_mid)\r
{\r
- // initialize ok\r
- CHECK_TRUE( SetEvent(m_threadEvent) );\r
- \r
- // loop\r
- Key key;\r
- while (!m_doForceTerminate)\r
- {\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
- {\r
-#else // !NO_DRIVER\r
- if (!ReadFile(m_device, &kid, sizeof(kid), &len, &m_ol))\r
- {\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
- {\r
- case WAIT_OBJECT_0: // m_readEvent\r
-#ifdef NO_DRIVER\r
- {\r
- Acquire a(&m_cskidq);\r
- if (m_kidq.empty())\r
- {\r
- goto rewait;\r
- }\r
- kid = m_kidq.front();\r
- m_kidq.pop_front();\r
- if (!m_kidq.empty())\r
- {\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
- \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 (i_mid->flags & LLMHF_INJECTED || !m_isEnabled || !m_setting || !m_setting->m_mouseEvent) {\r
+ return 0;\r
+ } else {\r
+ KEYBOARD_INPUT_DATA kid;\r
+\r
+ kid.UnitId = 0;\r
+ kid.Flags = KEYBOARD_INPUT_DATA::E1;\r
+ kid.Reserved = 0;\r
+ kid.ExtraInformation = 0;\r
+ switch (i_message) {\r
+ case WM_LBUTTONUP:\r
+ kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
+ case WM_LBUTTONDOWN:\r
+ kid.MakeCode = 1;\r
+ break;\r
+ case WM_RBUTTONUP:\r
+ kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
+ case WM_RBUTTONDOWN:\r
+ kid.MakeCode = 2;\r
+ break;\r
+ case WM_MBUTTONUP:\r
+ kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
+ case WM_MBUTTONDOWN:\r
+ kid.MakeCode = 3;\r
+ break;\r
+ case WM_MOUSEWHEEL:\r
+ if (i_mid->mouseData & (1<<31)) {\r
+ kid.MakeCode = 5;\r
+ } else {\r
+ kid.MakeCode = 4;\r
+ }\r
+ break;\r
+ case WM_XBUTTONUP:\r
+ kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;\r
+ case WM_XBUTTONDOWN:\r
+ switch ((i_mid->mouseData >> 16) & 0xFFFFU) {\r
+ case XBUTTON1:\r
+ kid.MakeCode = 6;\r
+ break;\r
+ case XBUTTON2:\r
+ kid.MakeCode = 7;\r
+ break;\r
+ default:\r
+ return 0;\r
+ break;\r
+ }\r
+ break;\r
+ case WM_MOUSEHWHEEL:\r
+ if (i_mid->mouseData & (1<<31)) {\r
+ kid.MakeCode = 9;\r
+ } else {\r
+ kid.MakeCode = 8;\r
+ }\r
+ break;\r
+ case WM_MOUSEMOVE: {\r
+ LONG dx = i_mid->pt.x - g_hookData->m_mousePos.x;\r
+ LONG dy = i_mid->pt.y - g_hookData->m_mousePos.y;\r
+ HWND target = reinterpret_cast<HWND>(g_hookData->m_hwndMouseHookTarget);\r
+\r
+ LONG dr = 0;\r
+ dr += (i_mid->pt.x - m_msllHookCurrent.pt.x) * (i_mid->pt.x - m_msllHookCurrent.pt.x);\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
+ kid.MakeCode = 0;\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
+ case MouseHookType_Wheel:\r
+ // For this type, g_hookData->m_mouseHookParam means\r
+ // translate rate mouse move to wheel.\r
+ mouse_event(MOUSEEVENTF_WHEEL, 0, 0,\r
+ g_hookData->m_mouseHookParam * dy, 0);\r
+ return 1;\r
+ break;\r
+ case MouseHookType_WindowMove: {\r
+ RECT curRect;\r
+\r
+ if (!GetWindowRect(target, &curRect))\r
+ return 0;\r
+\r
+ // g_hookData->m_mouseHookParam < 0 means\r
+ // target window to move is MDI.\r
+ if (g_hookData->m_mouseHookParam < 0) {\r
+ HWND parent = GetParent(target);\r
+ POINT p = {curRect.left, curRect.top};\r
+\r
+ if (parent == NULL || !ScreenToClient(parent, &p))\r
+ return 0;\r
+\r
+ curRect.left = p.x;\r
+ curRect.top = p.y;\r
+ }\r
+\r
+ SetWindowPos(target, NULL,\r
+ curRect.left + dx,\r
+ curRect.top + dy,\r
+ 0, 0,\r
+ SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE |\r
+ SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);\r
+ g_hookData->m_mousePos = i_mid->pt;\r
+ return 0;\r
+ break;\r
+ }\r
+ case MouseHookType_None:\r
+ default:\r
+ return 0;\r
+ break;\r
+ }\r
+ }\r
+ case WM_LBUTTONDBLCLK:\r
+ case WM_RBUTTONDBLCLK:\r
+ case WM_MBUTTONDBLCLK:\r
+ case WM_XBUTTONDBLCLK:\r
+ default:\r
+ return 0;\r
+ break;\r
+ }\r
\r
- case InterruptThreadReason_Resume:\r
- break;\r
+ WaitForSingleObject(m_queueMutex, INFINITE);\r
+\r
+ if (kid.Flags & KEYBOARD_INPUT_DATA::BREAK) {\r
+ m_buttonPressed = false;\r
+ if (m_dragging) {\r
+ KEYBOARD_INPUT_DATA kid2;\r
+\r
+ m_dragging = false;\r
+ kid2.UnitId = 0;\r
+ kid2.Flags = KEYBOARD_INPUT_DATA::E1 | KEYBOARD_INPUT_DATA::BREAK;\r
+ kid2.Reserved = 0;\r
+ kid2.ExtraInformation = 0;\r
+ kid2.MakeCode = 0;\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
- default:\r
- ASSERT( false );\r
- break;\r
- }\r
- CHECK_TRUE( SetEvent(m_threadEvent) );\r
- break;\r
- }\r
- }\r
- break;\r
- \r
- case WAIT_OBJECT_0 + NUMBER_OF(handles):\r
- {\r
- MSG message;\r
-\r
- while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))\r
- {\r
- switch (message.message)\r
- {\r
- case WM_APP + 201:\r
- {\r
- if (message.wParam)\r
- {\r
- m_currentLock.on(Modifier::Type_Touchpad);\r
- m_currentLock.on(Modifier::Type_TouchpadSticky);\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_inputQueue->push_back(kid);\r
}\r
- else\r
- m_currentLock.off(Modifier::Type_Touchpad);\r
- Acquire a(&m_log, 1);\r
- m_log << _T("touchpad: ") << message.wParam\r
- << _T(".") << (message.lParam & 0xffff)\r
- << _T(".") << (message.lParam >> 16 & 0xffff)\r
- << std::endl;\r
- break;\r
- }\r
- default:\r
- break;\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
- }\r
-\r
- checkFocusWindow();\r
-\r
- if (!m_setting || // m_setting has not been loaded\r
- !m_isEnabled) // disabled\r
- {\r
- if (m_isLogMode)\r
- {\r
- Key key;\r
- key.addScanCode(ScanCode(kid.MakeCode, kid.Flags));\r
- outputToLog(&key, ModifiedKey(), 0);\r
- }\r
- else\r
- {\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
- \r
- Acquire a(&m_cs);\r
-\r
- if (!m_currentFocusOfThread ||\r
- !m_currentKeymap)\r
- {\r
-#ifndef 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
- Acquire a(&m_log, 0);\r
- if (!m_currentFocusOfThread)\r
- m_log << _T("internal error: m_currentFocusOfThread == NULL")\r
- << std::endl;\r
- if (!m_currentKeymap)\r
- m_log << _T("internal error: m_currentKeymap == NULL")\r
- << std::endl;\r
- updateLastPressedKey(NULL);\r
- continue;\r
- }\r
- \r
- Current c;\r
- c.m_keymap = m_currentKeymap;\r
- c.m_i = m_currentFocusOfThread->m_keymaps.begin();\r
- \r
- // search key\r
- key.addScanCode(ScanCode(kid.MakeCode, kid.Flags));\r
- c.m_mkey = m_setting->m_keyboard.searchKey(key);\r
- if (!c.m_mkey.m_key)\r
- {\r
- c.m_mkey.m_key = m_setting->m_keyboard.searchPrefixKey(key);\r
- if (c.m_mkey.m_key)\r
- continue;\r
- }\r
-\r
- // press the key and update counter\r
- bool isPhysicallyPressed\r
- = !(key.getScanCodes()[0].m_flags & ScanCode::BREAK);\r
- if (c.m_mkey.m_key)\r
- {\r
- if (!c.m_mkey.m_key->m_isPressed && isPhysicallyPressed)\r
- ++ m_currentKeyPressCount;\r
- else if (c.m_mkey.m_key->m_isPressed && !isPhysicallyPressed)\r
- -- m_currentKeyPressCount;\r
- c.m_mkey.m_key->m_isPressed = isPhysicallyPressed;\r
- }\r
- \r
- // create modifiers\r
- c.m_mkey.m_modifier = getCurrentModifiers(c.m_mkey.m_key,\r
- isPhysicallyPressed);\r
- Keymap::AssignMode am;\r
- bool isModifier = fixModifierKey(&c.m_mkey, &am);\r
- if (m_isPrefix)\r
- {\r
- if (isModifier && m_doesIgnoreModifierForPrefix)\r
- am = Keymap::AM_true;\r
- if (m_doesEditNextModifier)\r
- {\r
- Modifier modifier = m_modifierForNextKey;\r
- modifier.add(c.m_mkey.m_modifier);\r
- c.m_mkey.m_modifier = modifier;\r
- }\r
- }\r
- \r
- if (m_isLogMode)\r
- outputToLog(&key, c.m_mkey, 0);\r
- else if (am == Keymap::AM_true)\r
- {\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("* true modifier") << std::endl;\r
- }\r
- // true modifier doesn't generate scan code\r
- outputToLog(&key, c.m_mkey, 1);\r
- }\r
- else if (am == Keymap::AM_oneShot || am == Keymap::AM_oneShotRepeatable)\r
- {\r
- {\r
- Acquire a(&m_log, 1);\r
- if (am == Keymap::AM_oneShot)\r
- m_log << _T("* one shot modifier") << std::endl;\r
- else\r
- m_log << _T("* one shot repeatable modifier") << std::endl;\r
- }\r
- // oneShot modifier doesn't generate scan code\r
- outputToLog(&key, c.m_mkey, 1);\r
- if (isPhysicallyPressed)\r
- {\r
- if (am == Keymap::AM_oneShotRepeatable // the key is repeating\r
- && m_oneShotKey.m_key == c.m_mkey.m_key)\r
- {\r
- if (m_oneShotRepeatableRepeatCount <\r
- m_setting->m_oneShotRepeatableDelay) {\r
- ; // delay\r
- } else {\r
- Current cnew = c;\r
- beginGeneratingKeyboardEvents(cnew, false);\r
- }\r
- ++ m_oneShotRepeatableRepeatCount;\r
- } else {\r
- m_oneShotKey = c.m_mkey;\r
- m_oneShotRepeatableRepeatCount = 0;\r
- }\r
- }\r
- else\r
- {\r
- if (m_oneShotKey.m_key)\r
- {\r
- Current cnew = c;\r
- cnew.m_mkey.m_modifier = m_oneShotKey.m_modifier;\r
- cnew.m_mkey.m_modifier.off(Modifier::Type_Up);\r
- cnew.m_mkey.m_modifier.on(Modifier::Type_Down);\r
- beginGeneratingKeyboardEvents(cnew, false);\r
- \r
- cnew = c;\r
- cnew.m_mkey.m_modifier = m_oneShotKey.m_modifier;\r
- cnew.m_mkey.m_modifier.on(Modifier::Type_Up);\r
- cnew.m_mkey.m_modifier.off(Modifier::Type_Down);\r
- beginGeneratingKeyboardEvents(cnew, false);\r
+ SetEvent(m_readEvent);\r
+ ReleaseMutex(m_queueMutex);\r
+\r
+ return 1;\r
}\r
- m_oneShotKey.m_key = NULL;\r
- m_oneShotRepeatableRepeatCount = 0;\r
- }\r
- }\r
- else if (c.m_mkey.m_key)\r
- // normal key\r
- {\r
- outputToLog(&key, c.m_mkey, 1);\r
- if (isPhysicallyPressed)\r
- m_oneShotKey.m_key = NULL;\r
- beginGeneratingKeyboardEvents(c, isModifier);\r
- }\r
- \r
- // if counter is zero, reset modifiers and keys on win32\r
- if (m_currentKeyPressCount <= 0)\r
- {\r
- {\r
- Acquire a(&m_log, 1);\r
- m_log << _T("* No key is pressed") << std::endl;\r
- }\r
- generateModifierEvents(Modifier());\r
- if (0 < m_currentKeyPressCountOnWin32)\r
- keyboardResetOnWin32();\r
- m_currentKeyPressCount = 0;\r
- m_currentKeyPressCountOnWin32 = 0;\r
- m_oneShotKey.m_key = NULL;\r
- if (m_currentLock.isOn(Modifier::Type_Touchpad) == false)\r
- m_currentLock.off(Modifier::Type_TouchpadSticky);\r
- }\r
- \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_readEvent(NULL),\r
- m_interruptThreadEvent(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
- m_eSync(NULL),\r
- m_generateKeyboardEventsRecursionGuard(0),\r
- m_currentKeyPressCount(0),\r
- m_currentKeyPressCountOnWin32(0),\r
- m_lastGeneratedKey(NULL),\r
- m_oneShotRepeatableRepeatCount(0),\r
- m_isPrefix(false),\r
- m_currentKeymap(NULL),\r
- m_currentFocusOfThread(NULL),\r
- m_hwndFocus(NULL),\r
- m_afShellExecute(NULL),\r
- m_variable(0),\r
- m_log(i_log)\r
+// keyboard handler thread\r
+unsigned int WINAPI Engine::keyboardHandler(void *i_this)\r
{\r
- for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i)\r
- m_lastPressedKey[i] = NULL;\r
- \r
- // set default lock state\r
- for (int i = 0; i < Modifier::Type_end; ++ i)\r
- m_currentLock.dontcare(static_cast<Modifier::Type>(i));\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
- m_hookPipe = CreateNamedPipe(addSessionId(HOOK_PIPE_NAME).c_str(),\r
- PIPE_ACCESS_OUTBOUND,\r
- PIPE_TYPE_BYTE, 1,\r
- 0, 0, 0, NULL);\r
- StrExprArg::setEngine(this);\r
+ reinterpret_cast<Engine *>(i_this)->keyboardHandler();\r
+ _endthreadex(0);\r
+ return 0;\r
}\r
+void Engine::keyboardHandler()\r
+{\r
+ // loop\r
+ Key key;\r
+ while (1) {\r
+ KEYBOARD_INPUT_DATA kid;\r
\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
-// open mayu device\r
-bool Engine::open()\r
-{\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
- {\r
- SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_START);\r
- if (hs)\r
- {\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
+ if (m_inputQueue->empty()) {\r
+ ResetEvent(m_readEvent);\r
+ continue;\r
+ }\r
\r
+ kid = m_inputQueue->front();\r
+ m_inputQueue->pop_front();\r
+ if (m_inputQueue->empty()) {\r
+ ResetEvent(m_readEvent);\r
+ }\r
\r
-// close mayu device\r
-void Engine::close()\r
-{\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
+ break;\r
\r
+#if 0\r
+ case WAIT_OBJECT_0 + NUMBER_OF(handles): {\r
+ MSG message;\r
+\r
+ while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {\r
+ switch (message.message) {\r
+ case WM_APP + 201: {\r
+ if (message.wParam) {\r
+ m_currentLock.on(Modifier::Type_Touchpad);\r
+ m_currentLock.on(Modifier::Type_TouchpadSticky);\r
+ } else\r
+ m_currentLock.off(Modifier::Type_Touchpad);\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("touchpad: ") << message.wParam\r
+ << _T(".") << (message.lParam & 0xffff)\r
+ << _T(".") << (message.lParam >> 16 & 0xffff)\r
+ << std::endl;\r
+ break;\r
+ }\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ goto rewait;\r
+ }\r
+#endif\r
+ }\r
+ ReleaseMutex(m_queueMutex);\r
+\r
+ checkFocusWindow();\r
+\r
+ if (!m_setting || // m_setting has not been loaded\r
+ !m_isEnabled) { // disabled\r
+ if (m_isLogMode) {\r
+ Key key;\r
+ key.addScanCode(ScanCode(kid.MakeCode, kid.Flags));\r
+ outputToLog(&key, ModifiedKey(), 0);\r
+ if (kid.Flags & KEYBOARD_INPUT_DATA::E1) {\r
+ // through mouse event even if log mode\r
+ injectInput(&kid, NULL);\r
+ }\r
+ } else {\r
+ injectInput(&kid, NULL);\r
+ }\r
+ updateLastPressedKey(NULL);\r
+ continue;\r
+ }\r
\r
-// start keyboard handler thread\r
-void Engine::start()\r
-{\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
- 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
+ Acquire a(&m_cs);\r
+\r
+ if (!m_currentFocusOfThread ||\r
+ !m_currentKeymap) {\r
+ injectInput(&kid, NULL);\r
+ Acquire a(&m_log, 0);\r
+ if (!m_currentFocusOfThread)\r
+ m_log << _T("internal error: m_currentFocusOfThread == NULL")\r
+ << std::endl;\r
+ if (!m_currentKeymap)\r
+ m_log << _T("internal error: m_currentKeymap == NULL")\r
+ << std::endl;\r
+ updateLastPressedKey(NULL);\r
+ continue;\r
+ }\r
+\r
+ Current c;\r
+ c.m_keymap = m_currentKeymap;\r
+ c.m_i = m_currentFocusOfThread->m_keymaps.begin();\r
+\r
+ // search key\r
+ key.addScanCode(ScanCode(kid.MakeCode, kid.Flags));\r
+ c.m_mkey = m_setting->m_keyboard.searchKey(key);\r
+ if (!c.m_mkey.m_key) {\r
+ c.m_mkey.m_key = m_setting->m_keyboard.searchPrefixKey(key);\r
+ if (c.m_mkey.m_key)\r
+ continue;\r
+ }\r
+\r
+ // press the key and update counter\r
+ bool isPhysicallyPressed\r
+ = !(key.getScanCodes()[0].m_flags & ScanCode::BREAK);\r
+ if (c.m_mkey.m_key) {\r
+ if (!c.m_mkey.m_key->m_isPressed && isPhysicallyPressed)\r
+ ++ m_currentKeyPressCount;\r
+ else if (c.m_mkey.m_key->m_isPressed && !isPhysicallyPressed)\r
+ -- m_currentKeyPressCount;\r
+ c.m_mkey.m_key->m_isPressed = isPhysicallyPressed;\r
+ }\r
+\r
+ // create modifiers\r
+ c.m_mkey.m_modifier = getCurrentModifiers(c.m_mkey.m_key,\r
+ isPhysicallyPressed);\r
+ Keymap::AssignMode am;\r
+ bool isModifier = fixModifierKey(&c.m_mkey, &am);\r
+ if (m_isPrefix) {\r
+ if (isModifier && m_doesIgnoreModifierForPrefix)\r
+ am = Keymap::AM_true;\r
+ if (m_doesEditNextModifier) {\r
+ Modifier modifier = m_modifierForNextKey;\r
+ modifier.add(c.m_mkey.m_modifier);\r
+ c.m_mkey.m_modifier = modifier;\r
+ }\r
+ }\r
+\r
+ if (m_isLogMode) {\r
+ outputToLog(&key, c.m_mkey, 0);\r
+ if (kid.Flags & KEYBOARD_INPUT_DATA::E1) {\r
+ // through mouse event even if log mode\r
+ injectInput(&kid, NULL);\r
+ }\r
+ } else if (am == Keymap::AM_true) {\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("* true modifier") << std::endl;\r
+ }\r
+ // true modifier doesn't generate scan code\r
+ outputToLog(&key, c.m_mkey, 1);\r
+ } else if (am == Keymap::AM_oneShot || am == Keymap::AM_oneShotRepeatable) {\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ if (am == Keymap::AM_oneShot)\r
+ m_log << _T("* one shot modifier") << std::endl;\r
+ else\r
+ m_log << _T("* one shot repeatable modifier") << std::endl;\r
+ }\r
+ // oneShot modifier doesn't generate scan code\r
+ outputToLog(&key, c.m_mkey, 1);\r
+ if (isPhysicallyPressed) {\r
+ if (am == Keymap::AM_oneShotRepeatable // the key is repeating\r
+ && m_oneShotKey.m_key == c.m_mkey.m_key) {\r
+ if (m_oneShotRepeatableRepeatCount <\r
+ m_setting->m_oneShotRepeatableDelay) {\r
+ ; // delay\r
+ } else {\r
+ Current cnew = c;\r
+ beginGeneratingKeyboardEvents(cnew, false);\r
+ }\r
+ ++ m_oneShotRepeatableRepeatCount;\r
+ } else {\r
+ m_oneShotKey = c.m_mkey;\r
+ m_oneShotRepeatableRepeatCount = 0;\r
+ }\r
+ } else {\r
+ if (m_oneShotKey.m_key) {\r
+ Current cnew = c;\r
+ cnew.m_mkey.m_modifier = m_oneShotKey.m_modifier;\r
+ cnew.m_mkey.m_modifier.off(Modifier::Type_Up);\r
+ cnew.m_mkey.m_modifier.on(Modifier::Type_Down);\r
+ beginGeneratingKeyboardEvents(cnew, false);\r
+\r
+ cnew = c;\r
+ cnew.m_mkey.m_modifier = m_oneShotKey.m_modifier;\r
+ cnew.m_mkey.m_modifier.on(Modifier::Type_Up);\r
+ cnew.m_mkey.m_modifier.off(Modifier::Type_Down);\r
+ beginGeneratingKeyboardEvents(cnew, false);\r
+ }\r
+ m_oneShotKey.m_key = NULL;\r
+ m_oneShotRepeatableRepeatCount = 0;\r
+ }\r
+ } else if (c.m_mkey.m_key) {\r
+ // normal key\r
+ outputToLog(&key, c.m_mkey, 1);\r
+ if (isPhysicallyPressed)\r
+ m_oneShotKey.m_key = NULL;\r
+ beginGeneratingKeyboardEvents(c, isModifier);\r
+ } else {\r
+ // undefined key\r
+ if (kid.Flags & KEYBOARD_INPUT_DATA::E1) {\r
+ // through mouse event even if undefined for fail safe\r
+ injectInput(&kid, NULL);\r
+ }\r
+ }\r
+\r
+ // if counter is zero, reset modifiers and keys on win32\r
+ if (m_currentKeyPressCount <= 0) {\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("* No key is pressed") << std::endl;\r
+ }\r
+ generateModifierEvents(Modifier());\r
+ if (0 < m_currentKeyPressCountOnWin32)\r
+ keyboardResetOnWin32();\r
+ m_currentKeyPressCount = 0;\r
+ m_currentKeyPressCountOnWin32 = 0;\r
+ m_oneShotKey.m_key = NULL;\r
+ if (m_currentLock.isOn(Modifier::Type_Touchpad) == false)\r
+ m_currentLock.off(Modifier::Type_TouchpadSticky);\r
+ }\r
+\r
+ key.initialize();\r
+ updateLastPressedKey(isPhysicallyPressed ? c.m_mkey.m_key : NULL);\r
+ }\r
}\r
\r
\r
-// stop keyboard handler thread\r
-void Engine::stop()\r
-{\r
- if (m_threadEvent)\r
- {\r
- m_doForceTerminate = true;\r
- do\r
- {\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
- {\r
- SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);\r
- if (hscm)\r
- {\r
- SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_STOP);\r
- if (hs)\r
- {\r
- SERVICE_STATUS ss;\r
- ControlService(hs, SERVICE_CONTROL_STOP, &ss);\r
- CloseServiceHandle(hs);\r
+Engine::Engine(tomsgstream &i_log)\r
+ : m_hwndAssocWindow(NULL),\r
+ m_setting(NULL),\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_queueMutex(NULL),\r
+ m_sts4mayu(NULL),\r
+ m_cts4mayu(NULL),\r
+ m_isLogMode(false),\r
+ m_isEnabled(true),\r
+ m_isSynchronizing(false),\r
+ m_eSync(NULL),\r
+ m_generateKeyboardEventsRecursionGuard(0),\r
+ m_currentKeyPressCount(0),\r
+ m_currentKeyPressCountOnWin32(0),\r
+ m_lastGeneratedKey(NULL),\r
+ m_oneShotRepeatableRepeatCount(0),\r
+ m_isPrefix(false),\r
+ m_currentKeymap(NULL),\r
+ m_currentFocusOfThread(NULL),\r
+ m_hwndFocus(NULL),\r
+ m_afShellExecute(NULL),\r
+ m_variable(0),\r
+ m_log(i_log) {\r
+ BOOL (WINAPI *pChangeWindowMessageFilter)(UINT, DWORD) =\r
+ reinterpret_cast<BOOL (WINAPI*)(UINT, DWORD)>(GetProcAddress(GetModuleHandle(_T("user32.dll")), "ChangeWindowMessageFilter"));\r
+\r
+ if(pChangeWindowMessageFilter != NULL) {\r
+ pChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);\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
+\r
+ for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i)\r
+ m_lastPressedKey[i] = NULL;\r
+\r
+ // set default lock state\r
+ for (int i = 0; i < Modifier::Type_end; ++ i)\r
+ m_currentLock.dontcare(static_cast<Modifier::Type>(i));\r
+ for (int i = Modifier::Type_Lock0; i <= Modifier::Type_Lock9; ++ i)\r
+ m_currentLock.release(static_cast<Modifier::Type>(i));\r
+\r
+ // create event for sync\r
+ CHECK_TRUE( m_eSync = CreateEvent(NULL, FALSE, FALSE, NULL) );\r
+ // create named pipe for &SetImeString\r
+ m_hookPipe = CreateNamedPipe(addSessionId(HOOK_PIPE_NAME).c_str(),\r
+ PIPE_ACCESS_OUTBOUND,\r
+ PIPE_TYPE_BYTE, 1,\r
+ 0, 0, 0, NULL);\r
+ StrExprArg::setEngine(this);\r
+\r
+ m_msllHookCurrent.pt.x = 0;\r
+ m_msllHookCurrent.pt.y = 0;\r
+ m_msllHookCurrent.mouseData = 0;\r
+ m_msllHookCurrent.flags = 0;\r
+ m_msllHookCurrent.time = 0;\r
+ m_msllHookCurrent.dwExtraInfo = 0;\r
}\r
\r
-bool Engine::pause()\r
-{\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
+\r
+\r
+// start keyboard handler thread\r
+void Engine::start() {\r
+ m_keyboardHandler.start(this);\r
+ m_mouseHandler.start(this);\r
+\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
}\r
\r
\r
-bool Engine::resume()\r
-{\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
+// stop keyboard handler thread\r
+void Engine::stop() {\r
+ m_mouseHandler.stop();\r
+ m_keyboardHandler.stop();\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, 2000);\r
+ CHECK_TRUE( CloseHandle(m_threadHandle) );\r
+ m_threadHandle = NULL;\r
+\r
+ CHECK_TRUE( CloseHandle(m_readEvent) );\r
+ m_readEvent = NULL;\r
}\r
\r
\r
-bool Engine::prepairQuit()\r
-{\r
- // terminate and unload DLL for ThumbSense support if loaded\r
- manageTs4mayu(_T("sts4mayu.dll"), _T("SynCOM.dll"),\r
- false, &m_sts4mayu);\r
- manageTs4mayu(_T("cts4mayu.dll"), _T("TouchPad.dll"),\r
- false, &m_cts4mayu);\r
- return true;\r
+bool Engine::prepairQuit() {\r
+ // terminate and unload DLL for ThumbSense support if loaded\r
+ manageTs4mayu(_T("sts4mayu.dll"), _T("SynCOM.dll"),\r
+ false, &m_sts4mayu);\r
+ manageTs4mayu(_T("cts4mayu.dll"), _T("TouchPad.dll"),\r
+ false, &m_cts4mayu);\r
+ return true;\r
}\r
\r
\r
-Engine::~Engine()\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
- {\r
- DisconnectNamedPipe(m_hookPipe);\r
- CHECK_TRUE( CloseHandle(m_hookPipe) );\r
- }\r
+Engine::~Engine() {\r
+ CHECK_TRUE( CloseHandle(m_eSync) );\r
+\r
+ // destroy named pipe for &SetImeString\r
+ if (m_hookPipe && m_hookPipe != INVALID_HANDLE_VALUE) {\r
+ DisconnectNamedPipe(m_hookPipe);\r
+ CHECK_TRUE( CloseHandle(m_hookPipe) );\r
+ }\r
}\r
\r
\r
void Engine::manageTs4mayu(TCHAR *i_ts4mayuDllName,\r
- TCHAR *i_dependDllName,\r
- bool i_load, HMODULE *i_pTs4mayu)\r
-{\r
- Acquire a(&m_log, 0);\r
-\r
- if (i_load == false)\r
- {\r
- if (*i_pTs4mayu)\r
- {\r
- bool (WINAPI *pTs4mayuTerm)();\r
-\r
- pTs4mayuTerm = (bool (WINAPI*)())GetProcAddress(*i_pTs4mayu, "ts4mayuTerm");\r
- if (pTs4mayuTerm() == true)\r
- FreeLibrary(*i_pTs4mayu);\r
- *i_pTs4mayu = NULL;\r
- m_log << i_ts4mayuDllName <<_T(" unloaded") << std::endl;\r
- }\r
- }\r
- else\r
- {\r
- if (*i_pTs4mayu)\r
- {\r
- m_log << i_ts4mayuDllName << _T(" already loaded") << std::endl;\r
- }\r
- else\r
- {\r
- if (SearchPath(NULL, i_dependDllName, NULL, 0, NULL, NULL) == 0)\r
- {\r
- m_log << _T("load ") << i_ts4mayuDllName\r
- << _T(" failed: can't find ") << i_dependDllName\r
- << std::endl;\r
- }\r
- else\r
- {\r
- *i_pTs4mayu = LoadLibrary(i_ts4mayuDllName);\r
- if (*i_pTs4mayu == NULL)\r
- {\r
- m_log << _T("load ") << i_ts4mayuDllName\r
- << _T(" failed: can't find it") << std::endl;\r
- }\r
- else\r
- {\r
- bool (WINAPI *pTs4mayuInit)(UINT); \r
-\r
- pTs4mayuInit = (bool (WINAPI*)(UINT))GetProcAddress(*i_pTs4mayu, "ts4mayuInit");\r
- if (pTs4mayuInit(m_threadId) == true)\r
- m_log << i_ts4mayuDllName <<_T(" loaded") << std::endl;\r
- else\r
- m_log << i_ts4mayuDllName\r
- <<_T(" load failed: can't initialize") << std::endl;\r
+ TCHAR *i_dependDllName,\r
+ bool i_load, HMODULE *i_pTs4mayu) {\r
+ Acquire a(&m_log, 0);\r
+\r
+ if (i_load == false) {\r
+ if (*i_pTs4mayu) {\r
+ bool (WINAPI *pTs4mayuTerm)();\r
+\r
+ pTs4mayuTerm = (bool (WINAPI*)())GetProcAddress(*i_pTs4mayu, "ts4mayuTerm");\r
+ if (pTs4mayuTerm() == true)\r
+ FreeLibrary(*i_pTs4mayu);\r
+ *i_pTs4mayu = NULL;\r
+ m_log << i_ts4mayuDllName <<_T(" unloaded") << std::endl;\r
+ }\r
+ } else {\r
+ if (*i_pTs4mayu) {\r
+ m_log << i_ts4mayuDllName << _T(" already loaded") << std::endl;\r
+ } else {\r
+ if (SearchPath(NULL, i_dependDllName, NULL, 0, NULL, NULL) == 0) {\r
+ m_log << _T("load ") << i_ts4mayuDllName\r
+ << _T(" failed: can't find ") << i_dependDllName\r
+ << std::endl;\r
+ } else {\r
+ *i_pTs4mayu = LoadLibrary(i_ts4mayuDllName);\r
+ if (*i_pTs4mayu == NULL) {\r
+ m_log << _T("load ") << i_ts4mayuDllName\r
+ << _T(" failed: can't find it") << std::endl;\r
+ } else {\r
+ bool (WINAPI *pTs4mayuInit)(UINT);\r
+\r
+ pTs4mayuInit = (bool (WINAPI*)(UINT))GetProcAddress(*i_pTs4mayu, "ts4mayuInit");\r
+ if (pTs4mayuInit(m_threadId) == true)\r
+ m_log << i_ts4mayuDllName <<_T(" loaded") << std::endl;\r
+ else\r
+ m_log << i_ts4mayuDllName\r
+ <<_T(" load failed: can't initialize") << std::endl;\r
+ }\r
+ }\r
+ }\r
}\r
- }\r
- }\r
- }\r
}\r
\r
\r
// set m_setting\r
-bool Engine::setSetting(Setting *i_setting)\r
-{\r
- Acquire a(&m_cs);\r
- if (m_isSynchronizing)\r
- return false;\r
-\r
- if (m_setting)\r
- {\r
- for (Keyboard::KeyIterator i = m_setting->m_keyboard.getKeyIterator();\r
- *i; ++ i)\r
- {\r
- Key *key = i_setting->m_keyboard.searchKey(*(*i));\r
- if (key)\r
- {\r
- key->m_isPressed = (*i)->m_isPressed;\r
- key->m_isPressedOnWin32 = (*i)->m_isPressedOnWin32;\r
- key->m_isPressedByAssign = (*i)->m_isPressedByAssign;\r
- }\r
- }\r
- if (m_lastGeneratedKey)\r
- m_lastGeneratedKey =\r
- i_setting->m_keyboard.searchKey(*m_lastGeneratedKey);\r
- for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i)\r
- if (m_lastPressedKey[i])\r
- m_lastPressedKey[i] =\r
- i_setting->m_keyboard.searchKey(*m_lastPressedKey[i]);\r
- }\r
- \r
- m_setting = i_setting;\r
-\r
- manageTs4mayu(_T("sts4mayu.dll"), _T("SynCOM.dll"),\r
- m_setting->m_sts4mayu, &m_sts4mayu);\r
- manageTs4mayu(_T("cts4mayu.dll"), _T("TouchPad.dll"),\r
- m_setting->m_cts4mayu, &m_cts4mayu);\r
-\r
- g_hookData->m_correctKanaLockHandling = m_setting->m_correctKanaLockHandling;\r
- if (m_currentFocusOfThread)\r
- {\r
- for (FocusOfThreads::iterator i = m_focusOfThreads.begin();\r
- i != m_focusOfThreads.end(); i ++)\r
- {\r
- FocusOfThread *fot = &(*i).second;\r
- m_setting->m_keymaps.searchWindow(&fot->m_keymaps,\r
- fot->m_className, fot->m_titleName);\r
- }\r
- }\r
- m_setting->m_keymaps.searchWindow(&m_globalFocus.m_keymaps, _T(""), _T(""));\r
- if (m_globalFocus.m_keymaps.empty())\r
- {\r
- Acquire a(&m_log, 0);\r
- m_log << _T("internal error: m_globalFocus.m_keymap is empty")\r
- << std::endl;\r
- }\r
- m_currentFocusOfThread = &m_globalFocus;\r
- setCurrentKeymap(m_globalFocus.m_keymaps.front());\r
- m_hwndFocus = NULL;\r
- return true;\r
+bool Engine::setSetting(Setting *i_setting) {\r
+ Acquire a(&m_cs);\r
+ if (m_isSynchronizing)\r
+ return false;\r
+\r
+ if (m_setting) {\r
+ for (Keyboard::KeyIterator i = m_setting->m_keyboard.getKeyIterator();\r
+ *i; ++ i) {\r
+ Key *key = i_setting->m_keyboard.searchKey(*(*i));\r
+ if (key) {\r
+ key->m_isPressed = (*i)->m_isPressed;\r
+ key->m_isPressedOnWin32 = (*i)->m_isPressedOnWin32;\r
+ key->m_isPressedByAssign = (*i)->m_isPressedByAssign;\r
+ }\r
+ }\r
+ if (m_lastGeneratedKey)\r
+ m_lastGeneratedKey =\r
+ i_setting->m_keyboard.searchKey(*m_lastGeneratedKey);\r
+ for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i)\r
+ if (m_lastPressedKey[i])\r
+ m_lastPressedKey[i] =\r
+ i_setting->m_keyboard.searchKey(*m_lastPressedKey[i]);\r
+ }\r
+\r
+ m_setting = i_setting;\r
+\r
+ manageTs4mayu(_T("sts4mayu.dll"), _T("SynCOM.dll"),\r
+ m_setting->m_sts4mayu, &m_sts4mayu);\r
+ manageTs4mayu(_T("cts4mayu.dll"), _T("TouchPad.dll"),\r
+ m_setting->m_cts4mayu, &m_cts4mayu);\r
+\r
+ g_hookData->m_correctKanaLockHandling = m_setting->m_correctKanaLockHandling;\r
+ if (m_currentFocusOfThread) {\r
+ for (FocusOfThreads::iterator i = m_focusOfThreads.begin();\r
+ i != m_focusOfThreads.end(); i ++) {\r
+ FocusOfThread *fot = &(*i).second;\r
+ m_setting->m_keymaps.searchWindow(&fot->m_keymaps,\r
+ fot->m_className, fot->m_titleName);\r
+ }\r
+ }\r
+ m_setting->m_keymaps.searchWindow(&m_globalFocus.m_keymaps, _T(""), _T(""));\r
+ if (m_globalFocus.m_keymaps.empty()) {\r
+ Acquire a(&m_log, 0);\r
+ m_log << _T("internal error: m_globalFocus.m_keymap is empty")\r
+ << std::endl;\r
+ }\r
+ m_currentFocusOfThread = &m_globalFocus;\r
+ setCurrentKeymap(m_globalFocus.m_keymaps.front());\r
+ m_hwndFocus = NULL;\r
+ return true;\r
}\r
\r
\r
-void Engine::checkShow(HWND i_hwnd)\r
-{\r
- // update show style of window\r
- // this update should be done in hook DLL, but to\r
- // avoid update-loss for some applications(such as\r
- // cmd.exe), we update here.\r
- bool isMaximized = false;\r
- bool isMinimized = false;\r
- bool isMDIMaximized = false;\r
- bool isMDIMinimized = false;\r
- while (i_hwnd)\r
- {\r
+void Engine::checkShow(HWND i_hwnd) {\r
+ // update show style of window\r
+ // this update should be done in hook DLL, but to\r
+ // avoid update-loss for some applications(such as\r
+ // cmd.exe), we update here.\r
+ bool isMaximized = false;\r
+ bool isMinimized = false;\r
+ bool isMDIMaximized = false;\r
+ bool isMDIMinimized = false;\r
+ while (i_hwnd) {\r
#ifdef MAYU64\r
- LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);\r
+ LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);\r
#else\r
- LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);\r
+ LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);\r
#endif\r
- if (exStyle & WS_EX_MDICHILD)\r
- {\r
- WINDOWPLACEMENT placement;\r
- placement.length = sizeof(WINDOWPLACEMENT);\r
- if (GetWindowPlacement(i_hwnd, &placement))\r
- {\r
- switch (placement.showCmd)\r
- {\r
- case SW_SHOWMAXIMIZED:\r
- isMDIMaximized = true;\r
- break;\r
- case SW_SHOWMINIMIZED:\r
- isMDIMinimized = true;\r
- break;\r
- case SW_SHOWNORMAL:\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
+ if (exStyle & WS_EX_MDICHILD) {\r
+ WINDOWPLACEMENT placement;\r
+ placement.length = sizeof(WINDOWPLACEMENT);\r
+ if (GetWindowPlacement(i_hwnd, &placement)) {\r
+ switch (placement.showCmd) {\r
+ case SW_SHOWMAXIMIZED:\r
+ isMDIMaximized = true;\r
+ break;\r
+ case SW_SHOWMINIMIZED:\r
+ isMDIMinimized = true;\r
+ break;\r
+ case SW_SHOWNORMAL:\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
\r
#ifdef MAYU64\r
- LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);\r
+ LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);\r
#else\r
- LONG style = GetWindowLong(i_hwnd, GWL_STYLE);\r
+ LONG style = GetWindowLong(i_hwnd, GWL_STYLE);\r
#endif\r
- if ((style & WS_CHILD) == 0)\r
- {\r
- WINDOWPLACEMENT placement;\r
- placement.length = sizeof(WINDOWPLACEMENT);\r
- if (GetWindowPlacement(i_hwnd, &placement))\r
- {\r
- switch (placement.showCmd)\r
- {\r
- case SW_SHOWMAXIMIZED:\r
- isMaximized = true;\r
- break;\r
- case SW_SHOWMINIMIZED:\r
- isMinimized = true;\r
- break;\r
- case SW_SHOWNORMAL:\r
- default:\r
- break;\r
- }\r
- }\r
- } \r
- i_hwnd = GetParent(i_hwnd);\r
- }\r
- setShow(isMDIMaximized, isMDIMinimized, true);\r
- setShow(isMaximized, isMinimized, false);\r
+ if ((style & WS_CHILD) == 0) {\r
+ WINDOWPLACEMENT placement;\r
+ placement.length = sizeof(WINDOWPLACEMENT);\r
+ if (GetWindowPlacement(i_hwnd, &placement)) {\r
+ switch (placement.showCmd) {\r
+ case SW_SHOWMAXIMIZED:\r
+ isMaximized = true;\r
+ break;\r
+ case SW_SHOWMINIMIZED:\r
+ isMinimized = true;\r
+ break;\r
+ case SW_SHOWNORMAL:\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ i_hwnd = GetParent(i_hwnd);\r
+ }\r
+ setShow(isMDIMaximized, isMDIMinimized, true);\r
+ setShow(isMaximized, isMinimized, false);\r
}\r
\r
\r
// focus\r
-bool Engine::setFocus(HWND i_hwndFocus, DWORD i_threadId, \r
- const tstringi &i_className, const tstringi &i_titleName,\r
- bool i_isConsole)\r
-{\r
- Acquire a(&m_cs);\r
- if (m_isSynchronizing)\r
- return false;\r
- if (i_hwndFocus == NULL)\r
- return true;\r
-\r
- // remove newly created thread's id from m_detachedThreadIds\r
- if (!m_detachedThreadIds.empty())\r
- {\r
- DetachedThreadIds::iterator i;\r
- bool retry;\r
- do\r
- {\r
- retry = false;\r
- for (i = m_detachedThreadIds.begin();\r
- i != m_detachedThreadIds.end(); ++ i)\r
- if (*i == i_threadId)\r
- {\r
- m_detachedThreadIds.erase(i);\r
- retry = true;\r
- break;\r
+bool Engine::setFocus(HWND i_hwndFocus, DWORD i_threadId,\r
+ const tstringi &i_className, const tstringi &i_titleName,\r
+ bool i_isConsole) {\r
+ Acquire a(&m_cs);\r
+ if (m_isSynchronizing)\r
+ return false;\r
+ if (i_hwndFocus == NULL)\r
+ return true;\r
+\r
+ // remove newly created thread's id from m_detachedThreadIds\r
+ if (!m_detachedThreadIds.empty()) {\r
+ DetachedThreadIds::iterator i;\r
+ bool retry;\r
+ do {\r
+ retry = false;\r
+ for (i = m_detachedThreadIds.begin();\r
+ i != m_detachedThreadIds.end(); ++ i)\r
+ if (*i == i_threadId) {\r
+ m_detachedThreadIds.erase(i);\r
+ retry = true;\r
+ break;\r
+ }\r
+ } while (retry);\r
}\r
- } while (retry);\r
- }\r
- \r
- FocusOfThread *fot;\r
- FocusOfThreads::iterator i = m_focusOfThreads.find(i_threadId);\r
- if (i != m_focusOfThreads.end())\r
- {\r
- fot = &(*i).second;\r
- if (fot->m_hwndFocus == i_hwndFocus &&\r
- fot->m_isConsole == i_isConsole &&\r
- fot->m_className == i_className &&\r
- fot->m_titleName == i_titleName)\r
- return true;\r
- }\r
- else\r
- {\r
- i = m_focusOfThreads.insert(\r
- FocusOfThreads::value_type(i_threadId, FocusOfThread())).first;\r
- fot = &(*i).second;\r
- fot->m_threadId = i_threadId;\r
- }\r
- fot->m_hwndFocus = i_hwndFocus;\r
- fot->m_isConsole = i_isConsole;\r
- fot->m_className = i_className;\r
- fot->m_titleName = i_titleName;\r
- \r
- if (m_setting)\r
- {\r
- m_setting->m_keymaps.searchWindow(&fot->m_keymaps,\r
- i_className, i_titleName);\r
- ASSERT(0 < fot->m_keymaps.size());\r
- }\r
- else\r
- fot->m_keymaps.clear();\r
- checkShow(i_hwndFocus);\r
- return true;\r
+\r
+ FocusOfThread *fot;\r
+ FocusOfThreads::iterator i = m_focusOfThreads.find(i_threadId);\r
+ if (i != m_focusOfThreads.end()) {\r
+ fot = &(*i).second;\r
+ if (fot->m_hwndFocus == i_hwndFocus &&\r
+ fot->m_isConsole == i_isConsole &&\r
+ fot->m_className == i_className &&\r
+ fot->m_titleName == i_titleName)\r
+ return true;\r
+ } else {\r
+ i = m_focusOfThreads.insert(\r
+ FocusOfThreads::value_type(i_threadId, FocusOfThread())).first;\r
+ fot = &(*i).second;\r
+ fot->m_threadId = i_threadId;\r
+ }\r
+ fot->m_hwndFocus = i_hwndFocus;\r
+ fot->m_isConsole = i_isConsole;\r
+ fot->m_className = i_className;\r
+ fot->m_titleName = i_titleName;\r
+\r
+ if (m_setting) {\r
+ m_setting->m_keymaps.searchWindow(&fot->m_keymaps,\r
+ i_className, i_titleName);\r
+ ASSERT(0 < fot->m_keymaps.size());\r
+ } else\r
+ fot->m_keymaps.clear();\r
+ checkShow(i_hwndFocus);\r
+ return true;\r
}\r
\r
\r
// lock state\r
bool Engine::setLockState(bool i_isNumLockToggled,\r
- bool i_isCapsLockToggled,\r
- bool i_isScrollLockToggled,\r
- bool i_isKanaLockToggled,\r
- bool i_isImeLockToggled,\r
- bool i_isImeCompToggled)\r
-{\r
- Acquire a(&m_cs);\r
- if (m_isSynchronizing)\r
- return false;\r
- m_currentLock.on(Modifier::Type_NumLock, i_isNumLockToggled);\r
- m_currentLock.on(Modifier::Type_CapsLock, i_isCapsLockToggled);\r
- m_currentLock.on(Modifier::Type_ScrollLock, i_isScrollLockToggled);\r
- m_currentLock.on(Modifier::Type_KanaLock, i_isKanaLockToggled);\r
- m_currentLock.on(Modifier::Type_ImeLock, i_isImeLockToggled);\r
- m_currentLock.on(Modifier::Type_ImeComp, i_isImeCompToggled);\r
- return true;\r
+ bool i_isCapsLockToggled,\r
+ bool i_isScrollLockToggled,\r
+ bool i_isKanaLockToggled,\r
+ bool i_isImeLockToggled,\r
+ bool i_isImeCompToggled) {\r
+ Acquire a(&m_cs);\r
+ if (m_isSynchronizing)\r
+ return false;\r
+ m_currentLock.on(Modifier::Type_NumLock, i_isNumLockToggled);\r
+ m_currentLock.on(Modifier::Type_CapsLock, i_isCapsLockToggled);\r
+ m_currentLock.on(Modifier::Type_ScrollLock, i_isScrollLockToggled);\r
+ m_currentLock.on(Modifier::Type_KanaLock, i_isKanaLockToggled);\r
+ m_currentLock.on(Modifier::Type_ImeLock, i_isImeLockToggled);\r
+ m_currentLock.on(Modifier::Type_ImeComp, i_isImeCompToggled);\r
+ return true;\r
}\r
\r
\r
// show\r
bool Engine::setShow(bool i_isMaximized, bool i_isMinimized,\r
- bool i_isMDI)\r
-{\r
- Acquire a(&m_cs);\r
- if (m_isSynchronizing)\r
- return false;\r
- Acquire b(&m_log, 1);\r
- Modifier::Type max, min;\r
- if (i_isMDI == true) {\r
- max = Modifier::Type_MdiMaximized;\r
- min = Modifier::Type_MdiMinimized;\r
- }\r
- else\r
- {\r
- max = Modifier::Type_Maximized;\r
- min = Modifier::Type_Minimized;\r
- }\r
- m_currentLock.on(max, i_isMaximized);\r
- m_currentLock.on(min, i_isMinimized);\r
- m_log << _T("Set show to ") << (i_isMaximized ? _T("Maximized") :\r
- i_isMinimized ? _T("Minimized") : _T("Normal"));\r
- if (i_isMDI == true)\r
- {\r
- m_log << _T(" (MDI)");\r
- }\r
- m_log << std::endl;\r
- return true;\r
+ bool i_isMDI) {\r
+ Acquire a(&m_cs);\r
+ if (m_isSynchronizing)\r
+ return false;\r
+ Acquire b(&m_log, 1);\r
+ Modifier::Type max, min;\r
+ if (i_isMDI == true) {\r
+ max = Modifier::Type_MdiMaximized;\r
+ min = Modifier::Type_MdiMinimized;\r
+ } else {\r
+ max = Modifier::Type_Maximized;\r
+ min = Modifier::Type_Minimized;\r
+ }\r
+ m_currentLock.on(max, i_isMaximized);\r
+ m_currentLock.on(min, i_isMinimized);\r
+ m_log << _T("Set show to ") << (i_isMaximized ? _T("Maximized") :\r
+ i_isMinimized ? _T("Minimized") : _T("Normal"));\r
+ if (i_isMDI == true) {\r
+ m_log << _T(" (MDI)");\r
+ }\r
+ m_log << std::endl;\r
+ return true;\r
}\r
\r
\r
// sync\r
-bool Engine::syncNotify()\r
-{\r
- Acquire a(&m_cs);\r
- if (!m_isSynchronizing)\r
- return false;\r
- CHECK_TRUE( SetEvent(m_eSync) );\r
- return true;\r
+bool Engine::syncNotify() {\r
+ Acquire a(&m_cs);\r
+ if (!m_isSynchronizing)\r
+ return false;\r
+ CHECK_TRUE( SetEvent(m_eSync) );\r
+ return true;\r
}\r
\r
\r
// thread detach notify\r
-bool Engine::threadDetachNotify(DWORD i_threadId)\r
-{\r
- Acquire a(&m_cs);\r
- m_detachedThreadIds.push_back(i_threadId);\r
- return true;\r
+bool Engine::threadDetachNotify(DWORD i_threadId) {\r
+ Acquire a(&m_cs);\r
+ m_detachedThreadIds.push_back(i_threadId);\r
+ return true;\r
}\r
\r
\r
// get help message\r
-void Engine::getHelpMessages(tstring *o_helpMessage, tstring *o_helpTitle)\r
+void Engine::getHelpMessages(tstring *o_helpMessage, tstring *o_helpTitle) {\r
+ Acquire a(&m_cs);\r
+ *o_helpMessage = m_helpMessage;\r
+ *o_helpTitle = m_helpTitle;\r
+}\r
+\r
+\r
+unsigned int WINAPI Engine::InputHandler::run(void *i_this)\r
{\r
- Acquire a(&m_cs);\r
- *o_helpMessage = m_helpMessage;\r
- *o_helpTitle = m_helpTitle;\r
+ reinterpret_cast<InputHandler*>(i_this)->run();\r
+ _endthreadex(0);\r
+ return 0;\r
}\r
\r
+Engine::InputHandler::InputHandler(INSTALL_HOOK i_installHook, INPUT_DETOUR i_inputDetour)\r
+ : m_installHook(i_installHook), m_inputDetour(i_inputDetour)\r
+{\r
+ CHECK_TRUE(m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL));\r
+ CHECK_TRUE(m_hThread = (HANDLE)_beginthreadex(NULL, 0, run, this, CREATE_SUSPENDED, &m_threadId));\r
+}\r
\r
-// command notify\r
-void Engine::commandNotify(\r
- HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)\r
+Engine::InputHandler::~InputHandler()\r
{\r
- Acquire b(&m_log, 0);\r
- HWND hf = m_hwndFocus;\r
- if (!hf)\r
- return;\r
-\r
- if (GetWindowThreadProcessId(hf, NULL) == \r
- GetWindowThreadProcessId(m_hwndAssocWindow, NULL))\r
- return; // inhibit the investigation of MADO TSUKAI NO YUUTSU\r
-\r
- const _TCHAR *target = NULL;\r
- int number_target = 0;\r
- \r
- if (i_hwnd == hf)\r
- target = _T("ToItself");\r
- else if (i_hwnd == GetParent(hf))\r
- target = _T("ToParentWindow");\r
- else\r
- {\r
- // Function::toMainWindow\r
- HWND h = hf;\r
- while (true)\r
- {\r
- HWND p = GetParent(h);\r
- if (!p)\r
- break;\r
- h = p;\r
- }\r
- if (i_hwnd == h)\r
- target = _T("ToMainWindow");\r
- else\r
- {\r
- // Function::toOverlappedWindow\r
- HWND h = hf;\r
- while (h)\r
- {\r
-#ifdef MAYU64\r
- LONG_PTR style = GetWindowLongPtr(h, GWL_STYLE);\r
-#else\r
- LONG style = GetWindowLong(h, GWL_STYLE);\r
-#endif\r
- if ((style & WS_CHILD) == 0)\r
- break;\r
- h = GetParent(h);\r
- }\r
- if (i_hwnd == h)\r
- target = _T("ToOverlappedWindow");\r
- else\r
- {\r
- // number\r
- HWND h = hf;\r
- for (number_target = 0; h; number_target ++, h = GetParent(h))\r
- if (i_hwnd == h)\r
- break;\r
+ CloseHandle(m_hEvent);\r
+}\r
+\r
+void Engine::InputHandler::run()\r
+{\r
+ MSG msg;\r
+\r
+ CHECK_FALSE(m_installHook(m_inputDetour, m_engine, true));\r
+ PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);\r
+ SetEvent(m_hEvent);\r
+\r
+ while (GetMessage(&msg, NULL, 0, 0)) {\r
+ // nothing to do...\r
+ }\r
+\r
+ CHECK_FALSE(m_installHook(m_inputDetour, m_engine, false));\r
+\r
return;\r
- }\r
- }\r
- }\r
-\r
- m_log << _T("&PostMessage(");\r
- if (target)\r
- m_log << target;\r
- else\r
- m_log << number_target;\r
- m_log << _T(", ") << i_message\r
- << _T(", 0x") << std::hex << i_wParam\r
- << _T(", 0x") << i_lParam << _T(") # hwnd = ")\r
- << reinterpret_cast<int>(i_hwnd) << _T(", ")\r
- << _T("message = ") << std::dec;\r
- if (i_message == WM_COMMAND)\r
- m_log << _T("WM_COMMAND, ");\r
- else if (i_message == WM_SYSCOMMAND)\r
- m_log << _T("WM_SYSCOMMAND, ");\r
- else\r
- m_log << i_message << _T(", ");\r
- m_log << _T("wNotifyCode = ") << HIWORD(i_wParam) << _T(", ")\r
- << _T("wID = ") << LOWORD(i_wParam) << _T(", ")\r
- << _T("hwndCtrl = 0x") << std::hex << i_lParam << std::dec << std::endl;\r
+}\r
+\r
+int Engine::InputHandler::start(Engine *i_engine)\r
+{\r
+ m_engine = i_engine;\r
+ ResumeThread(m_hThread);\r
+ WaitForSingleObject(m_hEvent, INFINITE);\r
+ return 0;\r
+}\r
+\r
+int Engine::InputHandler::stop()\r
+{\r
+ PostThreadMessage(m_threadId, WM_QUIT, 0, 0);\r
+ WaitForSingleObject(m_hThread, INFINITE);\r
+ return 0;\r
}\r