Changeset 2768 for trunk/synergy/lib/platform/CPMKeyState.cpp
- Timestamp:
- Aug 20, 2006, 8:11:44 AM (19 years ago)
- File:
-
- 1 edited
-
trunk/synergy/lib/platform/CPMKeyState.cpp (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/synergy/lib/platform/CPMKeyState.cpp
r2765 r2768 28 28 29 29 // map virtual keys to synergy key enumeration 30 const KeyIDCPMKeyState::s_virtualKey[0x42] =31 { 32 /* 0x000 */ kKeyNone,// reserved33 /* 0x001 */ kKeyNone,// VK_BUTTON134 /* 0x002 */ kKeyNone,// VK_BUTTON235 /* 0x003 */ kKeyNone,// VK_BUTTON336 /* 0x004 */ kKeyBreak,// VK_BREAK37 /* 0x005 */ kKeyBackSpace,// VK_BACKSPACE38 /* 0x006 */ kKeyTab,// VK_TAB39 /* 0x007 */ kKeyLeftTab, // VK_BACKTAB -- ??? 40 /* 0x008 */ kKeyReturn,// VK_NEWLINE41 /* 0x009 */ kKeyShift_L,// VK_SHIFT42 /* 0x00a */ kKeyControl_L,// VK_CTRL43 /* 0x00b */ kKeyAlt_L,// VK_ALT44 /* 0x00c */ kKeyAltGr,// VK_ALTGRAF45 /* 0x00d */ kKeyPause,// VK_PAUSE46 /* 0x00e */ kKeyCapsLock,// VK_CAPSLOCK47 /* 0x00f */ kKeyEscape,// VK_ESC48 /* 0x010 */ kKeyNone,// VK_SPACE49 /* 0x011 */ kKeyPageUp,// VK_PAGEUP50 /* 0x012 */ kKeyPageDown,// VK_PAGEDOWN51 /* 0x013 */ kKeyEnd,// VK_END52 /* 0x014 */ kKeyHome,// VK_HOME53 /* 0x015 */ kKeyLeft,// VK_LEFT54 /* 0x016 */ kKeyUp,// VK_UP55 /* 0x017 */ kKeyRight,// VK_RIGHT56 /* 0x018 */ kKeyDown,// VK_DOWN57 /* 0x019 */ kKeyNone,// VK_PRINTSCRN58 /* 0x01a */ kKeyInsert,// VK_INSERT59 /* 0x01b */ kKeyDelete,// VK_DELETE60 /* 0x01c */ kKeyScrollLock,// VK_SCRLLOCK61 /* 0x01d */ kKeyNumLock,// VK_NUMLOCK62 /* 0x01e */ kKeyKP_Enter,// VK_ENTER63 /* 0x01f */ kKeySysReq,// VK_SYSRQ64 /* 0x020 */ kKeyF1,// VK_F165 /* 0x021 */ kKeyF2,// VK_F266 /* 0x022 */ kKeyF3,// VK_F367 /* 0x023 */ kKeyF4,// VK_F468 /* 0x024 */ kKeyF5,// VK_F569 /* 0x025 */ kKeyF6,// VK_F670 /* 0x026 */ kKeyF7,// VK_F771 /* 0x027 */ kKeyF8,// VK_F872 /* 0x028 */ kKeyF9,// VK_F973 /* 0x029 */ kKeyF10,// VK_F1074 /* 0x02a */ kKeyF11,// VK_F1175 /* 0x02b */ kKeyF12,// VK_F1276 /* 0x02c */ kKeyF13,// VK_F1377 /* 0x02d */ kKeyF14,// VK_F1478 /* 0x02e */ kKeyF15,// VK_F1579 /* 0x02f */ kKeyF16,// VK_F1680 /* 0x030 */ kKeyF17,// VK_F1781 /* 0x031 */ kKeyF18,// VK_F1882 /* 0x032 */ kKeyF19,// VK_F1983 /* 0x033 */ kKeyF20,// VK_F2084 /* 0x034 */ kKeyF21,// VK_F2185 /* 0x035 */ kKeyF22,// VK_F2286 /* 0x036 */ kKeyF23,// VK_F2387 /* 0x037 */ kKeyF24,// VK_F2488 /* 0x038 */ kKeyNone,// VK_ENDDRAG89 /* 0x039 */ kKeyClear,// VK_CLEAR90 /* 0x03a */ kKeyNone,// VK_EREOF91 /* 0x03b */ kKeyNone,// VK_PA192 /* 0x03c */ kKeyNone,// VK_ATTN93 /* 0x03d */ kKeyNone,// VK_CRSEL94 /* 0x03e */ kKeyNone,// VK_EXSEL95 /* 0x03f */ kKeyNone,// VK_COPY96 /* 0x040 */ kKeyNone,// VK_BLK197 /* 0x041 */ kKeyNone// VK_BLK230 const CPMKeyState::s_virtualKey[0x42] = 31 { 32 // reserved 33 // VK_BUTTON1 34 // VK_BUTTON2 35 // VK_BUTTON3 36 // VK_BREAK 37 // VK_BACKSPACE 38 // VK_TAB 39 { /* 0x007 */ kKeyLeftTab, 9, 0, 1 }, // VK_BACKTAB 40 // VK_NEWLINE 41 // VK_SHIFT 42 // VK_CTRL 43 // VK_ALT 44 // VK_ALTGRAF 45 // VK_PAUSE 46 // VK_CAPSLOCK 47 // VK_ESC 48 // VK_SPACE 49 // VK_PAGEUP 50 // VK_PAGEDOWN 51 // VK_END 52 // VK_HOME 53 // VK_LEFT 54 // VK_UP 55 // VK_RIGHT 56 // VK_DOWN 57 // VK_PRINTSCRN 58 // VK_INSERT 59 // VK_DELETE 60 // VK_SCRLLOCK 61 // VK_NUMLOCK 62 // VK_ENTER 63 // VK_SYSRQ 64 // VK_F1 65 // VK_F2 66 // VK_F3 67 // VK_F4 68 // VK_F5 69 // VK_F6 70 // VK_F7 71 // VK_F8 72 // VK_F9 73 // VK_F10 74 // VK_F11 75 // VK_F12 76 // VK_F13 77 // VK_F14 78 // VK_F15 79 // VK_F16 80 // VK_F17 81 // VK_F18 82 // VK_F19 83 // VK_F20 84 // VK_F21 85 // VK_F22 86 // VK_F23 87 // VK_F24 88 // VK_ENDDRAG 89 // VK_CLEAR 90 // VK_EREOF 91 // VK_PA1 92 // VK_ATTN 93 // VK_CRSEL 94 // VK_EXSEL 95 // VK_COPY 96 // VK_BLK1 97 // VK_BLK2 98 98 }; 99 99 … … 354 354 } 355 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 356 453 void 357 454 CPMKeyState::getKeyMap(CKeyMap& keyMap) … … 375 472 376 473 CKeyMap::KeyItem item; 377 // SInt32 numGroups = (SInt32)m_groups.size();378 // for (SInt32 g = 0; g < numGroups; ++g) {379 474 for (SInt32 g = 0; g < 1; ++g) { 380 475 item.m_group = g; 381 // ActivateKeyboardLayout(m_groups[g], 0); 382 383 // clear tables 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 // 384 509 memset(m_buttonToVK, 0, sizeof(m_buttonToVK)); 385 386 // map buttons (scancodes) to virtual keys387 510 for (KeyButton i = 1; i < 256; ++i) { 388 511 USHORT usVirtualKey = i; … … 394 517 } 395 518 } 519 520 396 521 397 522 // now map virtual keys to buttons. multiple virtual keys may map … … 406 531 case VK_BUTTON2: 407 532 case VK_BUTTON3: 408 case VK_SHIFT:409 case VK_CTRL:410 533 case VK_MENU: 411 534 continue; … … 423 546 } 424 547 } 425 426 /// @todo?427 // // add alt+printscreen428 // if (m_buttonToVK[0x54u] == 0) {429 // m_buttonToVK[0x54u] = VK_SNAPSHOT;430 // }431 548 432 549 // set virtual key to button table … … 441 558 // } 442 559 443 // add the keys to the map. 444 BYTE keys[256]; 445 memset(keys, 0, sizeof(keys)); 446 for (KeyButton i = 0; i < 512; ++i) { 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 // Does this translate to a virtual key or character? 567 // 447 568 USHORT usChar = i; 448 USHORT fCharShiftState = 0; 449 USHORT fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOVIRTUALKEY, &fCharShiftState); 569 USHORT fShiftState = 0; 570 USHORT fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState); 571 USHORT usVirtualKey = i; 572 USHORT fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 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 } 450 600 if ( usChar 451 || m_buttonToVK[i]) {452 // initialize item453 item.m_id = getKeyID(m_buttonToVK[i], i );601 || ) { 602 // initialize item 603 item.m_id = getKeyID(m_buttonToVK[i], i); 454 604 item.m_button = i; 455 605 item.m_required = 0; 456 606 item.m_sensitive = 0; 457 item.m_client = (m_buttonToVK[i] & 0xff) // 0-7 : virtual key. 458 | (i << 8) // 8-15: scancode 459 | (usChar & 0x3fff) // 16-29: PM char 460 | (0 << 30) // 30: KC_DEADKEY ?? 461 | (0 << 31); // 31: KC_COMPOSITE ?? 607 item.m_dead = false; 608 item.m_lock = false; 462 609 463 610 // get flags for modifier keys 464 611 CKeyMap::initModifierKey(item); 465 466 if (item.m_id == 0) { 467 #if 0 468 // translate virtual key to a character with and without 469 // shift, caps lock, and AltGr. 470 struct Modifier { 471 ULONG m_vk1; 472 ULONG m_vk2; 473 BYTE m_state; 474 KeyModifierMask m_mask; 475 }; 476 static const Modifier modifiers[] = { 477 { VK_SHIFT, VK_SHIFT, 0x80u, KeyModifierShift }, 478 { VK_CAPITAL, VK_CAPITAL, 0x01u, KeyModifierCapsLock }, 479 { VK_CONTROL, VK_MENU, 0x80u, KeyModifierControl | KeyModifierAlt } 480 }; 481 static const size_t s_numModifiers = sizeof(modifiers) / sizeof(modifiers[0]); 482 static const size_t s_numCombinations = 1 << s_numModifiers; 483 KeyID id[s_numCombinations]; 484 485 bool anyFound = false; 486 KeyButton button = static_cast<KeyButton>(i & 0xffu); 487 for (size_t j = 0; j < s_numCombinations; ++j) { 488 for (size_t k = 0; k < s_numModifiers; ++k) { 489 if ((j & (1 << k)) != 0) { 490 keys[modifiers[k].m_vk1] = modifiers[k].m_state; 491 keys[modifiers[k].m_vk2] = modifiers[k].m_state; 492 } 493 else { 494 keys[modifiers[k].m_vk1] = 0; 495 keys[modifiers[k].m_vk2] = 0; 496 } 497 } 498 id[j] = getIDForKey(item, button, m_buttonToVK[i], keys, m_groups[g]); 499 if (id[j] != 0) { 500 anyFound = true; 501 } 502 } 503 504 if (anyFound) { 505 // determine what modifiers we're sensitive to. 506 // we're sensitive if the KeyID changes when the 507 // modifier does. 508 item.m_sensitive = 0; 509 for (size_t k = 0; k < s_numModifiers; ++k) { 510 for (size_t j = 0; j < s_numCombinations; ++j) { 511 if (id[j] != id[j ^ (1u << k)]) { 512 item.m_sensitive |= modifiers[k].m_mask; 513 break; 514 } 515 } 516 } 517 518 // save each key. the map will automatically discard 519 // duplicates, like an unshift and shifted version of 520 // a key that's insensitive to shift. 521 for (size_t j = 0; j < s_numCombinations; ++j) { 522 item.m_id = id[j]; 523 item.m_required = 0; 524 for (size_t k = 0; k < s_numModifiers; ++k) { 525 if ((j & (1 << k)) != 0) { 526 item.m_required |= modifiers[k].m_mask; 527 } 528 } 529 addKeyEntry(keyMap, item); 530 } 531 } 532 #endif 533 } else { 534 // found in table - adjust modifiers and add it. 535 switch (m_buttonToVK[i]) { 536 case VK_BACKTAB: 537 item.m_required |= KeyModifierShift; 538 item.m_sensitive |= KeyModifierShift; 539 break; 540 } 541 addKeyEntry(keyMap, item); 542 } 543 } 544 } // for buttons 0 thru 511 612 if (item.m_generates != 0) { 613 // it's a modifier key. 614 item.m_lock = usVirtualKey == VK_NUMLOCK 615 || usVirtualKey == VK_SCRLLOCK 616 || usVirtualKey == VK_CAPSLOCK; 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 addKeyEntry(keyMap, item); 627 } else { 628 // 629 // Check which keys it might be sensitive to. 630 // We assume (possibly incorrectly) that combinations doesn't matter... :) 631 // 632 static const struct { 633 KeyModifierMask mask; 634 unsigned fShiftState; 635 } modifiers[] = { 636 { KeyModifierShift, TCF_SHIFT}, 637 { KeyModifierControl, TCF_CONTROL }, 638 { KeyModifierAlt, TCF_ALT }, 639 { KeyModifierAltGr, TCF_ALTGR }, 640 { KeyModifierCapsLock, TCF_CAPSLOCK }, 641 { KeyModifierNumLock, TCF_NUMLOCK } 642 }; 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 for (unsigned j = 0; j < sizeof(modifiers) / sizeof(modifiers[0]); j++) { 650 USHORT usCh = i; 651 fShiftState = modifiers[j].fShiftState; 652 if ( WinTranslateChar2(0, &usCh, NULL, TC_SCANCODETOCHAR, &fShiftState) != 0 653 && usCh != 0 654 && usCh != usChar) { 655 item.m_sensitive |= modifiers[j].mask; 656 continue; 657 } 658 usCh = i; 659 fShiftState = modifiers[j].fShiftState; 660 WinTranslateChar2(0, &usCh, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 661 if ( usCh != 0 662 && usCh != usVirtualKey) { 663 item.m_sensitive |= modifiers[j].mask; 664 continue; 665 } 666 } 667 if (isASCIIControlChar(usChar)) { 668 item.m_sensitive |= KeyModifierControl; 669 } 670 671 // 672 // Check for numpad keys. We need to adjust stuff then. 673 // It think this test should be sufficient. 674 // 675 bool numpad = (item.m_sensitive & KeyModifierNumLock) != 0; 676 677 // 678 // Unoptimized brute force algorithm for determining the 679 // possible combinations and adding them to the key map. 680 // 681 struct 682 { 683 UCHAR uchChar; 684 UCHAR uchVirtualKey; 685 } combinations[1 << TCF_MAX_BITS]; 686 687 for (unsigned j = 0; j < sizeof(combinations) / sizeof(combinations[0]); j++) { 688 const KeyModifierMask mask = convertTCFToKeyModiferMask(j); 689 if ((mask & item.m_sensitive) != mask /*|| j>3*/) { 690 combinations[j].uchChar = combinations[j].uchVirtualKey = 0; 691 continue; 692 } 693 // get any character value 694 USHORT us = i; 695 fShiftState = j; 696 if (WinTranslateChar2(0, &us, NULL, TC_SCANCODETOCHAR, &fShiftState) == 0) { 697 us = 0; 698 } 699 combinations[j].uchChar = us; 700 701 // get any virtual key value 702 us = i; 703 fShiftState = j; 704 WinTranslateChar2(0, &us, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 705 combinations[j].uchVirtualKey = us; 706 707 // deal with missing character translations 708 if ( combinations[j].uchChar == 0 709 && us != 0 710 && us < sizeof(s_virtualKey) / sizeof(s_virtualKey[0])) { 711 combinations[j].uchChar = s_virtualKey[us].ch; 712 } 713 } 714 715 // 2. Eliminate duplicates. 716 for (unsigned j = 0; j < sizeof(combinations) / sizeof(combinations[0]); j++) { 717 unsigned best = j; 718 KeyModifierMask bestMask = convertTCFToKeyModiferMask(j); 719 for (unsigned k = j + 1; k < sizeof(combinations) / sizeof(combinations[0]); k++) { 720 if ( combinations[best].uchChar == combinations[k].uchChar 721 && combinations[best].uchVirtualKey == combinations[k].uchVirtualKey) { 722 const KeyModifierMask mask = convertTCFToKeyModiferMask(k); 723 // drop L/R mixes. 724 if (mask == bestMask) { 725 combinations[k].uchChar = combinations[k].uchVirtualKey = 0; 726 } 727 } 728 } 729 } 730 731 // 3. Add the remainders. 732 for (unsigned j = 0; j < sizeof(combinations) / sizeof(combinations[0]); j++) { 733 if (combinations[j].uchChar || combinations[j].uchVirtualKey) { 734 USHORT usChar = combinations[j].uchChar; 735 USHORT usVirtualKey = combinations[j].uchVirtualKey; 736 737 // update the changing item members 738 item.m_required = convertTCFToKeyModiferMask(j); 739 if (usVirtualKey) { 740 switch (usVirtualKey) { 741 case VK_BACKTAB: 742 item.m_required |= KeyModifierShift; 743 item.m_sensitive |= KeyModifierShift; 744 usChar = 0; // this one is translated incorrectly 745 break; 746 } 747 item.m_id = getKeyID(usVirtualKey, i, numpad, usChar); 748 } else { 749 item.m_id = usChar; /// @todo translate to unicode! 750 } 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 addKeyEntry(keyMap, item); 760 } 761 } 762 763 // 4. ASCII Control Character variants. (ARG! this doesn't work, fakeMsg hacks it.) 764 if (isASCIIControlChar(usChar)) { 765 /* add key */ 766 item.m_id = usChar - (usChar >= 'a' ? 0x60 : 0x40); 767 item.m_required = KeyModifierControl; 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 addKeyEntry(keyMap, item); 776 item.m_id = usChar; 777 addKeyEntry(keyMap, item); 778 } 779 } 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 545 819 } 546 820 … … 557 831 switch (keystroke.m_type) { 558 832 case Keystroke::kButton: { 559 LOG((CLOG_DEBUG1 " %03x (%08 x) %s%s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client,833 LOG((CLOG_DEBUG1 " %03x (%08x) %s%s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, 560 834 keystroke.m_data.m_button.m_press ? "down" : "up", keystroke.m_data.m_button.m_repeat ? " repeate" : "")); 561 835 KeyButton button = keystroke.m_data.m_button.m_button; … … 569 843 570 844 // unpack the m_client packet. 571 USHORT virtualKey = 0;//keystroke.m_data.m_button.m_client & 0xff; 572 UCHAR scanCode = (keystroke.m_data.m_button.m_client >> 8) & 0xff; 573 USHORT pmChar = 0;//(keystroke.m_data.m_button.m_client >> 16) & 0xff; 574 bool fKC_DEADKEY = (keystroke.m_data.m_button.m_client >> 30) & 1; 575 bool fKC_COMPOSITE = (keystroke.m_data.m_button.m_client >> 31) & 1; 576 845 ClientData data; 846 data.u = keystroke.m_data.m_button.m_client; 847 848 // 577 849 // synthesize message 850 851 852 853 854 855 856 857 858 859 860 861 862 863 578 864 HAB hab = CPMUtil::getHAB();/// @todo fix this 579 865 QMSG qmsg; 580 866 qmsg.hwnd = NULLHANDLE; 581 qmsg.msg = WM_ CHAR;867 qmsg.msg = WM_CHAR; 582 868 qmsg.ptl.x = 0; 583 869 qmsg.ptl.y = 0; … … 585 871 qmsg.reserved = 0; 586 872 587 // mp2 588 if (!keystroke.m_data.m_button.m_press) { 589 pmChar |= 0x0e00; /// @todo figure out what's going on here... 873 // 874 // calc the key code flags. 875 // PM deals with: KC_TOGGLE, KC_VIRTUALKEY, KC_CHAR, (WM_CHAR: also KC_CTRL, KC_ALT, KC_SHIFT). 876 // 877 USHORT fKC = 0; 878 if (data.s.scan) 879 fKC |= KC_SCANCODE; 880 if (!keystroke.m_data.m_button.m_press) 881 fKC |= KC_KEYUP; 882 /// @todo check that PM does KC_INVALIDCOMP 883 if (data.s.fDeadKey) 884 fKC |= KC_DEADKEY; 885 if (data.s.fComposite) 886 fKC |= KC_COMPOSITE; 887 if (!keystroke.m_data.m_button.m_press && m_lastButton == data.s.scan) 888 fKC |= KC_LONEKEY; 889 890 // we need these for calcing fKDD, so just put them in even if PM can do it for us. 891 KeyModifierMask modifierMask = this->getActiveModifiers(); 892 if (modifierMask & KeyModifierShift) 893 fKC |= KC_SHIFT; 894 if (modifierMask & KeyModifierControl) 895 fKC |= KC_CTRL; 896 if (modifierMask & KeyModifierAlt) 897 fKC |= KC_ALT; 898 899 // 900 // Calc the keyboard device driver flags. 901 // 902 USHORT fKDD; 903 // the action 904 if (data.s.fShiftKey) 905 fKDD = KDD_SHIFTKEY; 906 /** @todo Determin the KDD_ACTIONMASK value. 907 KDD_PREFIXKEY 908 KDD_PAUSEKEY 909 KDD_PSEUDOPAUSE 910 KDD_WAKEUPKEY 911 KDD_BREAKKEY 912 KDD_PSEUDOBREAK 913 KDD_PRTECHOKEY 914 KDD_PSEUDOPRECH */ 915 else 916 fKDD = KDD_PUTINKIB; 917 #if 0 918 if (fKC & KC_LONEKEY) fKDD |= KDD_KC_LONEKEY; 919 if (fKC & KC_PREVDOWN) fKDD |= KDD_KC_PREVDOWN; 920 if (fKC & KC_KEYUP) fKDD |= KDD_KC_KEYUP | KDD_BREAK; 921 if (fKC & KC_ALT) fKDD |= KDD_KC_ALT; 922 if (fKC & KC_CTRL) fKDD |= KDD_KC_CTRL; 923 if (fKC & KC_SHIFT) fKDD |= KDD_KC_SHIFT; 924 #else 925 if (fKC & KC_KEYUP) fKDD |= KDD_BREAK; 926 #endif 927 if (data.s.fSecondary) fKDD |= KDD_SECONDARY; 928 if (data.s.fExtendedKey) fKDD |= KDD_EXTENDEDKEY; 929 930 // 931 // Adjust char for ASCII control keys. (Ctrl+C and stuff) 932 // 933 if ( (fKC & KC_CTRL) 934 && isASCIIControlChar(data.s.xlatChar)) { 935 data.s.xlatChar -= (data.s.xlatChar >= 'a' ? 0x60 : 0x40); 590 936 } 591 qmsg.mp2 = MPFROM2SHORT(pmChar, virtualKey); 592 593 // mp1 594 USHORT fFlags = 0; 595 if (!keystroke.m_data.m_button.m_press) { 596 fFlags |= KC_KEYUP; 597 /// @todo KC_LONEKEY and KC_TOGGLE, or will PM take care of that? 937 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_INFO "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 } 598 965 } 599 /// @todo check that PM does KC_CTRL, KC_ALT and KC_SHIFT. 600 /// @todo check that PM does KC_INVALIDCOMP 601 if (fKC_DEADKEY) fFlags |= KC_DEADKEY; 602 if (fKC_COMPOSITE) fFlags |= KC_COMPOSITE; 603 // if (virtualKey) fFlags |= KC_VIRTUALKEY; 604 // if (keystroke.m_data.m_button.m_press && pmChar) 605 // fFlags |= KC_CHAR; 606 if (scanCode) fFlags |= KC_SCANCODE; 607 if (!keystroke.m_data.m_button.m_press && m_lastButton == scanCode) 608 fFlags |= KC_LONEKEY; 609 // PM does: KC_TOGGLE, KC_CTRL, KC_ALT, KC_SHIFT. more? 610 qmsg.mp1 = MPFROMSH2CH(fFlags, 1, scanCode); /** @todo translate the scan code back to its untranslated form. */ 611 612 // finaly inject it. 966 967 // 968 // Inject the (last) message. 969 // 970 qmsg.mp1 = MPFROMSH2CH(fKC, 1, data.s.scan); 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 ", 973 SHORT1FROMMP(qmsg.mp1), CHAR3FROMMP(qmsg.mp1), CHAR4FROMMP(qmsg.mp1), CHAR1FROMMP(qmsg.mp2), 974 isprint(CHAR1FROMMP(qmsg.mp2)) ? CHAR1FROMMP(qmsg.mp2) : '.', CHAR2FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2))); 613 975 const char *pszError = m_fakeMsg(hab, &qmsg); 614 976 if (pszError) { … … 618 980 // remember the previous key for KC_LONEKEY. 619 981 if (keystroke.m_data.m_button.m_press && !keystroke.m_data.m_button.m_repeat) 620 m_lastButton = scanCode;982 m_lastButton = ; 621 983 break; 622 984 } … … 654 1016 655 1017 KeyID 656 CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button )1018 CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button) 657 1019 { 658 1020 LOG((CLOG_DEBUG "getKeyID:")); 659 // if ((button & 0x100u) != 0) { 660 // virtualKey += 0x100u; 661 // } 662 // return s_virtualKey[virtualKey]; 663 return virtualKey < sizeof(s_virtualKey) / sizeof(s_virtualKey[0]) 664 ? s_virtualKey[virtualKey] 665 : kKeyNone; 1021 if (virtualKey < sizeof(s_virtualKey) / sizeof(s_virtualKey[0])) { 1022 1023 // 1024 // Numpad kludge. 1025 // 1026 if (numpad && s_virtualKey[virtualKey].numpad) { 1027 switch (usChar) { 1028 case '=': return kKeyKP_Equal; 1029 case '*': return kKeyKP_Multiply; 1030 case '+': return kKeyKP_Add; 1031 //case ',': 1032 //case '.': return kKeyKP_Separator ? kKeyKP_Decimal; 1033 case '-': return kKeyKP_Subtract; 1034 case '/': return kKeyKP_Divide; 1035 case '0': return kKeyKP_0; 1036 case '1': return kKeyKP_1; 1037 case '2': return kKeyKP_2; 1038 case '3': return kKeyKP_3; 1039 case '4': return kKeyKP_4; 1040 case '5': return kKeyKP_5; 1041 case '6': return kKeyKP_6; 1042 case '7': return kKeyKP_7; 1043 case '8': return kKeyKP_8; 1044 case '9': return kKeyKP_9; 1045 case ' ': return kKeyKP_Space; 1046 } 1047 switch (s_virtualKey[virtualKey].key) { 1048 case kKeyHome: return kKeyKP_Home; 1049 case kKeyLeft: return kKeyKP_Left; 1050 case kKeyUp: return kKeyKP_Up; 1051 case kKeyRight: return kKeyKP_Right; 1052 case kKeyDown: return kKeyKP_Down; 1053 case kKeyPageUp: return kKeyKP_PageUp; 1054 case kKeyPageDown: return kKeyKP_PageDown; 1055 case kKeyEnd: return kKeyKP_End; 1056 case kKeyBegin: return kKeyKP_Begin; 1057 case kKeyInsert: return kKeyKP_Insert; 1058 case kKeyDelete: return kKeyKP_Delete; 1059 } 1060 } else { 1061 // 1062 // Left/right shift and control kludge. 1063 // 1064 switch (virtualKey) { 1065 case VK_CTRL: 1066 if (m_virtualKeyToButton[VK_CTRL] != button) { 1067 return kKeyControl_R; 1068 } 1069 break; 1070 case VK_SHIFT: 1071 if (m_virtualKeyToButton[VK_SHIFT] != button) { 1072 return kKeyShift_R; 1073 } 1074 break; 1075 } 1076 } 1077 return s_virtualKey[virtualKey].key; 1078 } 1079 return kKeyNone; 666 1080 } 667 1081 … … 700 1114 } 701 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 702 1137 void 703 1138 CPMKeyState::addKeyEntry(CKeyMap& keyMap, CKeyMap::KeyItem& item) 704 1139 { 705 LOG((CLOG_DEBUG "addKeyEntry:")); 706 keyMap.addKeyEntry(item); 1140 ClientData data; data.u = item.m_client; assert(sizeof(data.u) == sizeof(data)); 1141 LOG((CLOG_DEBUG 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", 1143 item.m_button, convertKeyModiferMaskToTCF(item.m_required), 1144 item.m_required & KeyModifierShift ? 'S' : '-', 1145 item.m_required & KeyModifierControl ? 'C' : '-', 1146 item.m_required & KeyModifierAlt ? 'A' : '-', 1147 item.m_required & KeyModifierAltGr ? 'R' : '-', 1148 item.m_required & KeyModifierCapsLock ? 'U' : '-', 1149 item.m_required & KeyModifierNumLock ? 'N' : '-', 1150 item.m_sensitive & KeyModifierShift ? 'S' : '-', 1151 item.m_sensitive & KeyModifierControl ? 'C' : '-', 1152 item.m_sensitive & KeyModifierAlt ? 'A' : '-', 1153 item.m_sensitive & KeyModifierAltGr ? 'R' : '-', 1154 item.m_sensitive & KeyModifierCapsLock ? 'U' : '-', 1155 item.m_sensitive & KeyModifierNumLock ? 'N' : '-', 1156 item.m_generates, 1157 item.m_id, item.m_id < 128 && isprint(item.m_id) ? item.m_id : '.', 1158 data.s.xlatChar, data.s.xlatChar < 128 && isprint(data.s.xlatChar) ? data.s.xlatChar : '.', 1159 data.s.scan, data.s.xlatScan, 1160 getKeyName(item.m_id), 1161 data.s.fExtendedKey ? " extendedkey" : "", 1162 data.s.fShiftKey ? " shiftkey" : "", 1163 data.s.fDeadKey ? " deadkey" : "", 1164 data.s.fComposite ? " composite" : "", 1165 item.m_lock ? " lock" : "", 1166 item.m_dead ? " dead" : "" 1167 )); 1168 if (data.s.scan2 || data.s.xlatScan2) { 1169 LOG((CLOG_DEBUG 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_DEBUG "!not accepted!")); 1177 } 707 1178 if (item.m_group == 0) { 708 1179 m_keyToVKMap[item.m_id] = item.m_client;
Note:
See TracChangeset
for help on using the changeset viewer.
