00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "CMSWindowsKeyState.h"
00020 #include "CMSWindowsDesks.h"
00021 #include "CThread.h"
00022 #include "CFunctionJob.h"
00023 #include "CLog.h"
00024 #include "CStringUtil.h"
00025 #include "IEventQueue.h"
00026 #include "TMethodEventJob.h"
00027 #include "CArchMiscWindows.h"
00028
00029
00030 #if !defined(VK_XBUTTON1)
00031 #define VK_XBUTTON1 0x05
00032 #define VK_XBUTTON2 0x06
00033 #endif
00034
00035
00036
00037
00038
00039
00040 const KeyID CMSWindowsKeyState::s_virtualKey[] =
00041 {
00042 { kKeyNone },
00043 { kKeyNone },
00044 { kKeyNone },
00045 { kKeyNone },
00046 { kKeyNone },
00047 { kKeyNone },
00048 { kKeyNone },
00049 { kKeyNone },
00050 { kKeyBackSpace },
00051 { kKeyTab },
00052 { kKeyNone },
00053 { kKeyNone },
00054 { kKeyClear },
00055 { kKeyReturn },
00056 { kKeyNone },
00057 { kKeyNone },
00058 { kKeyShift_L },
00059 { kKeyControl_L },
00060 { kKeyAlt_L },
00061 { kKeyPause },
00062 { kKeyCapsLock },
00063 { kKeyHangulKana },
00064 { kKeyNone },
00065 { kKeyNone },
00066 { kKeyNone },
00067 { kKeyHanjaKanzi },
00068 { kKeyNone },
00069 { kKeyEscape },
00070 { kKeyHenkan },
00071 { kKeyNone },
00072 { kKeyNone },
00073 { kKeyNone },
00074 { kKeyNone },
00075 { kKeyKP_PageUp },
00076 { kKeyKP_PageDown },
00077 { kKeyKP_End },
00078 { kKeyKP_Home },
00079 { kKeyKP_Left },
00080 { kKeyKP_Up },
00081 { kKeyKP_Right },
00082 { kKeyKP_Down },
00083 { kKeySelect },
00084 { kKeyNone },
00085 { kKeyExecute },
00086 { kKeyPrint },
00087 { kKeyKP_Insert },
00088 { kKeyKP_Delete },
00089 { kKeyHelp },
00090 { kKeyNone },
00091 { kKeyNone },
00092 { kKeyNone },
00093 { kKeyNone },
00094 { kKeyNone },
00095 { kKeyNone },
00096 { kKeyNone },
00097 { kKeyNone },
00098 { kKeyNone },
00099 { kKeyNone },
00100 { kKeyNone },
00101 { kKeyNone },
00102 { kKeyNone },
00103 { kKeyNone },
00104 { kKeyNone },
00105 { kKeyNone },
00106 { kKeyNone },
00107 { kKeyNone },
00108 { kKeyNone },
00109 { kKeyNone },
00110 { kKeyNone },
00111 { kKeyNone },
00112 { kKeyNone },
00113 { kKeyNone },
00114 { kKeyNone },
00115 { kKeyNone },
00116 { kKeyNone },
00117 { kKeyNone },
00118 { kKeyNone },
00119 { kKeyNone },
00120 { kKeyNone },
00121 { kKeyNone },
00122 { kKeyNone },
00123 { kKeyNone },
00124 { kKeyNone },
00125 { kKeyNone },
00126 { kKeyNone },
00127 { kKeyNone },
00128 { kKeyNone },
00129 { kKeyNone },
00130 { kKeyNone },
00131 { kKeyNone },
00132 { kKeyNone },
00133 { kKeySuper_L },
00134 { kKeySuper_R },
00135 { kKeyMenu },
00136 { kKeyNone },
00137 { kKeySleep },
00138 { kKeyKP_0 },
00139 { kKeyKP_1 },
00140 { kKeyKP_2 },
00141 { kKeyKP_3 },
00142 { kKeyKP_4 },
00143 { kKeyKP_5 },
00144 { kKeyKP_6 },
00145 { kKeyKP_7 },
00146 { kKeyKP_8 },
00147 { kKeyKP_9 },
00148 { kKeyKP_Multiply },
00149 { kKeyKP_Add },
00150 { kKeyKP_Separator },
00151 { kKeyKP_Subtract },
00152 { kKeyKP_Decimal },
00153 { kKeyNone },
00154 { kKeyF1 },
00155 { kKeyF2 },
00156 { kKeyF3 },
00157 { kKeyF4 },
00158 { kKeyF5 },
00159 { kKeyF6 },
00160 { kKeyF7 },
00161 { kKeyF8 },
00162 { kKeyF9 },
00163 { kKeyF10 },
00164 { kKeyF11 },
00165 { kKeyF12 },
00166 { kKeyF13 },
00167 { kKeyF14 },
00168 { kKeyF15 },
00169 { kKeyF16 },
00170 { kKeyF17 },
00171 { kKeyF18 },
00172 { kKeyF19 },
00173 { kKeyF20 },
00174 { kKeyF21 },
00175 { kKeyF22 },
00176 { kKeyF23 },
00177 { kKeyF24 },
00178 { kKeyNone },
00179 { kKeyNone },
00180 { kKeyNone },
00181 { kKeyNone },
00182 { kKeyNone },
00183 { kKeyNone },
00184 { kKeyNone },
00185 { kKeyNone },
00186 { kKeyNumLock },
00187 { kKeyScrollLock },
00188 { kKeyNone },
00189 { kKeyNone },
00190 { kKeyNone },
00191 { kKeyNone },
00192 { kKeyNone },
00193 { kKeyNone },
00194 { kKeyNone },
00195 { kKeyNone },
00196 { kKeyNone },
00197 { kKeyNone },
00198 { kKeyNone },
00199 { kKeyNone },
00200 { kKeyNone },
00201 { kKeyNone },
00202 { kKeyShift_L },
00203 { kKeyShift_R },
00204 { kKeyControl_L },
00205 { kKeyControl_R },
00206 { kKeyAlt_L },
00207 { kKeyAlt_R },
00208 { kKeyNone },
00209 { kKeyNone },
00210 { kKeyNone },
00211 { kKeyNone },
00212 { kKeyNone },
00213 { kKeyNone },
00214 { kKeyNone },
00215 { kKeyNone },
00216 { kKeyNone },
00217 { kKeyNone },
00218 { kKeyNone },
00219 { kKeyNone },
00220 { kKeyNone },
00221 { kKeyNone },
00222 { kKeyNone },
00223 { kKeyNone },
00224 { kKeyNone },
00225 { kKeyNone },
00226 { kKeyNone },
00227 { kKeyNone },
00228 { kKeyNone },
00229 { kKeyNone },
00230 { kKeyNone },
00231 { kKeyNone },
00232 { kKeyNone },
00233 { kKeyNone },
00234 { kKeyNone },
00235 { kKeyNone },
00236 { kKeyNone },
00237 { kKeyNone },
00238 { kKeyNone },
00239 { kKeyNone },
00240 { kKeyNone },
00241 { kKeyNone },
00242 { kKeyNone },
00243 { kKeyNone },
00244 { kKeyNone },
00245 { kKeyNone },
00246 { kKeyNone },
00247 { kKeyNone },
00248 { kKeyNone },
00249 { kKeyNone },
00250 { kKeyNone },
00251 { kKeyNone },
00252 { kKeyNone },
00253 { kKeyNone },
00254 { kKeyNone },
00255 { kKeyNone },
00256 { kKeyNone },
00257 { kKeyNone },
00258 { kKeyNone },
00259 { kKeyNone },
00260 { kKeyNone },
00261 { kKeyNone },
00262 { kKeyNone },
00263 { kKeyNone },
00264 { kKeyNone },
00265 { kKeyNone },
00266 { kKeyNone },
00267 { kKeyNone },
00268 { kKeyNone },
00269 { kKeyNone },
00270 { kKeyNone },
00271 { kKeyNone },
00272 { kKeyNone },
00273 { kKeyNone },
00274 { kKeyNone },
00275 { kKeyNone },
00276 { kKeyNone },
00277 { kKeyNone },
00278 { kKeyNone },
00279 { kKeyNone },
00280 { kKeyNone },
00281 { kKeyNone },
00282 { kKeyNone },
00283 { kKeyNone },
00284 { kKeyHiraganaKatakana },
00285 { kKeyZenkaku },
00286 { kKeyZenkaku },
00287 { kKeyNone },
00288 { kKeyNone },
00289 { kKeyNone },
00290 { kKeyNone },
00291 { kKeyNone },
00292 { kKeyNone },
00293 { kKeyNone },
00294 { kKeyNone },
00295 { kKeyNone },
00296 { kKeyNone },
00297 { kKeyNone },
00298
00299 { kKeyNone },
00300 { kKeyNone },
00301 { kKeyNone },
00302 { kKeyBreak },
00303 { kKeyNone },
00304 { kKeyNone },
00305 { kKeyNone },
00306 { kKeyNone },
00307 { kKeyNone },
00308 { kKeyNone },
00309 { kKeyNone },
00310 { kKeyNone },
00311 { kKeyClear },
00312 { kKeyKP_Enter },
00313 { kKeyNone },
00314 { kKeyNone },
00315 { kKeyShift_R },
00316 { kKeyControl_R },
00317 { kKeyAlt_R },
00318 { kKeyNone },
00319 { kKeyNone },
00320 { kKeyNone },
00321 { kKeyNone },
00322 { kKeyNone },
00323 { kKeyNone },
00324 { kKeyNone },
00325 { kKeyNone },
00326 { kKeyNone },
00327 { kKeyNone },
00328 { kKeyNone },
00329 { kKeyNone },
00330 { kKeyNone },
00331 { kKeyNone },
00332 { kKeyPageUp },
00333 { kKeyPageDown },
00334 { kKeyEnd },
00335 { kKeyHome },
00336 { kKeyLeft },
00337 { kKeyUp },
00338 { kKeyRight },
00339 { kKeyDown },
00340 { kKeySelect },
00341 { kKeyNone },
00342 { kKeyExecute },
00343 { kKeyPrint },
00344 { kKeyInsert },
00345 { kKeyDelete },
00346 { kKeyHelp },
00347 { kKeyNone },
00348 { kKeyNone },
00349 { kKeyNone },
00350 { kKeyNone },
00351 { kKeyNone },
00352 { kKeyNone },
00353 { kKeyNone },
00354 { kKeyNone },
00355 { kKeyNone },
00356 { kKeyNone },
00357 { kKeyNone },
00358 { kKeyNone },
00359 { kKeyNone },
00360 { kKeyNone },
00361 { kKeyNone },
00362 { kKeyNone },
00363 { kKeyNone },
00364 { kKeyNone },
00365 { kKeyNone },
00366 { kKeyNone },
00367 { kKeyNone },
00368 { kKeyNone },
00369 { kKeyNone },
00370 { kKeyNone },
00371 { kKeyNone },
00372 { kKeyNone },
00373 { kKeyNone },
00374 { kKeyNone },
00375 { kKeyNone },
00376 { kKeyNone },
00377 { kKeyNone },
00378 { kKeyNone },
00379 { kKeyNone },
00380 { kKeyNone },
00381 { kKeyNone },
00382 { kKeyNone },
00383 { kKeyNone },
00384 { kKeyNone },
00385 { kKeyNone },
00386 { kKeyNone },
00387 { kKeyNone },
00388 { kKeyNone },
00389 { kKeyNone },
00390 { kKeySuper_L },
00391 { kKeySuper_R },
00392 { kKeyMenu },
00393 { kKeyNone },
00394 { kKeyNone },
00395 { kKeyNone },
00396 { kKeyNone },
00397 { kKeyNone },
00398 { kKeyNone },
00399 { kKeyNone },
00400 { kKeyNone },
00401 { kKeyNone },
00402 { kKeyNone },
00403 { kKeyNone },
00404 { kKeyNone },
00405 { kKeyNone },
00406 { kKeyNone },
00407 { kKeyKP_Separator },
00408 { kKeyNone },
00409 { kKeyNone },
00410 { kKeyKP_Divide },
00411 { kKeyNone },
00412 { kKeyNone },
00413 { kKeyNone },
00414 { kKeyNone },
00415 { kKeyNone },
00416 { kKeyNone },
00417 { kKeyNone },
00418 { kKeyNone },
00419 { kKeyNone },
00420 { kKeyNone },
00421 { kKeyNone },
00422 { kKeyNone },
00423 { kKeyF13 },
00424 { kKeyF14 },
00425 { kKeyF15 },
00426 { kKeyF16 },
00427 { kKeyF17 },
00428 { kKeyF18 },
00429 { kKeyF19 },
00430 { kKeyF20 },
00431 { kKeyF21 },
00432 { kKeyF22 },
00433 { kKeyF23 },
00434 { kKeyF24 },
00435 { kKeyNone },
00436 { kKeyNone },
00437 { kKeyNone },
00438 { kKeyNone },
00439 { kKeyNone },
00440 { kKeyNone },
00441 { kKeyNone },
00442 { kKeyNone },
00443 { kKeyNumLock },
00444 { kKeyNone },
00445 { kKeyNone },
00446 { kKeyNone },
00447 { kKeyNone },
00448 { kKeyNone },
00449 { kKeyNone },
00450 { kKeyNone },
00451 { kKeyNone },
00452 { kKeyNone },
00453 { kKeyNone },
00454 { kKeyNone },
00455 { kKeyNone },
00456 { kKeyNone },
00457 { kKeyNone },
00458 { kKeyNone },
00459 { kKeyShift_L },
00460 { kKeyShift_R },
00461 { kKeyControl_L },
00462 { kKeyControl_R },
00463 { kKeyAlt_L },
00464 { kKeyAlt_R },
00465 { kKeyWWWBack },
00466 { kKeyWWWForward },
00467 { kKeyWWWRefresh },
00468 { kKeyWWWStop },
00469 { kKeyWWWSearch },
00470 { kKeyWWWFavorites },
00471 { kKeyWWWHome },
00472 { kKeyAudioMute },
00473 { kKeyAudioDown },
00474 { kKeyAudioUp },
00475 { kKeyAudioNext },
00476 { kKeyAudioPrev },
00477 { kKeyAudioStop },
00478 { kKeyAudioPlay },
00479 { kKeyAppMail },
00480 { kKeyAppMedia },
00481 { kKeyAppUser1 },
00482 { kKeyAppUser2 },
00483 { kKeyNone },
00484 { kKeyNone },
00485 { kKeyNone },
00486 { kKeyNone },
00487 { kKeyNone },
00488 { kKeyNone },
00489 { kKeyNone },
00490 { kKeyNone },
00491 { kKeyNone },
00492 { kKeyNone },
00493 { kKeyNone },
00494 { kKeyNone },
00495 { kKeyNone },
00496 { kKeyNone },
00497 { kKeyNone },
00498 { kKeyNone },
00499 { kKeyNone },
00500 { kKeyNone },
00501 { kKeyNone },
00502 { kKeyNone },
00503 { kKeyNone },
00504 { kKeyNone },
00505 { kKeyNone },
00506 { kKeyNone },
00507 { kKeyNone },
00508 { kKeyNone },
00509 { kKeyNone },
00510 { kKeyNone },
00511 { kKeyNone },
00512 { kKeyNone },
00513 { kKeyNone },
00514 { kKeyNone },
00515 { kKeyNone },
00516 { kKeyNone },
00517 { kKeyNone },
00518 { kKeyNone },
00519 { kKeyNone },
00520 { kKeyNone },
00521 { kKeyNone },
00522 { kKeyNone },
00523 { kKeyNone },
00524 { kKeyNone },
00525 { kKeyNone },
00526 { kKeyNone },
00527 { kKeyNone },
00528 { kKeyNone },
00529 { kKeyNone },
00530 { kKeyNone },
00531 { kKeyNone },
00532 { kKeyNone },
00533 { kKeyNone },
00534 { kKeyNone },
00535 { kKeyNone },
00536 { kKeyNone },
00537 { kKeyNone },
00538 { kKeyNone },
00539 { kKeyNone },
00540 { kKeyNone },
00541 { kKeyNone },
00542 { kKeyNone },
00543 { kKeyNone },
00544 { kKeyNone },
00545 { kKeyNone },
00546 { kKeyNone },
00547 { kKeyNone },
00548 { kKeyNone },
00549 { kKeyNone },
00550 { kKeyNone },
00551 { kKeyNone },
00552 { kKeyNone },
00553 { kKeyNone },
00554 { kKeyNone }
00555 };
00556
00557 struct CWin32Modifiers {
00558 public:
00559 UINT m_vk;
00560 KeyModifierMask m_mask;
00561 };
00562
00563 static const CWin32Modifiers s_modifiers[] =
00564 {
00565 { VK_SHIFT, KeyModifierShift },
00566 { VK_LSHIFT, KeyModifierShift },
00567 { VK_RSHIFT, KeyModifierShift },
00568 { VK_CONTROL, KeyModifierControl },
00569 { VK_LCONTROL, KeyModifierControl },
00570 { VK_RCONTROL, KeyModifierControl },
00571 { VK_MENU, KeyModifierAlt },
00572 { VK_LMENU, KeyModifierAlt },
00573 { VK_RMENU, KeyModifierAlt },
00574 { VK_LWIN, KeyModifierSuper },
00575 { VK_RWIN, KeyModifierSuper }
00576 };
00577
00578 CMSWindowsKeyState::CMSWindowsKeyState(
00579 CMSWindowsDesks* desks, void* eventTarget) :
00580 m_is95Family(CArchMiscWindows::isWindows95Family()),
00581 m_eventTarget(eventTarget),
00582 m_desks(desks),
00583 m_keyLayout(GetKeyboardLayout(0)),
00584 m_fixTimer(NULL),
00585 m_lastDown(0),
00586 m_useSavedModifiers(false),
00587 m_savedModifiers(0),
00588 m_originalSavedModifiers(0),
00589 m_eventQueue(*EVENTQUEUE)
00590 {
00591 init();
00592 }
00593
00594 CMSWindowsKeyState::CMSWindowsKeyState(
00595 CMSWindowsDesks* desks, void* eventTarget, IEventQueue& eventQueue, CKeyMap& keyMap) :
00596 CKeyState(eventQueue, keyMap),
00597 m_is95Family(CArchMiscWindows::isWindows95Family()),
00598 m_eventTarget(eventTarget),
00599 m_desks(desks),
00600 m_keyLayout(GetKeyboardLayout(0)),
00601 m_fixTimer(NULL),
00602 m_lastDown(0),
00603 m_useSavedModifiers(false),
00604 m_savedModifiers(0),
00605 m_originalSavedModifiers(0),
00606 m_eventQueue(eventQueue)
00607 {
00608 init();
00609 }
00610
00611 CMSWindowsKeyState::~CMSWindowsKeyState()
00612 {
00613 disable();
00614 }
00615
00616 void
00617 CMSWindowsKeyState::init()
00618 {
00619
00620 HMODULE userModule = GetModuleHandle("user32.dll");
00621 m_ToUnicodeEx = (ToUnicodeEx_t)GetProcAddress(userModule, "ToUnicodeEx");
00622 }
00623
00624 void
00625 CMSWindowsKeyState::disable()
00626 {
00627 if (m_fixTimer != NULL) {
00628 getEventQueue().removeHandler(CEvent::kTimer, m_fixTimer);
00629 getEventQueue().deleteTimer(m_fixTimer);
00630 m_fixTimer = NULL;
00631 }
00632 m_lastDown = 0;
00633 }
00634
00635 KeyButton
00636 CMSWindowsKeyState::virtualKeyToButton(UINT virtualKey) const
00637 {
00638 return m_virtualKeyToButton[virtualKey & 0xffu];
00639 }
00640
00641 void
00642 CMSWindowsKeyState::setKeyLayout(HKL keyLayout)
00643 {
00644 m_keyLayout = keyLayout;
00645 }
00646
00647 bool
00648 CMSWindowsKeyState::testAutoRepeat(bool press, bool isRepeat, KeyButton button)
00649 {
00650 if (!isRepeat) {
00651 isRepeat = (press && m_lastDown != 0 && button == m_lastDown);
00652 }
00653 if (press) {
00654 m_lastDown = button;
00655 }
00656 else {
00657 m_lastDown = 0;
00658 }
00659 return isRepeat;
00660 }
00661
00662 void
00663 CMSWindowsKeyState::saveModifiers()
00664 {
00665 m_savedModifiers = getActiveModifiers();
00666 m_originalSavedModifiers = m_savedModifiers;
00667 }
00668
00669 void
00670 CMSWindowsKeyState::useSavedModifiers(bool enable)
00671 {
00672 if (enable != m_useSavedModifiers) {
00673 m_useSavedModifiers = enable;
00674 if (!m_useSavedModifiers) {
00675
00676 KeyModifierMask mask = m_originalSavedModifiers ^ m_savedModifiers;
00677 getActiveModifiersRValue() =
00678 (getActiveModifiers() & ~mask) | (m_savedModifiers & mask);
00679 }
00680 }
00681 }
00682
00683 KeyID
00684 CMSWindowsKeyState::mapKeyFromEvent(WPARAM charAndVirtKey,
00685 LPARAM info, KeyModifierMask* maskOut) const
00686 {
00687 static const KeyModifierMask s_controlAlt =
00688 KeyModifierControl | KeyModifierAlt;
00689
00690
00691 char c = (char)((charAndVirtKey & 0xff00u) >> 8);
00692 UINT vkCode = (charAndVirtKey & 0xffu);
00693 bool noAltGr = ((charAndVirtKey & 0xff0000u) != 0);
00694
00695
00696 KeyID id = getKeyID(vkCode, (KeyButton)((info >> 16) & 0x1ffu));
00697
00698
00699 if (id == kKeyNone && c != 0) {
00700 if ((c & 0x80u) == 0) {
00701
00702 id = static_cast<KeyID>(c) & 0xffu;
00703 }
00704 else {
00705
00706
00707
00708
00709 char src = c;
00710 wchar_t unicode;
00711 if (MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED,
00712 &src, 1, &unicode, 1) > 0) {
00713 id = static_cast<KeyID>(unicode);
00714 }
00715 else {
00716 id = static_cast<KeyID>(c) & 0xffu;
00717 }
00718 }
00719 }
00720
00721
00722 if (maskOut != NULL) {
00723 KeyModifierMask active = getActiveModifiers();
00724 if (!noAltGr && (active & s_controlAlt) == s_controlAlt) {
00725
00726
00727
00728
00729 active &= ~s_controlAlt;
00730 }
00731 *maskOut = active;
00732 }
00733
00734 return id;
00735 }
00736
00737 bool
00738 CMSWindowsKeyState::didGroupsChange() const
00739 {
00740 GroupList groups;
00741 return (getGroups(groups) && groups != m_groups);
00742 }
00743
00744 UINT
00745 CMSWindowsKeyState::mapKeyToVirtualKey(KeyID key) const
00746 {
00747 if (key == kKeyNone) {
00748 return 0;
00749 }
00750 KeyToVKMap::const_iterator i = m_keyToVKMap.find(key);
00751 if (i == m_keyToVKMap.end()) {
00752 return 0;
00753 }
00754 else {
00755 return i->second;
00756 }
00757 }
00758
00759 void
00760 CMSWindowsKeyState::onKey(KeyButton button, bool down, KeyModifierMask newState)
00761 {
00762
00763 fixKeys();
00764 CKeyState::onKey(button, down, newState);
00765 fixKeys();
00766 }
00767
00768 void
00769 CMSWindowsKeyState::sendKeyEvent(void* target,
00770 bool press, bool isAutoRepeat,
00771 KeyID key, KeyModifierMask mask,
00772 SInt32 count, KeyButton button)
00773 {
00774 if (press || isAutoRepeat) {
00775
00776 if (press && !isAutoRepeat) {
00777 CKeyState::sendKeyEvent(target, true, false,
00778 key, mask, 1, button);
00779 if (count > 0) {
00780 --count;
00781 }
00782 }
00783 if (count >= 1) {
00784 CKeyState::sendKeyEvent(target, true, true,
00785 key, mask, count, button);
00786 }
00787 }
00788 else {
00789
00790 CKeyState::sendKeyEvent(target, false, false, key, mask, 1, button);
00791 }
00792 }
00793
00794 void
00795 CMSWindowsKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask,
00796 KeyButton button)
00797 {
00798 CKeyState::fakeKeyDown(id, mask, button);
00799 }
00800
00801 bool
00802 CMSWindowsKeyState::fakeKeyRepeat(KeyID id, KeyModifierMask mask,
00803 SInt32 count, KeyButton button)
00804 {
00805 return CKeyState::fakeKeyRepeat(id, mask, count, button);
00806 }
00807
00808 bool
00809 CMSWindowsKeyState::fakeCtrlAltDel()
00810 {
00811 if (!m_is95Family) {
00812
00813
00814
00815
00816
00817 HANDLE hEvtSendSas = OpenEvent( EVENT_MODIFY_STATE, FALSE, "Global\\SendSAS" );
00818 if ( hEvtSendSas ) {
00819 LOG((CLOG_DEBUG "found the SendSAS event - signaling my launcher to simulate ctrl+alt+del"));
00820 SetEvent( hEvtSendSas );
00821 CloseHandle( hEvtSendSas );
00822 }
00823 else {
00824 CThread cad(new CFunctionJob(&CMSWindowsKeyState::ctrlAltDelThread));
00825 cad.wait();
00826 }
00827 }
00828 else {
00829
00830 fakeKeyDown(kKeyDelete, KeyModifierControl | KeyModifierAlt,
00831 virtualKeyToButton(VK_DELETE));
00832 }
00833 return true;
00834 }
00835
00836 void
00837 CMSWindowsKeyState::ctrlAltDelThread(void*)
00838 {
00839
00840 HDESK desk = OpenDesktop("Winlogon", 0, FALSE, MAXIMUM_ALLOWED);
00841 if (desk != NULL) {
00842 if (SetThreadDesktop(desk)) {
00843 PostMessage(HWND_BROADCAST, WM_HOTKEY, 0,
00844 MAKELPARAM(MOD_CONTROL | MOD_ALT, VK_DELETE));
00845 }
00846 else {
00847 LOG((CLOG_DEBUG "can't switch to Winlogon desk: %d", GetLastError()));
00848 }
00849 CloseDesktop(desk);
00850 }
00851 else {
00852 LOG((CLOG_DEBUG "can't open Winlogon desk: %d", GetLastError()));
00853 }
00854 }
00855
00856 KeyModifierMask
00857 CMSWindowsKeyState::pollActiveModifiers() const
00858 {
00859 KeyModifierMask state = 0;
00860
00861
00862 for (size_t i = 0; i < sizeof(s_modifiers) / sizeof(s_modifiers[0]); ++i) {
00863 KeyButton button = virtualKeyToButton(s_modifiers[i].m_vk);
00864 if (button != 0 && isKeyDown(button)) {
00865 state |= s_modifiers[i].m_mask;
00866 }
00867 }
00868
00869
00870 if ((GetKeyState(VK_CAPITAL) & 0x01) != 0) {
00871 state |= KeyModifierCapsLock;
00872 }
00873 if ((GetKeyState(VK_NUMLOCK) & 0x01) != 0) {
00874 state |= KeyModifierNumLock;
00875 }
00876 if ((GetKeyState(VK_SCROLL) & 0x01) != 0) {
00877 state |= KeyModifierScrollLock;
00878 }
00879
00880 return state;
00881 }
00882
00883 SInt32
00884 CMSWindowsKeyState::pollActiveGroup() const
00885 {
00886
00887 HWND targetWindow = GetForegroundWindow();
00888 DWORD targetThread = GetWindowThreadProcessId(targetWindow, NULL);
00889
00890
00891 HKL hkl = GetKeyboardLayout(targetThread);
00892
00893 if (!hkl) {
00894
00895
00896 targetWindow = GetDesktopWindow();
00897 targetThread = GetWindowThreadProcessId(targetWindow, NULL);
00898 hkl = GetKeyboardLayout(targetThread);
00899 }
00900
00901
00902 GroupMap::const_iterator i = m_groupMap.find(hkl);
00903 if (i == m_groupMap.end()) {
00904 LOG((CLOG_DEBUG1 "can't find keyboard layout %08x", hkl));
00905 return 0;
00906 }
00907
00908 return i->second;
00909 }
00910
00911 void
00912 CMSWindowsKeyState::pollPressedKeys(KeyButtonSet& pressedKeys) const
00913 {
00914 BYTE keyState[256];
00915 if (!GetKeyboardState(keyState)) {
00916 LOG((CLOG_ERR "GetKeyboardState returned false on pollPressedKeys"));
00917 return;
00918 }
00919 for (KeyButton i = 1; i < 256; ++i) {
00920 if ((keyState[i] & 0x80) != 0) {
00921 pressedKeys.insert(i);
00922 }
00923 }
00924 }
00925
00926 void
00927 CMSWindowsKeyState::getKeyMap(CKeyMap& keyMap)
00928 {
00929
00930 if (getGroups(m_groups)) {
00931 m_groupMap.clear();
00932 SInt32 numGroups = (SInt32)m_groups.size();
00933 for (SInt32 g = 0; g < numGroups; ++g) {
00934 m_groupMap[m_groups[g]] = g;
00935 }
00936 }
00937 HKL activeLayout = GetKeyboardLayout(0);
00938
00939
00940 memset(m_virtualKeyToButton, 0, sizeof(m_virtualKeyToButton));
00941 m_keyToVKMap.clear();
00942
00943 CKeyMap::KeyItem item;
00944 SInt32 numGroups = (SInt32)m_groups.size();
00945 for (SInt32 g = 0; g < numGroups; ++g) {
00946 item.m_group = g;
00947 ActivateKeyboardLayout(m_groups[g], 0);
00948
00949
00950 memset(m_buttonToVK, 0, sizeof(m_buttonToVK));
00951 memset(m_buttonToNumpadVK, 0, sizeof(m_buttonToNumpadVK));
00952
00953
00954 for (KeyButton i = 1; i < 256; ++i) {
00955 UINT vk = MapVirtualKey(i, 1);
00956 if (vk == 0) {
00957
00958 continue;
00959 }
00960
00961
00962 switch (vk) {
00963 case VK_SHIFT:
00964
00965
00966
00967
00968
00969
00970 if (MapVirtualKey(VK_RSHIFT, 0) == i) {
00971 vk = VK_RSHIFT;
00972 }
00973 else {
00974 vk = VK_LSHIFT;
00975 }
00976 break;
00977
00978 case VK_CONTROL:
00979 vk = VK_LCONTROL;
00980 break;
00981
00982 case VK_MENU:
00983 vk = VK_LMENU;
00984 break;
00985
00986 case VK_NUMLOCK:
00987 vk = VK_PAUSE;
00988 break;
00989
00990 case VK_NUMPAD0:
00991 case VK_NUMPAD1:
00992 case VK_NUMPAD2:
00993 case VK_NUMPAD3:
00994 case VK_NUMPAD4:
00995 case VK_NUMPAD5:
00996 case VK_NUMPAD6:
00997 case VK_NUMPAD7:
00998 case VK_NUMPAD8:
00999 case VK_NUMPAD9:
01000 case VK_DECIMAL:
01001
01002 m_buttonToNumpadVK[i] = vk;
01003 continue;
01004
01005 case VK_LWIN:
01006 case VK_RWIN:
01007
01008 if (m_is95Family) {
01009 m_buttonToVK[i | 0x100u] = vk;
01010 continue;
01011 }
01012 break;
01013
01014 case VK_RETURN:
01015 case VK_PRIOR:
01016 case VK_NEXT:
01017 case VK_END:
01018 case VK_HOME:
01019 case VK_LEFT:
01020 case VK_UP:
01021 case VK_RIGHT:
01022 case VK_DOWN:
01023 case VK_INSERT:
01024 case VK_DELETE:
01025
01026 m_buttonToVK[i | 0x100u] = vk;
01027 break;
01028 }
01029
01030 if (m_buttonToVK[i] == 0) {
01031 m_buttonToVK[i] = vk;
01032 }
01033 }
01034
01035
01036
01037
01038
01039
01040 for (UINT i = 1; i < 255; ++i) {
01041
01042 switch (i) {
01043 case VK_LBUTTON:
01044 case VK_RBUTTON:
01045 case VK_MBUTTON:
01046 case VK_XBUTTON1:
01047 case VK_XBUTTON2:
01048 case VK_SHIFT:
01049 case VK_CONTROL:
01050 case VK_MENU:
01051 continue;
01052 }
01053
01054
01055 KeyButton button = static_cast<KeyButton>(MapVirtualKey(i, 0));
01056 if (button == 0) {
01057 continue;
01058 }
01059
01060
01061 switch (i) {
01062 case VK_NUMPAD0:
01063 case VK_NUMPAD1:
01064 case VK_NUMPAD2:
01065 case VK_NUMPAD3:
01066 case VK_NUMPAD4:
01067 case VK_NUMPAD5:
01068 case VK_NUMPAD6:
01069 case VK_NUMPAD7:
01070 case VK_NUMPAD8:
01071 case VK_NUMPAD9:
01072 case VK_DECIMAL:
01073 m_buttonToNumpadVK[button] = i;
01074 break;
01075
01076 default:
01077
01078 if (m_buttonToVK[button] != i) {
01079 m_buttonToVK[button | 0x100u] = i;
01080 }
01081 break;
01082 }
01083 }
01084
01085
01086 if (m_buttonToVK[0x54u] == 0) {
01087 m_buttonToVK[0x54u] = VK_SNAPSHOT;
01088 }
01089
01090
01091 if (GetKeyboardLayout(0) == m_groups[g]) {
01092 for (KeyButton i = 0; i < 512; ++i) {
01093 if (m_buttonToVK[i] != 0) {
01094 if (m_virtualKeyToButton[m_buttonToVK[i]] == 0) {
01095 m_virtualKeyToButton[m_buttonToVK[i]] = i;
01096 }
01097 }
01098 if (m_buttonToNumpadVK[i] != 0) {
01099 if (m_virtualKeyToButton[m_buttonToNumpadVK[i]] == 0) {
01100 m_virtualKeyToButton[m_buttonToNumpadVK[i]] = i;
01101 }
01102 }
01103 }
01104 }
01105
01106
01107 for (KeyButton i = 0; i < 512; ++i) {
01108 if (m_buttonToNumpadVK[i] != 0) {
01109 item.m_id = getKeyID(m_buttonToNumpadVK[i], i);
01110 item.m_button = i;
01111 item.m_required = KeyModifierNumLock;
01112 item.m_sensitive = KeyModifierNumLock | KeyModifierShift;
01113 item.m_generates = 0;
01114 item.m_client = m_buttonToNumpadVK[i];
01115 addKeyEntry(keyMap, item);
01116 }
01117 }
01118
01119
01120 BYTE keys[256];
01121 memset(keys, 0, sizeof(keys));
01122 for (KeyButton i = 0; i < 512; ++i) {
01123 if (m_buttonToVK[i] != 0) {
01124
01125 item.m_id = getKeyID(m_buttonToVK[i], i);
01126 item.m_button = i;
01127 item.m_required = 0;
01128 item.m_sensitive = 0;
01129 item.m_client = m_buttonToVK[i];
01130
01131
01132 CKeyMap::initModifierKey(item);
01133
01134 if (item.m_id == 0) {
01135
01136
01137 struct Modifier {
01138 UINT m_vk1;
01139 UINT m_vk2;
01140 BYTE m_state;
01141 KeyModifierMask m_mask;
01142 };
01143 static const Modifier modifiers[] = {
01144 { VK_SHIFT, VK_SHIFT, 0x80u, KeyModifierShift },
01145 { VK_CAPITAL, VK_CAPITAL, 0x01u, KeyModifierCapsLock },
01146 { VK_CONTROL, VK_MENU, 0x80u, KeyModifierControl |
01147 KeyModifierAlt }
01148 };
01149 static const size_t s_numModifiers =
01150 sizeof(modifiers) / sizeof(modifiers[0]);
01151 static const size_t s_numCombinations = 1 << s_numModifiers;
01152 KeyID id[s_numCombinations];
01153
01154 bool anyFound = false;
01155 KeyButton button = static_cast<KeyButton>(i & 0xffu);
01156 for (size_t j = 0; j < s_numCombinations; ++j) {
01157 for (size_t k = 0; k < s_numModifiers; ++k) {
01158
01159
01160 if ((j & (1i64 << k)) != 0) {
01161 keys[modifiers[k].m_vk1] = modifiers[k].m_state;
01162 keys[modifiers[k].m_vk2] = modifiers[k].m_state;
01163 }
01164 else {
01165 keys[modifiers[k].m_vk1] = 0;
01166 keys[modifiers[k].m_vk2] = 0;
01167 }
01168 }
01169 id[j] = getIDForKey(item, button,
01170 m_buttonToVK[i], keys, m_groups[g]);
01171 if (id[j] != 0) {
01172 anyFound = true;
01173 }
01174 }
01175
01176 if (anyFound) {
01177
01178
01179
01180 item.m_sensitive = 0;
01181 for (size_t k = 0; k < s_numModifiers; ++k) {
01182 for (size_t j = 0; j < s_numCombinations; ++j) {
01183
01184
01185 if (id[j] != id[j ^ (1ui64 << k)]) {
01186 item.m_sensitive |= modifiers[k].m_mask;
01187 break;
01188 }
01189 }
01190 }
01191
01192
01193
01194
01195 for (size_t j = 0; j < s_numCombinations; ++j) {
01196 item.m_id = id[j];
01197 item.m_required = 0;
01198 for (size_t k = 0; k < s_numModifiers; ++k) {
01199 if ((j & (1i64 << k)) != 0) {
01200 item.m_required |= modifiers[k].m_mask;
01201 }
01202 }
01203 addKeyEntry(keyMap, item);
01204 }
01205 }
01206 }
01207 else {
01208
01209 switch (m_buttonToVK[i]) {
01210 case VK_TAB:
01211
01212 item.m_id = kKeyLeftTab;
01213 item.m_required |= KeyModifierShift;
01214 item.m_sensitive |= KeyModifierShift;
01215 addKeyEntry(keyMap, item);
01216 item.m_id = kKeyTab;
01217 item.m_required &= ~KeyModifierShift;
01218 break;
01219
01220 case VK_CANCEL:
01221 item.m_required |= KeyModifierControl;
01222 item.m_sensitive |= KeyModifierControl;
01223 break;
01224
01225 case VK_SNAPSHOT:
01226 item.m_sensitive |= KeyModifierAlt;
01227 if ((i & 0x100u) == 0) {
01228
01229 item.m_required |= KeyModifierAlt;
01230 }
01231 break;
01232 }
01233 addKeyEntry(keyMap, item);
01234 }
01235 }
01236 }
01237 }
01238
01239
01240 ActivateKeyboardLayout(activeLayout, 0);
01241 }
01242
01243 void
01244 CMSWindowsKeyState::fakeKey(const Keystroke& keystroke)
01245 {
01246 switch (keystroke.m_type) {
01247 case Keystroke::kButton: {
01248 LOG((CLOG_DEBUG1 " %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
01249 KeyButton button = keystroke.m_data.m_button.m_button;
01250
01251
01252 if (keystroke.m_data.m_button.m_repeat &&
01253 !keystroke.m_data.m_button.m_press) {
01254 LOG((CLOG_DEBUG1 " discard key repeat release"));
01255 break;
01256 }
01257
01258
01259 UINT vk = keystroke.m_data.m_button.m_client;
01260
01261
01262 if (vk == VK_SNAPSHOT) {
01263 if ((getActiveModifiers() & KeyModifierAlt) != 0) {
01264
01265 button = 1;
01266 }
01267 else {
01268
01269 button = 0;
01270 }
01271 }
01272
01273
01274 m_desks->fakeKeyEvent(button, vk,
01275 keystroke.m_data.m_button.m_press,
01276 keystroke.m_data.m_button.m_repeat);
01277 break;
01278 }
01279
01280 case Keystroke::kGroup:
01281
01282
01283
01284 if (!keystroke.m_data.m_group.m_restore) {
01285 if (keystroke.m_data.m_group.m_absolute) {
01286 LOG((CLOG_DEBUG1 " group %d", keystroke.m_data.m_group.m_group));
01287 setWindowGroup(keystroke.m_data.m_group.m_group);
01288 }
01289 else {
01290 LOG((CLOG_DEBUG1 " group %+d", keystroke.m_data.m_group.m_group));
01291 setWindowGroup(getEffectiveGroup(pollActiveGroup(),
01292 keystroke.m_data.m_group.m_group));
01293 }
01294 }
01295 break;
01296 }
01297 }
01298
01299 KeyModifierMask&
01300 CMSWindowsKeyState::getActiveModifiersRValue()
01301 {
01302 if (m_useSavedModifiers) {
01303 return m_savedModifiers;
01304 }
01305 else {
01306 return CKeyState::getActiveModifiersRValue();
01307 }
01308 }
01309
01310 bool
01311 CMSWindowsKeyState::getGroups(GroupList& groups) const
01312 {
01313
01314 UInt32 newNumLayouts = GetKeyboardLayoutList(0, NULL);
01315 if (newNumLayouts == 0) {
01316 LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
01317 return false;
01318 }
01319 HKL* newLayouts = new HKL[newNumLayouts];
01320 newNumLayouts = GetKeyboardLayoutList(newNumLayouts, newLayouts);
01321 if (newNumLayouts == 0) {
01322 LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
01323 delete[] newLayouts;
01324 return false;
01325 }
01326
01327 groups.clear();
01328 groups.insert(groups.end(), newLayouts, newLayouts + newNumLayouts);
01329 delete[] newLayouts;
01330 return true;
01331 }
01332
01333 void
01334 CMSWindowsKeyState::setWindowGroup(SInt32 group)
01335 {
01336 HWND targetWindow = GetForegroundWindow();
01337
01338 bool sysCharSet = true;
01339
01340
01341
01342 PostMessage(targetWindow, WM_INPUTLANGCHANGEREQUEST,
01343 sysCharSet ? 1 : 0, (LPARAM)m_groups[group]);
01344
01345
01346
01347
01348
01349 Sleep(100);
01350 }
01351
01352 void
01353 CMSWindowsKeyState::fixKeys()
01354 {
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 if (!m_is95Family) {
01366 return;
01367 }
01368
01369 KeyButton leftButton = virtualKeyToButton(VK_LWIN);
01370 KeyButton rightButton = virtualKeyToButton(VK_RWIN);
01371 bool leftDown = isKeyDown(leftButton);
01372 bool rightDown = isKeyDown(rightButton);
01373 bool fix = (leftDown || rightDown);
01374 if (fix) {
01375
01376 bool leftAsyncDown = ((GetAsyncKeyState(VK_LWIN) & 0x8000) != 0);
01377 bool rightAsyncDown = ((GetAsyncKeyState(VK_RWIN) & 0x8000) != 0);
01378
01379 if (leftAsyncDown != leftDown || rightAsyncDown != rightDown) {
01380 KeyModifierMask state = getActiveModifiers();
01381 if (!leftAsyncDown && !rightAsyncDown) {
01382
01383 state &= ~KeyModifierSuper;
01384 }
01385
01386
01387 if (leftDown && !leftAsyncDown) {
01388 LOG((CLOG_DEBUG1 "event: fake key release left windows key (0x%03x)", leftButton));
01389 CKeyState::onKey(leftButton, false, state);
01390 CKeyState::sendKeyEvent(m_eventTarget, false, false,
01391 kKeySuper_L, state, 1, leftButton);
01392 }
01393 if (rightDown && !rightAsyncDown) {
01394 LOG((CLOG_DEBUG1 "event: fake key release right windows key (0x%03x)", rightButton));
01395 CKeyState::onKey(rightButton, false, state);
01396 CKeyState::sendKeyEvent(m_eventTarget, false, false,
01397 kKeySuper_R, state, 1, rightButton);
01398 }
01399 }
01400 }
01401
01402 if (fix && m_fixTimer == NULL) {
01403
01404 m_fixTimer = EVENTQUEUE->newTimer(0.1, NULL);
01405 EVENTQUEUE->adoptHandler(CEvent::kTimer, m_fixTimer,
01406 new TMethodEventJob<CMSWindowsKeyState>(
01407 this, &CMSWindowsKeyState::handleFixKeys));
01408 }
01409 else if (!fix && m_fixTimer != NULL) {
01410
01411 EVENTQUEUE->removeHandler(CEvent::kTimer, m_fixTimer);
01412 EVENTQUEUE->deleteTimer(m_fixTimer);
01413 m_fixTimer = NULL;
01414 }
01415 }
01416
01417 void
01418 CMSWindowsKeyState::handleFixKeys(const CEvent&, void*)
01419 {
01420 fixKeys();
01421 }
01422
01423 KeyID
01424 CMSWindowsKeyState::getKeyID(UINT virtualKey, KeyButton button)
01425 {
01426 if ((button & 0x100u) != 0) {
01427 virtualKey += 0x100u;
01428 }
01429 return s_virtualKey[virtualKey];
01430 }
01431
01432 KeyID
01433 CMSWindowsKeyState::getIDForKey(CKeyMap::KeyItem& item,
01434 KeyButton button, UINT virtualKey,
01435 PBYTE keyState, HKL hkl) const
01436 {
01437 int n;
01438 KeyID id;
01439 if (m_is95Family) {
01440
01441 WORD ascii;
01442 n = ToAsciiEx(virtualKey, button, keyState, &ascii, 0, hkl);
01443 id = static_cast<KeyID>(ascii & 0xffu);
01444 }
01445 else {
01446 WCHAR unicode[2];
01447 n = m_ToUnicodeEx(virtualKey, button, keyState,
01448 unicode, sizeof(unicode) / sizeof(unicode[0]),
01449 0, hkl);
01450 id = static_cast<KeyID>(unicode[0]);
01451 }
01452 switch (n) {
01453 case -1:
01454 return CKeyMap::getDeadKey(id);
01455
01456 default:
01457 case 0:
01458
01459 return kKeyNone;
01460
01461 case 1:
01462 return id;
01463
01464 case 2:
01465
01466
01467
01468 return kKeyNone;
01469 }
01470 }
01471
01472 void
01473 CMSWindowsKeyState::addKeyEntry(CKeyMap& keyMap, CKeyMap::KeyItem& item)
01474 {
01475 keyMap.addKeyEntry(item);
01476 if (item.m_group == 0) {
01477 m_keyToVKMap[item.m_id] = static_cast<UINT>(item.m_client);
01478 }
01479 }