Changeset 2775
- Timestamp:
- Aug 20, 2006, 10:09:42 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/synergy/lib/platform/CPMKeyState.cpp
r2773 r2775 100 100 struct CWin32Modifiers { 101 101 public: 102 ULONGm_vk;103 KeyModifierMaskm_mask;102 ULONG m_vk; 103 KeyModifierMask m_mask; 104 104 }; 105 105 106 106 static const CWin32Modifiers s_modifiers[] = 107 107 { 108 109 110 111 108 { VK_SHIFT, KeyModifierShift }, 109 { VK_CTRL, KeyModifierControl }, 110 { VK_ALT, KeyModifierAlt }, 111 { VK_ALTGRAF, KeyModifierAltGr }, 112 112 }; 113 113 114 114 CPMKeyState::CPMKeyState(void* eventTarget, FakeMsgFunc fakeMsg) : 115 116 115 m_eventTarget(eventTarget), 116 m_fakeMsg(fakeMsg), 117 117 m_lastButton(0), 118 119 120 121 122 118 m_fixTimer(NULL), 119 m_lastDown(kKeyNone), 120 m_useSavedModifiers(false), 121 m_savedModifiers(0), 122 m_originalSavedModifiers(0) 123 123 { 124 124 LOG((CLOG_DEBUG2 "CPMKeyState:")); … … 128 128 { 129 129 LOG((CLOG_DEBUG2 "~CPMKeyState:")); 130 130 disable(); 131 131 } 132 132 … … 135 135 { 136 136 LOG((CLOG_DEBUG2 "disable:")); 137 138 139 140 141 142 137 if (m_fixTimer != NULL) { 138 EVENTQUEUE->removeHandler(CEvent::kTimer, m_fixTimer); 139 EVENTQUEUE->deleteTimer(m_fixTimer); 140 m_fixTimer = NULL; 141 } 142 m_lastDown = kKeyNone; 143 143 } 144 144 … … 147 147 { 148 148 LOG((CLOG_DEBUG2 "virtualKeyToButton:")); 149 149 return m_virtualKeyToButton[virtualKey & 0xffu]; 150 150 } 151 151 … … 154 154 { 155 155 LOG((CLOG_DEBUG2 "testAutoRepeat:")); 156 157 158 159 156 if (!isRepeat) 157 isRepeat = press && button == m_lastDown && button != kKeyNone; 158 m_lastDown = press ? button : kKeyNone; 159 return isRepeat; 160 160 } 161 161 … … 164 164 { 165 165 LOG((CLOG_DEBUG2 "saveModifiers:")); 166 167 166 m_savedModifiers = getActiveModifiers(); 167 m_originalSavedModifiers = m_savedModifiers; 168 168 } 169 169 … … 172 172 { 173 173 LOG((CLOG_DEBUG2 "useSavedModifiers:")); 174 175 176 177 178 179 180 181 174 if (enable != m_useSavedModifiers) { 175 m_useSavedModifiers = enable; 176 if (!m_useSavedModifiers) { 177 // transfer any modifier state changes to CKeyState's state 178 KeyModifierMask mask = m_originalSavedModifiers ^ m_savedModifiers; 179 getActiveModifiersRValue() = (getActiveModifiers() & ~mask) | (m_savedModifiers & mask); 180 } 181 } 182 182 } 183 183 … … 187 187 LOG((CLOG_DEBUG2 "mapKeyFromEvent:")); 188 188 #if 0 /** @todo */ 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 189 static const KeyModifierMask s_controlAlt = KeyModifierControl | KeyModifierAlt; 190 191 // extract character, virtual key, and if we didn't use AltGr 192 char c = (char)((charAndVirtKey & 0xff00u) >> 8); 193 ULONG vkCode = (charAndVirtKey & 0xffu); 194 bool noAltGr = ((charAndVirtKey & 0xff0000u) != 0); 195 196 // handle some keys via table lookup 197 KeyID id = getKeyID(vkCode, (KeyButton)((info >> 16) & 0x1ffu)); 198 199 // check if not in table; map character to key id 200 if (id == kKeyNone && c != 0) { 201 if ((c & 0x80u) == 0) { 202 // ASCII 203 id = static_cast<KeyID>(c) & 0xffu; 204 } 205 else { 206 // character is not really ASCII. instead it's some 207 // character in the current ANSI code page. try to 208 // convert that to a Unicode character. if we fail 209 // then use the single byte character as is. 210 char src = c; 211 wchar_t unicode; 212 if (MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, 213 &src, 1, &unicode, 1) > 0) { 214 id = static_cast<KeyID>(unicode); 215 } 216 else { 217 id = static_cast<KeyID>(c) & 0xffu; 218 } 219 } 220 } 221 222 // set modifier mask 223 if (maskOut != NULL) { 224 KeyModifierMask active = getActiveModifiers(); 225 if (!noAltGr && (active & s_controlAlt) == s_controlAlt) { 226 // if !noAltGr then we're only interested in matching the 227 // key, not the AltGr. AltGr is down (i.e. control and alt 228 // are down) but we don't want the client to have to match 229 // that so we clear it. 230 active &= ~s_controlAlt; 231 } 232 *maskOut = active; 233 } 234 return id; 235 235 #else 236 236 return kKeyNone; 237 237 #endif 238 238 } … … 242 242 { 243 243 LOG((CLOG_DEBUG2 "mapKeyToVirtualKey:")); 244 245 246 247 248 249 244 if (key == kKeyNone) 245 return 0; 246 KeyToVKMap::const_iterator i = m_keyToVKMap.find(key); 247 if (i == m_keyToVKMap.end()) 248 return 0; 249 return i->second; 250 250 } 251 251 252 252 void 253 253 CPMKeyState::sendKeyEvent(void* target, 254 255 256 254 bool press, bool isAutoRepeat, 255 KeyID key, KeyModifierMask mask, 256 SInt32 count, KeyButton button) 257 257 { 258 258 LOG((CLOG_DEBUG2 "sendKeyEvent:")); 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 259 if (press || isAutoRepeat) { 260 // send key 261 if (press && !isAutoRepeat) { 262 CKeyState::sendKeyEvent(target, true, false, key, mask, 1, button); 263 if (count > 0) { 264 --count; 265 } 266 } 267 if (count >= 1) { 268 CKeyState::sendKeyEvent(target, true, true, key, mask, count, button); 269 } 270 } 271 else { 272 // do key up 273 CKeyState::sendKeyEvent(target, false, false, key, mask, 1, button); 274 } 275 275 } 276 276 … … 279 279 { 280 280 LOG((CLOG_DEBUG2 "fakeKeyDown: id=%#x mask=%#x button=%#x", id, mask, button)); 281 281 CKeyState::fakeKeyDown(id, mask, button); 282 282 } 283 283 … … 286 286 { 287 287 LOG((CLOG_DEBUG2 "fakeKeyRepeat: id=%#x mask=%#x count=%d button=%#x", id, mask, count, button)); 288 288 CKeyState::fakeKeyRepeat(id, mask, count, button); 289 289 } 290 290 … … 300 300 { 301 301 LOG((CLOG_DEBUG2 "pollActiveModifiers:")); 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 302 KeyModifierMask state = 0; 303 304 // get non-toggle modifiers from our own shadow key state 305 for (size_t i = 0; i < sizeof(s_modifiers) / sizeof(s_modifiers[0]); ++i) { 306 KeyButton button = virtualKeyToButton(s_modifiers[i].m_vk); 307 if (button != 0 && isKeyDown(button)) { 308 state |= s_modifiers[i].m_mask; 309 } 310 } 311 312 // we can get toggle modifiers from the system 313 if (WinGetKeyState(HWND_DESKTOP, VK_CAPSLOCK) & 1) 314 state |= KeyModifierCapsLock; 315 if (WinGetKeyState(HWND_DESKTOP, VK_NUMLOCK) & 1) 316 state |= KeyModifierNumLock; 317 if (WinGetKeyState(HWND_DESKTOP, VK_SCRLLOCK) & 1) 318 state |= KeyModifierScrollLock; 319 return state; 320 320 } 321 321 … … 325 325 LOG((CLOG_DEBUG2 "pollActiveGroup:")); 326 326 #if 0 327 328 329 330 331 332 333 334 335 336 327 HKL hkl = GetKeyboardLayout(targetThread); 328 329 // get group 330 GroupMap::const_iterator i = m_groupMap.find(hkl); 331 if (i == m_groupMap.end()) { 332 LOG((CLOG_DEBUG1 "can't find keyboard layout %08x", hkl)); 333 return 0; 334 } 335 336 return i->second; 337 337 #else 338 338 return 0; … … 344 344 { 345 345 LOG((CLOG_DEBUG2 "pollPressedKeys:")); 346 346 BYTE keyState[256]; 347 347 if (WinSetKeyboardStateTable(HWND_DESKTOP, keyState, FALSE)) { 348 349 350 351 352 348 for (KeyButton i = 1; i < 256; ++i) { 349 if ((keyState[i] & 0x80) != 0) { 350 pressedKeys.insert(i); 351 } 352 } 353 353 } 354 354 } … … 399 399 CPMKeyState::convertScancodes(ClientData *pData) 400 400 { 401 402 403 404 405 401 /* 402 * This is a bit tricky / hackish, but what we have to do here is to 403 * deal with extended keys and the keypad stuff. The scancode 404 * translation tables doesn't seem to be 100% correct for these 405 * keys, and these keys are the ones we need them the most. sigh. 406 406 */ 407 407 408 409 410 //home, up, pgup, left, right, end, down, pgdn, insert, delete411 412 413 414 415 416 &&pData->s.xlatScan <= 0x69 /* VK_DELETE */417 418 419 420 421 422 423 424 425 426 427 428 429 if (pData->s.virtualKey < sizeof(s_virtualKey) / sizeof(s_virtualKey[0])430 &&!pData->s.fExtendedKey) {431 if (s_virtualKey[pData->s.virtualKey].extended == 1432 || (s_virtualKey[pData->s.virtualKey].extended == -1433 && (pData->s.xlatChar == 0434 435 436 437 438 439 440 441 442 443 444 445 //pData->s.scan = m_pmScanToOemScanExt[pData->s.xlatScan];446 447 //pData->s.scan = m_pmScanToOemScan[pData->s.xlatScan];448 449 408 // 409 // navigation and insert/delete buttons left of the numpad: 410 // home, up, pgup, left, right, end, down, pgdn, insert, delete 411 // 412 // The pm and translated scancodes are mixed up in these cases. 413 // The keys are all extended and secondary. 414 // 415 if ( pData->s.xlatScan >= 0x60 /* VK_HOME */ 416 && pData->s.xlatScan <= 0x69 /* VK_DELETE */ 417 && pData->s.virtualKey != 0) { 418 pData->s.scan = pData->s.xlatScan; 419 pData->s.xlatScan = m_pmScanToOemScanExt[pData->s.xlatScan]; 420 pData->s.fExtendedKey = true; 421 pData->s.fNeedNumUnlockKey = true; 422 pData->s.fSecondary = true; 423 return; 424 } 425 426 // 427 // There are some virtual keys we know are extended, mark them so (like the Fxx keys). 428 // 429 if ( pData->s.virtualKey < sizeof(s_virtualKey) / sizeof(s_virtualKey[0]) 430 && !pData->s.fExtendedKey) { 431 if ( s_virtualKey[pData->s.virtualKey].extended == 1 432 || ( s_virtualKey[pData->s.virtualKey].extended == -1 433 && ( pData->s.xlatChar == 0 434 || pData->s.xlatChar == s_virtualKey[pData->s.virtualKey].ch))) { 435 pData->s.fExtendedKey = true; 436 } 437 } 438 439 // 440 // Do the translating. 441 // 442 if (pData->s.xlatScan == pData->s.scan) { 443 pData->s.scan = m_pmScanToOemScan[pData->s.xlatScan]; 444 //if (pData->s.fExtendedKey) { 445 // pData->s.scan = m_pmScanToOemScanExt[pData->s.xlatScan]; 446 //} else { 447 // pData->s.scan = m_pmScanToOemScan[pData->s.xlatScan]; 448 //} 449 } 450 450 } 451 451 … … 456 456 LOG((CLOG_DEBUG2 "getKeyMap:")); 457 457 #if 0 458 459 460 461 462 463 464 465 466 458 // update keyboard groups 459 if (getGroups(m_groups)) { 460 m_groupMap.clear(); 461 SInt32 numGroups = (SInt32)m_groups.size(); 462 for (SInt32 g = 0; g < numGroups; ++g) { 463 m_groupMap[m_groups[g]] = g; 464 } 465 } 466 HKL activeLayout = GetKeyboardLayout(0); 467 467 #endif 468 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 469 // clear table 470 memset(m_virtualKeyToButton, 0, sizeof(m_virtualKeyToButton)); 471 m_keyToVKMap.clear(); 472 473 CKeyMap::KeyItem item; 474 for (SInt32 g = 0; g < 1; ++g) { 475 item.m_group = g; 476 477 // 478 // Fill the scan code conversion tables. 479 // 480 for (unsigned i = 0; i < sizeof(m_pmScanToOemScan) / sizeof(m_pmScanToOemScan[0]); i++) { 481 USHORT us = i; 482 USHORT fShiftState = 0; 483 WinTranslateChar2(0, &us, NULL, TC_SCANTOOEMSCAN, &fShiftState); 484 m_pmScanToOemScan[i] = us; 485 } 486 for (unsigned i = 0; i < sizeof(m_pmScanToOemScanExt) / sizeof(m_pmScanToOemScanExt[0]); i++) { 487 USHORT us = i; 488 USHORT fShiftState = TCF_EXTENDEDKEY; 489 WinTranslateChar2(0, &us, NULL, TC_SCANTOOEMSCAN, &fShiftState); 490 m_pmScanToOemScanExt[i] = us; 491 } 492 for (unsigned i = 0; i < sizeof(m_oemScanToPmScan) / sizeof(m_oemScanToPmScan[0]); i++) { 493 USHORT us = i; 494 USHORT fShiftState = 0; 495 WinTranslateChar2(0, &us, NULL, TC_OEMSCANTOSCAN, &fShiftState); 496 m_oemScanToPmScan[i] = us; 497 } 498 for (unsigned i = 0; i < sizeof(m_oemScanToPmScanExt) / sizeof(m_oemScanToPmScanExt[0]); i++) { 499 USHORT us = i; 500 USHORT fShiftState = TCF_EXTENDEDKEY; 501 WinTranslateChar2(0, &us, NULL, TC_OEMSCANTOSCAN, &fShiftState); 502 m_oemScanToPmScanExt[i] = us; 503 } 504 505 506 // 507 // map buttons (scancodes) to virtual keys 508 // 509 memset(m_buttonToVK, 0, sizeof(m_buttonToVK)); 510 for (KeyButton i = 1; i < 256; ++i) { 511 511 USHORT usVirtualKey = i; 512 512 USHORT fShiftState = 0; 513 514 513 WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 514 if ( usVirtualKey != 0 515 515 && m_buttonToVK[i] == 0) { 516 516 m_buttonToVK[i] = usVirtualKey; 517 518 517 } 518 } 519 519 520 520 /// @todo the stuff down to the button loop isn't really done yet. 521 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 522 // now map virtual keys to buttons. multiple virtual keys may map 523 // to a single button. if the virtual key matches the one in 524 // m_buttonToVK then we use the button as is. if not then it's 525 // either a numpad key and we use the button as is or it's an 526 // extended button. 527 for (ULONG i = 1; i < 255; ++i) { 528 // skip virtual keys we don't want 529 switch (i) { 530 case VK_BUTTON1: 531 case VK_BUTTON2: 532 case VK_BUTTON3: 533 case VK_MENU: 534 continue; 535 } 536 537 // get the button 538 538 USHORT usButton = i; 539 539 USHORT fShiftState = 0; … … 541 541 542 542 // add extended key if virtual keys don't match 543 543 if ( usButton != 0 544 544 && m_buttonToVK[usButton] != i) { 545 545 m_buttonToVK[usButton | 0x100u] = i; 546 547 548 549 550 // 551 552 553 554 555 556 557 558 // 559 560 561 562 563 564 565 546 } 547 } 548 549 // set virtual key to button table 550 // if (GetKeyboardLayout(0) == m_groups[g]) { 551 for (KeyButton i = 0; i < 512; ++i) { 552 if (m_buttonToVK[i] != 0) { 553 if (m_virtualKeyToButton[m_buttonToVK[i]] == 0) { 554 m_virtualKeyToButton[m_buttonToVK[i]] = i; 555 } 556 } 557 } 558 // } 559 560 // 561 // Add the keys to the map. 562 // 563 //for (KeyButton i = 0; i < 256; ++i) { 564 for (KeyButton i = 0; i < 256; ++i) { 565 // 566 566 // Does this translate to a virtual key or character? 567 567 // 568 568 USHORT usChar = i; 569 569 USHORT fShiftState = 0; … … 571 571 USHORT usVirtualKey = i; 572 572 USHORT fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 573 if (!usChar && !usVirtualKey) { 574 // try with control down. 575 usChar = i; 576 fShiftState = TCF_CONTROL; 577 fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState); 578 usVirtualKey = i; 579 fShiftState = TCF_CONTROL; 580 fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 581 } 582 if (!usChar && !usVirtualKey) { 583 // try with altgr down. 584 usChar = i; 585 fShiftState = TCF_ALTGR; 586 fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState); 587 usVirtualKey = i; 588 fShiftState = TCF_ALTGR; 589 fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 590 } 591 if (!usChar && !usVirtualKey) { 592 // try with numlock toggled. 593 usChar = i; 594 fShiftState = TCF_NUMLOCK; 595 fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState); 596 usVirtualKey = i; 597 fShiftState = TCF_NUMLOCK; 598 fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 599 } 600 if ( usChar 601 601 || usVirtualKey) { 602 603 604 605 606 607 608 609 610 611 602 // initialize the item 603 item.m_id = getKeyID(m_buttonToVK[i], i, false, usChar); 604 item.m_button = i; 605 item.m_required = 0; 606 item.m_sensitive = 0; 607 item.m_dead = false; 608 item.m_lock = false; 609 610 // get flags for modifier keys 611 CKeyMap::initModifierKey(item); 612 612 if (item.m_generates != 0) { 613 613 // it's a modifier key. … … 615 615 || usVirtualKey == VK_SCRLLOCK 616 616 || usVirtualKey == VK_CAPSLOCK; 617 618 619 620 621 622 623 624 625 617 ClientData data; 618 data.u = 0; 619 data.s.scan = i; 620 data.s.xlatScan = i; 621 data.s.fShiftKey = true; 622 data.s.xlatChar = usChar; 623 data.s.virtualKey = usVirtualKey; 624 convertScancodes(&data); 625 item.m_client = data.u; 626 626 addKeyEntry(keyMap, item); 627 627 } else { … … 641 641 { KeyModifierNumLock, TCF_NUMLOCK } 642 642 }; 643 644 645 646 647 648 643 usChar = i; 644 fShiftState = 0; 645 fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState); 646 usVirtualKey = i; 647 fShiftState = 0; 648 fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 649 649 for (unsigned j = 0; j < sizeof(modifiers) / sizeof(modifiers[0]); j++) { 650 650 USHORT usCh = i; … … 742 742 item.m_required |= KeyModifierShift; 743 743 item.m_sensitive |= KeyModifierShift; 744 usChar= 0; // this one is translated incorrectly744 usChar = 0; // this one is translated incorrectly 745 745 break; 746 746 } … … 749 749 item.m_id = usChar; /// @todo translate to unicode! 750 750 } 751 752 753 754 755 756 757 758 751 ClientData data; 752 data.u = 0; 753 data.s.scan = i; 754 data.s.xlatScan = i; 755 data.s.xlatChar = usChar; 756 data.s.virtualKey = usVirtualKey; 757 convertScancodes(&data); 758 item.m_client = data.u; 759 759 addKeyEntry(keyMap, item); 760 760 } … … 766 766 item.m_id = usChar - (usChar >= 'a' ? 0x60 : 0x40); 767 767 item.m_required = KeyModifierControl; 768 769 770 771 772 773 774 768 ClientData data; 769 data.u = 0; 770 data.s.scan = i; 771 data.s.xlatScan = i; 772 data.s.xlatChar = item.m_id; 773 convertScancodes(&data); 774 item.m_client = data.u; 775 775 addKeyEntry(keyMap, item); 776 776 item.m_id = usChar; … … 778 778 } 779 779 } 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 item.m_id= kKeySuper_L;804 805 806 807 808 809 810 811 item.m_id= kKeySuper_R;812 813 814 815 816 817 818 819 780 } 781 } // for buttons 0 thru 254 782 783 // 784 // Various other keys for which we don't expect the above loops to catch. 785 // 786 item.m_id = kKeyMenu; 787 item.m_button = 0xee; 788 item.m_required = 0; 789 item.m_sensitive = 0; 790 item.m_dead = false; 791 item.m_lock = false; 792 ClientData data; 793 data.u = 0; 794 data.s.scan = 0x7c; 795 data.s.xlatScan = 0xee; 796 data.s.fSecondary = true; 797 data.s.fExtendedKey = true; 798 data.s.fNeedNumUnlockKey = true; 799 item.m_client = data.u; 800 CKeyMap::initModifierKey(item); 801 addKeyEntry(keyMap, item); 802 803 item.m_id = kKeySuper_L; 804 item.m_button = 0xec; 805 data.s.xlatScan = 0xec; 806 data.s.scan = 0x7e; 807 item.m_client = data.u; 808 CKeyMap::initModifierKey(item); 809 addKeyEntry(keyMap, item); 810 811 item.m_id = kKeySuper_R; 812 item.m_button = 0xed; 813 data.s.xlatScan = 0xed; 814 data.s.scan = 0x7f; 815 item.m_client = data.u; 816 CKeyMap::initModifierKey(item); 817 addKeyEntry(keyMap, item); 818 819 } 820 820 821 821 #if 0 822 823 822 // restore keyboard layout 823 ActivateKeyboardLayout(activeLayout, 0); 824 824 #endif 825 825 } … … 829 829 { 830 830 LOG((CLOG_DEBUG2 "fakeKey:")); 831 832 833 831 switch (keystroke.m_type) { 832 case Keystroke::kButton: { 833 LOG((CLOG_DEBUG2 " %03x (%08llx) %s%s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, 834 834 keystroke.m_data.m_button.m_press ? "down" : "up", keystroke.m_data.m_button.m_repeat ? " repeate" : "")); 835 836 837 838 839 840 841 842 843 844 845 846 835 KeyButton button = keystroke.m_data.m_button.m_button; 836 837 // OS/2 doesn't send key ups for key repeats 838 if (keystroke.m_data.m_button.m_repeat && 839 !keystroke.m_data.m_button.m_press) { 840 LOG((CLOG_DEBUG " discard key repeat release")); 841 break; 842 } 843 844 // unpack the m_client packet. 845 ClientData data; 846 data.u = keystroke.m_data.m_button.m_client; 847 847 848 848 // … … 936 936 } 937 937 938 939 940 941 942 943 if ( 944 && ((modifierMask & (KeyModifierShift | KeyModifierNumLock)) == KeyModifierNumLock945 ||(modifierMask & (KeyModifierShift | KeyModifierNumLock)) == KeyModifierShift)) {946 947 948 949 950 951 952 953 954 955 956 957 958 LOG((CLOG_INFO"WM_VIOCHAR: fKC=%04x rep=%02x scan=%02x xlch=%02x(%c) xlscan=%02x fKDD=%04x ",959 960 961 962 963 964 965 } 966 967 968 969 938 // 939 // For some keys (navigation and edit keys left to the numpad), 940 // any numlock or shift needs to be 'canceled'. 941 // (At least this happens with my logitech diNovo keyboards.) 942 // 943 if ( data.s.fNeedNumUnlockKey 944 && ( (modifierMask & (KeyModifierShift | KeyModifierNumLock)) == KeyModifierNumLock 945 || (modifierMask & (KeyModifierShift | KeyModifierNumLock)) == KeyModifierShift)) { 946 // need to insert a key nullifying the numlock/shift. 947 QMSG qmsg0 = qmsg; 948 qmsg0.mp1 = MPFROMSH2CH(fKC & KC_KEYUP, 1, 0); 949 qmsg0.mp2 = MPFROM2SHORT(MAKESHORT(0, 0x2a), (fKDD & KDD_BREAK) | KDD_UNDEFINED | KDD_SECONDARY | KDD_EXTENDEDKEY); 950 951 // this message comes first on keydown and last on keyup. 952 if (fKC & KC_KEYUP) { 953 QMSG tmp = qmsg; 954 qmsg = qmsg0; 955 qmsg0 = tmp; 956 } 957 958 LOG((CLOG_DEBUG "WM_VIOCHAR: fKC=%04x rep=%02x scan=%02x xlch=%02x(%c) xlscan=%02x fKDD=%04x ", 959 SHORT1FROMMP(qmsg0.mp1), CHAR3FROMMP(qmsg0.mp1), CHAR4FROMMP(qmsg0.mp1), CHAR1FROMMP(qmsg0.mp2), 960 isprint(CHAR1FROMMP(qmsg0.mp2)) ? CHAR1FROMMP(qmsg0.mp2) : '.', CHAR2FROMMP(qmsg0.mp2), SHORT2FROMMP(qmsg0.mp2))); 961 const char *pszError = m_fakeMsg(hab, &qmsg0); 962 if (pszError) { 963 LOG((CLOG_ERR " fakeMsg failed to inject msg=%#lx mp1=%#lx mp2=%#lx: %s", qmsg0.msg, qmsg0.mp1, qmsg0.mp2, pszError)); 964 } 965 } 966 967 // 968 // Inject the (last) message. 969 // 970 970 qmsg.mp1 = MPFROMSH2CH(fKC, 1, data.s.scan); 971 971 qmsg.mp2 = MPFROM2SHORT(MAKESHORT(data.s.xlatChar, data.s.xlatScan), fKDD); 972 LOG((CLOG_ INFO"WM_VIOCHAR: fKC=%04x rep=%02x scan=%02x xlch=%02x(%c) xlscan=%02x fKDD=%04x ",972 LOG((CLOG_DEBUG "WM_VIOCHAR: fKC=%04x rep=%02x scan=%02x xlch=%02x(%c) xlscan=%02x fKDD=%04x ", 973 973 SHORT1FROMMP(qmsg.mp1), CHAR3FROMMP(qmsg.mp1), CHAR4FROMMP(qmsg.mp1), CHAR1FROMMP(qmsg.mp2), 974 974 isprint(CHAR1FROMMP(qmsg.mp2)) ? CHAR1FROMMP(qmsg.mp2) : '.', CHAR2FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2))); 975 975 const char *pszError = m_fakeMsg(hab, &qmsg); 976 976 if (pszError) { 977 977 LOG((CLOG_ERR " fakeMsg failed to inject msg=%#lx mp1=%#lx mp2=%#lx: %s", qmsg.msg, qmsg.mp1, qmsg.mp2, pszError)); 978 978 } 979 979 … … 981 981 if (keystroke.m_data.m_button.m_press && !keystroke.m_data.m_button.m_repeat) 982 982 m_lastButton = data.s.scan; 983 984 985 986 983 break; 984 } 985 986 case Keystroke::kGroup: 987 987 #if 0 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 988 // we don't restore the group. we'd like to but we can't be 989 // sure the restoring group change will be processed after the 990 // key events. 991 if (!keystroke.m_data.m_group.m_restore) { 992 if (keystroke.m_data.m_group.m_absolute) { 993 LOG((CLOG_DEBUG1 " group %d", keystroke.m_data.m_group.m_group)); 994 setWindowGroup(keystroke.m_data.m_group.m_group); 995 } 996 else { 997 LOG((CLOG_DEBUG1 " group %+d", keystroke.m_data.m_group.m_group)); 998 setWindowGroup(getEffectiveGroup(pollActiveGroup(), 999 keystroke.m_data.m_group.m_group)); 1000 } 1001 } 1002 1002 #endif 1003 1004 1003 break; 1004 } 1005 1005 } 1006 1006 … … 1009 1009 { 1010 1010 LOG((CLOG_DEBUG2 "getActiveModifiersRValue:")); 1011 1012 1013 1011 if (m_useSavedModifiers) { 1012 return m_savedModifiers; 1013 } 1014 1014 return CKeyState::getActiveModifiersRValue(); 1015 1015 } … … 1021 1021 if (virtualKey < sizeof(s_virtualKey) / sizeof(s_virtualKey[0])) { 1022 1022 1023 1024 1025 1023 // 1024 // Numpad kludge. 1025 // 1026 1026 if (numpad && s_virtualKey[virtualKey].numpad) { 1027 1027 switch (usChar) { … … 1059 1059 } 1060 1060 } else { 1061 1062 1063 1061 // 1062 // Left/right shift and control kludge. 1063 // 1064 1064 switch (virtualKey) { 1065 1065 case VK_CTRL: … … 1082 1082 KeyID 1083 1083 CPMKeyState::getIDForKey(CKeyMap::KeyItem& item, 1084 1085 1084 KeyButton button, ULONG virtualKey, 1085 PBYTE keyState) const 1086 1086 { 1087 1087 LOG((CLOG_DEBUG2 "getIDForKey:")); 1088 1088 #if 0 1089 1090 1089 int n; 1090 KeyID id; 1091 1091 WORD ascii; 1092 1092 n = ToAsciiEx(virtualKey, button, keyState, &ascii, 0, hkl); 1093 1093 id = static_cast<KeyID>(ascii & 0xffu); 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1094 switch (n) { 1095 case -1: 1096 return CKeyMap::getDeadKey(id); 1097 1098 default: 1099 case 0: 1100 // unmapped 1101 return kKeyNone; 1102 1103 case 1: 1104 return id; 1105 1106 case 2: 1107 // left over dead key in buffer; oops. 1108 return getIDForKey(item, button, virtualKey, keyState, hkl); 1109 } 1110 1110 #else 1111 1111 //fixme! … … 1138 1138 CPMKeyState::addKeyEntry(CKeyMap& keyMap, CKeyMap::KeyItem& item) 1139 1139 { 1140 1140 ClientData data; data.u = item.m_client; assert(sizeof(data.u) == sizeof(data)); 1141 1141 LOG((CLOG_DEBUG1 1142 1142 "addKeyEntry: scan=%02x+%02x req=%c%c%c%c%c%c[%c%c%c%c%c%c]{%x} id=%04x(%c) xlatChar=%02x(%c) scan=%02x xlatScan=%02x [%s]%s%s%s%s%s%s", … … 1156 1156 item.m_generates, 1157 1157 item.m_id, item.m_id < 128 && isprint(item.m_id) ? item.m_id : '.', 1158 1159 1158 data.s.xlatChar, data.s.xlatChar < 128 && isprint(data.s.xlatChar) ? data.s.xlatChar : '.', 1159 data.s.scan, data.s.xlatScan, 1160 1160 getKeyName(item.m_id), 1161 1161 data.s.fExtendedKey ? " extendedkey" : "", … … 1166 1166 item.m_dead ? " dead" : "" 1167 1167 )); 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 } 1178 1179 1168 if (data.s.scan2 || data.s.xlatScan2) { 1169 LOG((CLOG_DEBUG1 1170 "addKeyEntry: xlatChar2=%02x(%c) scan2=%02x xlatScan2=%02x", 1171 data.s.xlatChar2, data.s.xlatChar2 < 128 && isprint(data.s.xlatChar2) ? data.s.xlatChar2 : '.', 1172 data.s.scan2, data.s.xlatScan2)); 1173 } 1174 1175 if (!keyMap.addKeyEntry(item)) { 1176 LOG((CLOG_DEBUG1 "!not accepted!")); 1177 } 1178 if (item.m_group == 0) { 1179 m_keyToVKMap[item.m_id] = item.m_client; 1180 1180 } 1181 1181 }
Note:
See TracChangeset
for help on using the changeset viewer.