Changeset 2768 for trunk/synergy/lib/platform
- Timestamp:
- Aug 20, 2006, 8:11:44 AM (19 years ago)
- Location:
- trunk/synergy/lib/platform
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/synergy/lib/platform/CMSWindowsKeyState.cpp
r2753 r2768 1189 1189 switch (keystroke.m_type) { 1190 1190 case Keystroke::kButton: { 1191 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"));1191 LOG((CLOG_DEBUG1 " %03x (%08x) %s", keystroke.m_data.m_button.m_button, (UInt32)keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up")); 1192 1192 KeyButton button = keystroke.m_data.m_button.m_button; 1193 1193 … … 1200 1200 1201 1201 // get the virtual key for the button 1202 UINT vk = keystroke.m_data.m_button.m_client;1202 UINT vk = (UINT)keystroke.m_data.m_button.m_client; 1203 1203 1204 1204 // special handling of VK_SNAPSHOT -
trunk/synergy/lib/platform/COSXKeyState.cpp
r2749 r2768 2 2 * synergy -- mouse and keyboard sharing utility 3 3 * Copyright (C) 2004 Chris Schoeneman 4 * 4 * 5 5 * This package is free software; you can redistribute it and/or 6 6 * modify it under the terms of the GNU General Public License 7 7 * found in the file COPYING that should have accompanied this file. 8 * 8 * 9 9 * This package is distributed in the hope that it will be useful, 10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 145 145 } 146 146 147 KeyButton 147 KeyButton 148 148 COSXKeyState::mapKeyFromEvent(CKeyIDs& ids, 149 149 KeyModifierMask* maskOut, EventRef event) const … … 366 366 switch (keystroke.m_type) { 367 367 case Keystroke::kButton: 368 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"));368 LOG((CLOG_DEBUG1 " %03x (%08x) %s", keystroke.m_data.m_button.m_button, (UInt32)keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up")); 369 369 370 370 // let system figure out character for us … … 552 552 } 553 553 macVirtualKey = mapKeyButtonToVirtualKey(button); 554 554 555 555 // calculate modifier mask 556 556 macModifierMask = 0; … … 570 570 macModifierMask |= alphaLock; 571 571 } 572 572 573 573 return true; 574 574 } 575 575 576 576 void 577 577 COSXKeyState::handleModifierKeys(void* target, -
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::VirtualKey CPMKeyState::s_virtualKey[0x42] = 31 { 32 { /* 0x000 */ kKeyNone, 0, 0, 0 }, // reserved 33 { /* 0x001 */ kKeyNone, 0, 0, 0 }, // VK_BUTTON1 34 { /* 0x002 */ kKeyNone, 0, 0, 0 }, // VK_BUTTON2 35 { /* 0x003 */ kKeyNone, 0, 0, 0 }, // VK_BUTTON3 36 { /* 0x004 */ kKeyBreak, 0, 0, 0 }, // VK_BREAK 37 { /* 0x005 */ kKeyBackSpace, 8, 0, 0 }, // VK_BACKSPACE 38 { /* 0x006 */ kKeyTab, 9, 0, 0 }, // VK_TAB 39 { /* 0x007 */ kKeyLeftTab, 9, 0, 1 }, // VK_BACKTAB 40 { /* 0x008 */ kKeyReturn, 0x0d, 0, 0 }, // VK_NEWLINE 41 { /* 0x009 */ kKeyShift_L, 0, 0, 0 }, // VK_SHIFT 42 { /* 0x00a */ kKeyControl_L, 0, 0, 0 }, // VK_CTRL 43 { /* 0x00b */ kKeyAlt_L, 0, 0, 0 }, // VK_ALT 44 { /* 0x00c */ kKeyAltGr, 0, 0, 0 }, // VK_ALTGRAF 45 { /* 0x00d */ kKeyPause, 0, 0, 0 }, // VK_PAUSE 46 { /* 0x00e */ kKeyCapsLock, 0, 0, 0 }, // VK_CAPSLOCK 47 { /* 0x00f */ kKeyEscape, 0x1b, 0, 0 }, // VK_ESC 48 { /* 0x010 */ ' ', 0x20, 0, 0 }, // VK_SPACE 49 { /* 0x011 */ kKeyPageUp, 0xe0, 1, -1 }, // VK_PAGEUP 50 { /* 0x012 */ kKeyPageDown, 0xe0, 1, -1 }, // VK_PAGEDOWN 51 { /* 0x013 */ kKeyEnd, 0xe0, 1, -1 }, // VK_END 52 { /* 0x014 */ kKeyHome, 0xe0, 1, -1 }, // VK_HOME 53 { /* 0x015 */ kKeyLeft, 0xe0, 1, -1 }, // VK_LEFT 54 { /* 0x016 */ kKeyUp, 0xe0, 1, -1 }, // VK_UP 55 { /* 0x017 */ kKeyRight, 0xe0, 1, -1 }, // VK_RIGHT 56 { /* 0x018 */ kKeyDown, 0xe0, 1, -1 }, // VK_DOWN 57 { /* 0x019 */ kKeyNone, 0xe0, 0, 0 }, // VK_PRINTSCRN 58 { /* 0x01a */ kKeyInsert, 0xe0, 1, 1 }, // VK_INSERT 59 { /* 0x01b */ kKeyDelete, 0xe0, 1, 1 }, // VK_DELETE 60 { /* 0x01c */ kKeyScrollLock, 0, 0, 0 }, // VK_SCRLLOCK 61 { /* 0x01d */ kKeyNumLock, 0, 0, 0 }, // VK_NUMLOCK 62 { /* 0x01e */ kKeyKP_Enter, 0x0d, 1, 1 }, // VK_ENTER 63 { /* 0x01f */ kKeySysReq, 0, 0, 0 }, // VK_SYSRQ 64 { /* 0x020 */ kKeyF1, 0, 0, 1 }, // VK_F1 65 { /* 0x021 */ kKeyF2, 0, 0, 1 }, // VK_F2 66 { /* 0x022 */ kKeyF3, 0, 0, 1 }, // VK_F3 67 { /* 0x023 */ kKeyF4, 0, 0, 1 }, // VK_F4 68 { /* 0x024 */ kKeyF5, 0, 0, 1 }, // VK_F5 69 { /* 0x025 */ kKeyF6, 0, 0, 1 }, // VK_F6 70 { /* 0x026 */ kKeyF7, 0, 0, 1 }, // VK_F7 71 { /* 0x027 */ kKeyF8, 0, 0, 1 }, // VK_F8 72 { /* 0x028 */ kKeyF9, 0, 0, 1 }, // VK_F9 73 { /* 0x029 */ kKeyF10, 0, 0, 1 }, // VK_F10 74 { /* 0x02a */ kKeyF11, 0, 0, 1 }, // VK_F11 75 { /* 0x02b */ kKeyF12, 0, 0, 1 }, // VK_F12 76 { /* 0x02c */ kKeyF13, 0, 0, 1 }, // VK_F13 77 { /* 0x02d */ kKeyF14, 0, 0, 1 }, // VK_F14 78 { /* 0x02e */ kKeyF15, 0, 0, 1 }, // VK_F15 79 { /* 0x02f */ kKeyF16, 0, 0, 1 }, // VK_F16 80 { /* 0x030 */ kKeyF17, 0, 0, 1 }, // VK_F17 81 { /* 0x031 */ kKeyF18, 0, 0, 1 }, // VK_F18 82 { /* 0x032 */ kKeyF19, 0, 0, 1 }, // VK_F19 83 { /* 0x033 */ kKeyF20, 0, 0, 1 }, // VK_F20 84 { /* 0x034 */ kKeyF21, 0, 0, 1 }, // VK_F21 85 { /* 0x035 */ kKeyF22, 0, 0, 1 }, // VK_F22 86 { /* 0x036 */ kKeyF23, 0, 0, 1 }, // VK_F23 87 { /* 0x037 */ kKeyF24, 0, 0, 1 }, // VK_F24 88 { /* 0x038 */ kKeyNone, 0, 0, 0 }, // VK_ENDDRAG 89 { /* 0x039 */ kKeyNone, 0, 0, 0 }, // VK_CLEAR 90 { /* 0x03a */ kKeyNone, 0, 0, 0 }, // VK_EREOF 91 { /* 0x03b */ kKeyNone, 0, 0, 0 }, // VK_PA1 92 { /* 0x03c */ kKeyNone, 0, 0, 0 }, // VK_ATTN 93 { /* 0x03d */ kKeyNone, 0, 0, 0 }, // VK_CRSEL 94 { /* 0x03e */ kKeyNone, 0, 0, 0 }, // VK_EXSEL 95 { /* 0x03f */ kKeyNone, 0, 0, 0 }, // VK_COPY 96 { /* 0x040 */ kKeyNone, 0, 0, 0 }, // VK_BLK1 97 { /* 0x041 */ kKeyNone, 0, 0, 0 }, // VK_BLK2 98 98 }; 99 99 … … 354 354 } 355 355 356 static USHORT 357 convertKeyModiferMaskToTCF(const KeyModifierMask mask) 358 { 359 USHORT fShiftState = 0; 360 if (mask & KeyModifierShift) fShiftState |= TCF_SHIFT; 361 if (mask & KeyModifierControl) fShiftState |= TCF_CONTROL; 362 if (mask & KeyModifierAlt) fShiftState |= TCF_ALT; 363 if (mask & KeyModifierAltGr) fShiftState |= TCF_ALTGR; 364 if (mask & KeyModifierCapsLock) fShiftState |= TCF_CAPSLOCK; 365 if (mask & KeyModifierNumLock) fShiftState |= TCF_NUMLOCK; 366 return fShiftState; 367 } 368 369 static KeyModifierMask 370 convertTCFToKeyModiferMask(const USHORT fShiftState) 371 { 372 KeyModifierMask mask = 0; 373 if (fShiftState & TCF_SHIFT) mask |= KeyModifierShift; 374 if (fShiftState & TCF_CONTROL) mask |= KeyModifierControl; 375 if (fShiftState & TCF_ALT) mask |= KeyModifierAlt; 376 if (fShiftState & TCF_ALTGR) mask |= KeyModifierAltGr; 377 if (fShiftState & TCF_CAPSLOCK) mask |= KeyModifierCapsLock; 378 if (fShiftState & TCF_NUMLOCK) mask |= KeyModifierNumLock; 379 return mask; 380 } 381 382 static bool 383 isASCIIControlChar(const USHORT usChar) 384 { 385 switch (usChar) { 386 /* Skip the ones with virtual keys. */ 387 case 0x08 + 0x40: case 0x08 + 0x60: // backspace 388 case 0x09 + 0x40: case 0x09 + 0x60: // horizontal tab 389 case 0x1b + 0x40: case 0x1b + 0x60: // escape 390 case 0x0d + 0x40: case 0x0d + 0x60: // return 391 return false; 392 default: 393 return (usChar >= 'A' && usChar <= '_') 394 || (usChar >= 'a' && usChar <= 'z'); 395 } 396 } 397 398 void 399 CPMKeyState::convertScancodes(ClientData *pData) 400 { 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 */ 407 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 } 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 /// @todo the stuff down to the button loop isn't really done yet. 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 || usVirtualKey) { 602 // initialize the item 603 item.m_id = getKeyID(m_buttonToVK[i], i, false, usChar); 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 (%08llx) %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 // There are two options at this point, WM_CHAR or WM_VIOCHAR. It seems 851 // like WM_VIOCHAR is the better choice since that's the form in which 852 // keyboard events normally arrive in the system queue. 853 // 854 // WM_VIOCHAR: 855 // mp1.s1: KC_ flags. 856 // mp1.c3: repeat 857 // mp1.c4: scancode 858 // mp2.c1: translated char 859 // mp2.c2: translated scancode 860 // mp2.s2: KDD_ flags. 861 // 862 863 // the standard bits. 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_VIOCHAR; 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 = data.s.scan; 621 983 break; 622 984 } … … 654 1016 655 1017 KeyID 656 CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button )1018 CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button, bool numpad, USHORT usChar) 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 static const char * 1117 getKeyName(KeyID key) 1118 { 1119 const KeyNameMapEntry *entry = &kKeyNameMap[0]; 1120 while (entry->m_id != kKeyNone) { 1121 if (entry->m_id == key) { 1122 return entry->m_name; 1123 } 1124 entry++; 1125 } 1126 /* ASCII? */ 1127 static char s_buf[2][2]; 1128 static char s_idxBuf; 1129 if (key >= ' ' && key <= 'z') { 1130 char *buf = &s_buf[s_idxBuf = (s_idxBuf + 1) % 2][0]; 1131 *buf = key; 1132 return buf; 1133 } 1134 return ""; 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; -
trunk/synergy/lib/platform/CPMKeyState.h
r2765 r2768 113 113 no such key. 114 114 */ 115 static KeyID getKeyID(ULONG virtualKey, KeyButton button);115 KeyID getKeyID(ULONG virtualKey, KeyButton button, bool fNumPadKey, USHORT usChar); 116 116 117 117 //@} … … 142 142 143 143 private: 144 typedef union { 145 /** the 64-bit data view. */ 146 UInt64 u; 147 /** the struct view. */ 148 struct 149 { 150 /** The pm scan code. */ 151 unsigned xlatScan : 8; 152 /** The char. */ 153 unsigned xlatChar: 8; 154 /** The raw scan code. */ 155 unsigned scan : 7; 156 /** KDD_EXTENDEDKEY. */ 157 unsigned fExtendedKey : 1; 158 /** The pm scan code of the 2nd message. */ 159 unsigned xlatScan2 : 8; 160 /** The char of the 2nd message. */ 161 unsigned xlatChar2: 8; 162 /** The raw scan code of the 2nd message. */ 163 unsigned scan2 : 7; 164 /** KDD_SECONDARY. */ 165 unsigned fSecondary : 1; 166 /** The virtual key. */ 167 unsigned virtualKey : 7; 168 /** KC_DEADKEY. */ 169 unsigned fDeadKey : 1; 170 /** KC_COMPOSITE. */ 171 unsigned fComposite : 1; 172 /** shift key. */ 173 unsigned fShiftKey : 1; 174 /** Indicates that the key requires the xlscan=2a KDD_SECONADARY+KDD_UNDEFINED+KDD_UNDEFINED 175 * key if numlock is effective. */ 176 unsigned fNeedNumUnlockKey : 1; 177 /** Bits we haven't used yet. */ 178 unsigned fReserved : 4; 179 } s; 180 } ClientData; 181 182 void convertScancodes(ClientData *pData); 144 183 KeyID getIDForKey(CKeyMap::KeyItem& item, 145 184 KeyButton button, ULONG virtualKey, … … 160 199 KeyToVKMap m_keyToVKMap; 161 200 201 // scan code conversions. 202 UInt8 m_pmScanToOemScan[256]; 203 UInt8 m_pmScanToOemScanExt[256]; 204 UInt8 m_oemScanToPmScan[128]; 205 UInt8 m_oemScanToPmScanExt[128]; 206 162 207 // function which can inject fake WM_CHAR messages. 163 208 FakeMsgFunc m_fakeMsg; … … 180 225 KeyModifierMask m_originalSavedModifiers; 181 226 182 static const KeyID s_virtualKey[0x42]; 227 typedef struct { 228 KeyID key; 229 unsigned char ch; 230 bool numpad; 231 char extended; 232 } VirtualKey; 233 static const VirtualKey s_virtualKey[0x42]; 183 234 }; 184 235 -
trunk/synergy/lib/platform/CPMSynergyHook.cpp
r2764 r2768 22 22 #include <InnoTekLIBC/FastInfoBlocks.h> 23 23 #else 24 unsigned long fibGetMsCount(void 24 unsigned long fibGetMsCount(void) 25 25 { 26 26 ULONG ul = 0; … … 50 50 } 51 51 52 #endif 52 #endif 53 53 54 54 // … … 542 542 * @param hab The hab of the current thread. 543 543 * @param pqmsg Where to put the message. 544 * @param fSkip Skip message flag. 544 * @param fSkip Skip message flag. 545 545 * If TRUE we should just skip a message (pqmsg is NULL). If no futher 546 546 * messages are queued, we must release the hook. … … 567 567 } else { 568 568 *pqmsg = g_qmsg; 569 } 570 569 if (pqmsg->msg == WM_VIOCHAR) { 570 /* mp1.s1: KC_ flags. 571 * mp1.c3: repeat 572 * mp1.c4: scancode 573 * mp2.c1: translated char 574 * mp2.c2: translated scancode 575 * mp2.s2: KDD_ flags. 576 */ 577 KbdPacket[0].monFlags = 0; // no monitor flag 578 KbdPacket[0].scancode = CHAR4FROMMP(pqmsg->mp1); 579 KbdPacket[0].xlatedchar = CHAR1FROMMP(pqmsg->mp2); 580 KbdPacket[0].xlatedscan = CHAR2FROMMP(pqmsg->mp2); 581 KbdPacket[0].time = pqmsg->time; 582 KbdPacket[0].ddFlags = SHORT2FROMMP(pqmsg->mp2); 583 /** @todo extended stuff, keypad, workarounds. see pmvnc. */ 584 } 585 } 586 587 /* 588 * We're not recording, so no chance of a feedback loop here. 589 * This doesn't seem to work, bah! 590 */ 591 if (pfNoRecord) { 592 *pfNoRecord = FALSE; 593 } 571 594 return TRUE; 572 595 } … … 587 610 assert(g_fSynergyInitialized); 588 611 if (g_fSynergyInitialized) { 589 /* 612 /* 590 613 * Reset the event semaphore and queue the message for MsgInputHook. 591 614 */ … … 609 632 610 633 /* 611 * It took a bit longer than expected. We'll wait for some 2-3 634 * It took a bit longer than expected. We'll wait for some 2-3 612 635 * seconds before we give up. This might be a bit paranoid, but 613 636 * I'd rather drop a message than locking up PM. … … 623 646 if (rc != ERROR_TIMEOUT && rc != ERROR_SEM_TIMEOUT && rc != ERROR_INTERRUPT) { 624 647 break; 625 } 648 } 626 649 if (fibGetMsCount() - ulStart > 2500) { 627 650 break; … … 630 653 } 631 654 632 /* 633 * Since we probably didn't manage to inject the message, we should 634 * release the hook to make sure we're not overwriting g_qmsg while 655 /* 656 * Since we probably didn't manage to inject the message, we should 657 * release the hook to make sure we're not overwriting g_qmsg while 635 658 * some other thread is reading it from MsgInputHook. 636 659 */ … … 639 662 pszRet = g_pszErrorMsg; 640 663 return pszRet ? pszRet : "timed out"; 641 } 664 } 642 665 pszRet = "WinSetHook failed"; 643 666 } else { -
trunk/synergy/lib/platform/CPMSynergyHook.def
r2763 r2768 2 2 DATA SHARED 3 3 4 IMPORTS 5 _KbdPacket = PMWIN.174 ; fix KbdPacket in win.imp and make it data! 6 -
trunk/synergy/lib/platform/CPMSynergyHook.h
r2763 r2768 87 87 CSYNERGYHOOK_API const char * fakeMsg(HAB hab, const QMSG *pQmsg); 88 88 89 90 91 // 92 // Various OS/2 stuff from the DDK. 93 // 94 95 /* 96 * video/rel/.../pmwinp.mac and pmwinx.h in the ddk. 97 */ 98 typedef struct _KBDEVENT { /* kevt */ 99 BYTE monFlags; /* Open, Close and Flush monitor flags */ 100 BYTE scancode; /* Original scan code (actually high byte of 101 monitor flags */ 102 BYTE xlatedchar; /* Output of interrupt level character translation 103 table */ 104 105 BYTE xlatedscan; /* Translated scan code. Different only for 106 the enhanced keyboard */ 107 108 USHORT shiftDBCS; /* DBCS shift state and status */ 109 USHORT shiftstate; /* Current state of shift keys */ 110 ULONG time; /* millisecond counter time stamp */ 111 USHORT ddFlags; /* Keyboard device driver flags */ 112 } KBDEVENT; 113 typedef KBDEVENT *PKBDEVENT; 114 // guess MON_* are for the monFlags field. 115 #define MON_OPEN EQU 0001H 116 #define MON_CLOSE EQU 0002H 117 #define MON_FLUSH EQU 0004H 118 // guess KSS_* is for the shiftstate field. 119 #define KSS_SYSREQ EQU 8000H 120 #define KSS_CAPSLOCK EQU 4000H 121 #define KSS_NUMLOCK EQU 2000H 122 #define KSS_SCROLLLOCK EQU 1000H 123 #define KSS_RIGHTALT EQU 0800H 124 #define KSS_RIGHTCTRL EQU 0400H 125 #define KSS_LEFTALT EQU 0200H 126 #define KSS_LEFTCTRL EQU 0100H 127 #define KSS_INSERTON EQU 0080H 128 #define KSS_CAPSLOCKON EQU 0040H 129 #define KSS_NUMLOCKON EQU 0020H 130 #define KSS_SCROLLLOCKON EQU 0010H 131 #define KSS_EITHERALT EQU 0008H 132 #define KSS_EITHERCTRL EQU 0004H 133 #define KSS_LEFTSHIFT EQU 0002H 134 #define KSS_RIGHTSHIFT EQU 0001H 135 #define KSS_EITHERSHIFT EQU 0003H 136 /* Valid values for ddFlags field */ 137 #define KDD_MONFLAG1 0x8000 // bird: conflicts with KDD_KC_LONEKEY - relevant for VIOCHAR? 138 #define KDD_MONFLAG2 0x4000 // bird: conflicts with KDD_KC_PREVDOWN - relevant for VIOCHAR? 139 #define KDD_RESERVED 0x3C00 140 #define KDD_ACCENTED 0x0200 141 #define KDD_MULTIMAKE 0x0100 142 #define KDD_SECONDARY 0x0080 143 #define KDD_BREAK 0x0040 144 #define KDD_EXTENDEDKEY 0x0020 145 #define KDD_ACTIONFIELD 0x001F 146 #define KDD_KC_LONEKEY 0x8000 147 #define KDD_KC_PREVDOWN 0x4000 148 #define KDD_KC_KEYUP 0x2000 149 #define KDD_KC_ALT 0x1000 150 #define KDD_KC_CTRL 0x0800 151 #define KDD_KC_SHIFT 0x0400 152 #define KDD_KC_FLAGS 0x0FC00 153 /* Valid values for KDD_ACTIONFIELD portion of ddFlags field */ 154 #define KDD_PUTINKIB 0x0000 155 #define KDD_ACK 0x0001 156 #define KDD_PREFIXKEY 0x0002 157 #define KDD_OVERRUN 0x0003 158 #define KDD_RESEND 0x0004 159 #define KDD_REBOOTKEY 0x0005 160 #define KDD_DUMPKEY 0x0006 161 #define KDD_SHIFTKEY 0x0007 162 #define KDD_PAUSEKEY 0x0008 163 #define KDD_PSEUDOPAUSE 0x0009 164 #define KDD_WAKEUPKEY 0x000A 165 #define KDD_BADACCENT 0x000B 166 #define KDD_HOTKEY 0x000C 167 #define KDD_ACCENTKEY 0x0010 168 #define KDD_BREAKKEY 0x0011 169 #define KDD_PSEUDOBREAK 0x0012 170 #define KDD_PRTSCKEY 0x0013 171 #define KDD_PRTECHOKEY 0x0014 172 #define KDD_PSEUDOPRECH 0x0015 173 #define KDD_STATUSCHG 0x0016 174 #define KDD_WRITTENKEY 0x0017 175 #define KDD_UNDEFINED 0x001F 176 177 /// PMWIN.174 178 // This needs to be used when pushing stuff to VIO programs. (pmvnc does anyway) 179 extern "C" KBDEVENT KbdPacket[2]; 180 89 181 #endif -
trunk/synergy/lib/platform/CPMUtil.h
r2765 r2768 42 42 43 43 }; 44 45 44 46 45 /** The WinTranlateChar2 operation. */ -
trunk/synergy/lib/platform/CXWindowsKeyState.cpp
r2749 r2768 2 2 * synergy -- mouse and keyboard sharing utility 3 3 * Copyright (C) 2003 Chris Schoeneman 4 * 4 * 5 5 * This package is free software; you can redistribute it and/or 6 6 * modify it under the terms of the GNU General Public License 7 7 * found in the file COPYING that should have accompanied this file. 8 * 8 * 9 9 * This package is distributed in the hope that it will be useful, 10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 206 206 switch (keystroke.m_type) { 207 207 case Keystroke::kButton: 208 LOG((CLOG_DEBUG1 " %03x (%08 x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));208 LOG((CLOG_DEBUG1 " %03x (%08llx) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up")); 209 209 if (keystroke.m_data.m_button.m_repeat) { 210 210 int c = keystroke.m_data.m_button.m_button; … … 301 301 tmpKeysyms[maxKeysyms * i + j] = NoSymbol; 302 302 } 303 } 303 } 304 304 } 305 305 XFree(allKeysyms);
Note:
See TracChangeset
for help on using the changeset viewer.