Changeset 2765
- Timestamp:
- Aug 14, 2006, 6:55:06 AM (19 years ago)
- Location:
- trunk/synergy/lib/platform
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/synergy/lib/platform/CMSWindowsKeyState.h
r2749 r2765 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 … … 186 186 CEventQueueTimer* m_fixTimer; 187 187 188 #if 0 188 189 // the groups (keyboard layouts) 189 190 GroupList m_groups; 190 191 GroupMap m_groupMap; 192 #endif 191 193 192 194 // the last button that we generated a key down event for. this -
trunk/synergy/lib/platform/CPMKeyState.cpp
r2763 r2765 19 19 #include "CLog.h" 20 20 #include "CStringUtil.h" 21 #include "CPMUtil.h" 21 22 #include "IEventQueue.h" 22 23 #include "TMethodEventJob.h" … … 111 112 }; 112 113 113 CPMKeyState::CPMKeyState(void* eventTarget ) :114 CPMKeyState::CPMKeyState(void* eventTarget, FakeMsgFunc fakeMsg) : 114 115 m_eventTarget(eventTarget), 116 m_fakeMsg(fakeMsg), 117 m_lastButton(0), 115 118 m_fixTimer(NULL), 116 119 m_lastDown(kKeyNone), … … 119 122 m_originalSavedModifiers(0) 120 123 { 121 124 LOG((CLOG_DEBUG "CPMKeyState:")); 122 125 } 123 126 124 127 CPMKeyState::~CPMKeyState() 125 128 { 129 LOG((CLOG_DEBUG "~CPMKeyState:")); 126 130 disable(); 127 131 } … … 130 134 CPMKeyState::disable() 131 135 { 136 LOG((CLOG_DEBUG "disable:")); 132 137 if (m_fixTimer != NULL) { 133 138 EVENTQUEUE->removeHandler(CEvent::kTimer, m_fixTimer); … … 141 146 CPMKeyState::virtualKeyToButton(ULONG virtualKey) const 142 147 { 148 LOG((CLOG_DEBUG "virtualKeyToButton:")); 143 149 return m_virtualKeyToButton[virtualKey & 0xffu]; 144 150 } … … 147 153 CPMKeyState::testAutoRepeat(bool press, bool isRepeat, KeyButton button) 148 154 { 155 LOG((CLOG_DEBUG "testAutoRepeat:")); 149 156 if (!isRepeat) 150 157 isRepeat = press && button == m_lastDown && button != kKeyNone; … … 156 163 CPMKeyState::saveModifiers() 157 164 { 165 LOG((CLOG_DEBUG "saveModifiers:")); 158 166 m_savedModifiers = getActiveModifiers(); 159 167 m_originalSavedModifiers = m_savedModifiers; … … 163 171 CPMKeyState::useSavedModifiers(bool enable) 164 172 { 173 LOG((CLOG_DEBUG "useSavedModifiers:")); 165 174 if (enable != m_useSavedModifiers) { 166 175 m_useSavedModifiers = enable; … … 176 185 CPMKeyState::mapKeyFromEvent(USHORT fsFlags, UCHAR ucRepeat, UCHAR ucScanCode, USHORT usch, USHORT usvk, KeyModifierMask* maskOut) const 177 186 { 187 LOG((CLOG_DEBUG "mapKeyFromEvent:")); 178 188 #if 0 /** @todo */ 179 189 static const KeyModifierMask s_controlAlt = KeyModifierControl | KeyModifierAlt; … … 231 241 CPMKeyState::mapKeyToVirtualKey(KeyID key) const 232 242 { 243 LOG((CLOG_DEBUG "mapKeyToVirtualKey:")); 233 244 if (key == kKeyNone) 234 245 return 0; … … 245 256 SInt32 count, KeyButton button) 246 257 { 258 LOG((CLOG_DEBUG "sendKeyEvent:")); 247 259 if (press || isAutoRepeat) { 248 260 // send key … … 266 278 CPMKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton button) 267 279 { 280 LOG((CLOG_DEBUG "fakeKeyDown: id=%#x mask=%#x button=%#x", id, mask, button)); 268 281 CKeyState::fakeKeyDown(id, mask, button); 269 282 } … … 272 285 CPMKeyState::fakeKeyRepeat(KeyID id, KeyModifierMask mask, SInt32 count, KeyButton button) 273 286 { 287 LOG((CLOG_DEBUG "fakeKeyRepeat: id=%#x mask=%#x count=%d button=%#x", id, mask, count, button)); 274 288 CKeyState::fakeKeyRepeat(id, mask, count, button); 275 289 } … … 278 292 CPMKeyState::fakeCtrlAltDel() 279 293 { 294 LOG((CLOG_DEBUG "fakeCtrlAltDel:")); 280 295 fakeKeyDown(kKeyDelete, KeyModifierControl | KeyModifierAlt, virtualKeyToButton(VK_DELETE)); 281 296 } … … 284 299 CPMKeyState::pollActiveModifiers() const 285 300 { 301 LOG((CLOG_DEBUG "pollActiveModifiers:")); 286 302 KeyModifierMask state = 0; 287 303 … … 307 323 CPMKeyState::pollActiveGroup() const 308 324 { 325 LOG((CLOG_DEBUG "pollActiveGroup:")); 309 326 #if 0 310 327 HKL hkl = GetKeyboardLayout(targetThread); … … 320 337 #else 321 338 return 0; 322 #endif 339 #endif 323 340 } 324 341 … … 326 343 CPMKeyState::pollPressedKeys(KeyButtonSet& pressedKeys) const 327 344 { 345 LOG((CLOG_DEBUG "pollPressedKeys:")); 328 346 BYTE keyState[256]; 329 347 if (WinSetKeyboardStateTable(HWND_DESKTOP, keyState, FALSE)) { … … 339 357 CPMKeyState::getKeyMap(CKeyMap& keyMap) 340 358 { 359 LOG((CLOG_DEBUG "getKeyMap:")); 341 360 #if 0 342 361 // update keyboard groups … … 349 368 } 350 369 HKL activeLayout = GetKeyboardLayout(0); 370 #endif 351 371 352 372 // clear table … … 355 375 356 376 CKeyMap::KeyItem item; 357 SInt32 numGroups = (SInt32)m_groups.size(); 358 for (SInt32 g = 0; g < numGroups; ++g) { 377 // SInt32 numGroups = (SInt32)m_groups.size(); 378 // for (SInt32 g = 0; g < numGroups; ++g) { 379 for (SInt32 g = 0; g < 1; ++g) { 359 380 item.m_group = g; 360 ActivateKeyboardLayout(m_groups[g], 0);381 // ActivateKeyboardLayout(m_groups[g], 0); 361 382 362 383 // clear tables 363 384 memset(m_buttonToVK, 0, sizeof(m_buttonToVK)); 364 memset(m_buttonToNumpadVK, 0, sizeof(m_buttonToNumpadVK));365 385 366 386 // map buttons (scancodes) to virtual keys 367 387 for (KeyButton i = 1; i < 256; ++i) { 368 ULONG vk = MapVirtualKey(i, 1); 369 if (vk == 0) { 370 // unmapped 371 continue; 372 } 373 374 // deal with certain virtual keys specially 375 switch (vk) { 376 case VK_SHIFT: 377 if (MapVirtualKey(VK_RSHIFT, 0) == i) { 378 vk = VK_RSHIFT; 379 } 380 else { 381 vk = VK_LSHIFT; 382 } 383 break; 384 385 case VK_CONTROL: 386 vk = VK_LCONTROL; 387 break; 388 389 case VK_MENU: 390 vk = VK_LMENU; 391 break; 392 393 case VK_NUMLOCK: 394 vk = VK_PAUSE; 395 break; 396 397 case VK_NUMPAD0: 398 case VK_NUMPAD1: 399 case VK_NUMPAD2: 400 case VK_NUMPAD3: 401 case VK_NUMPAD4: 402 case VK_NUMPAD5: 403 case VK_NUMPAD6: 404 case VK_NUMPAD7: 405 case VK_NUMPAD8: 406 case VK_NUMPAD9: 407 case VK_DECIMAL: 408 // numpad keys are saved in their own table 409 m_buttonToNumpadVK[i] = vk; 410 continue; 411 412 case VK_LWIN: 413 case VK_RWIN: 414 // add extended key only for these on 95 family 415 if (m_is95Family) { 416 m_buttonToVK[i | 0x100u] = vk; 417 continue; 418 } 419 break; 420 421 case VK_RETURN: 422 case VK_PRIOR: 423 case VK_NEXT: 424 case VK_END: 425 case VK_HOME: 426 case VK_LEFT: 427 case VK_UP: 428 case VK_RIGHT: 429 case VK_DOWN: 430 case VK_INSERT: 431 case VK_DELETE: 432 // also add extended key for these 433 m_buttonToVK[i | 0x100u] = vk; 434 break; 435 } 436 437 if (m_buttonToVK[i] == 0) { 438 m_buttonToVK[i] = vk; 388 USHORT usVirtualKey = i; 389 USHORT fShiftState = 0; 390 WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState); 391 if ( usVirtualKey != 0 392 && m_buttonToVK[i] == 0) { 393 m_buttonToVK[i] = usVirtualKey; 439 394 } 440 395 } … … 448 403 // skip virtual keys we don't want 449 404 switch (i) { 450 case VK_LBUTTON: 451 case VK_RBUTTON: 452 case VK_MBUTTON: 453 case VK_XBUTTON1: 454 case VK_XBUTTON2: 405 case VK_BUTTON1: 406 case VK_BUTTON2: 407 case VK_BUTTON3: 455 408 case VK_SHIFT: 456 case VK_C ONTROL:409 case VK_CTRL: 457 410 case VK_MENU: 458 411 continue; … … 460 413 461 414 // get the button 462 KeyButton button = static_cast<KeyButton>(MapVirtualKey(i, 0)); 463 if (button == 0) { 464 continue; 465 } 466 467 // deal with certain virtual keys specially 468 switch (i) { 469 case VK_NUMPAD0: 470 case VK_NUMPAD1: 471 case VK_NUMPAD2: 472 case VK_NUMPAD3: 473 case VK_NUMPAD4: 474 case VK_NUMPAD5: 475 case VK_NUMPAD6: 476 case VK_NUMPAD7: 477 case VK_NUMPAD8: 478 case VK_NUMPAD9: 479 case VK_DECIMAL: 480 m_buttonToNumpadVK[button] = i; 481 break; 482 483 default: 484 // add extended key if virtual keys don't match 485 if (m_buttonToVK[button] != i) { 486 m_buttonToVK[button | 0x100u] = i; 487 } 488 break; 489 } 490 } 491 492 // add alt+printscreen 493 if (m_buttonToVK[0x54u] == 0) { 494 m_buttonToVK[0x54u] = VK_SNAPSHOT; 495 } 415 USHORT usButton = i; 416 USHORT fShiftState = 0; 417 WinTranslateChar2(0, &usButton, NULL, TC_VIRTUALKEYTOSCANCODE, &fShiftState); 418 419 // add extended key if virtual keys don't match 420 if ( usButton != 0 421 && m_buttonToVK[usButton] != i) { 422 m_buttonToVK[usButton | 0x100u] = i; 423 } 424 } 425 426 /// @todo? 427 // // add alt+printscreen 428 // if (m_buttonToVK[0x54u] == 0) { 429 // m_buttonToVK[0x54u] = VK_SNAPSHOT; 430 // } 496 431 497 432 // set virtual key to button table 498 if (GetKeyboardLayout(0) == m_groups[g]) {433 // if (GetKeyboardLayout(0) == m_groups[g]) { 499 434 for (KeyButton i = 0; i < 512; ++i) { 500 435 if (m_buttonToVK[i] != 0) { … … 503 438 } 504 439 } 505 if (m_buttonToNumpadVK[i] != 0) { 506 if (m_virtualKeyToButton[m_buttonToNumpadVK[i]] == 0) { 507 m_virtualKeyToButton[m_buttonToNumpadVK[i]] = i; 508 } 509 } 510 } 511 } 512 513 // add numpad keys 514 for (KeyButton i = 0; i < 512; ++i) { 515 if (m_buttonToNumpadVK[i] != 0) { 516 item.m_id = getKeyID(m_buttonToNumpadVK[i], i); 517 item.m_button = i; 518 item.m_required = KeyModifierNumLock; 519 item.m_sensitive = KeyModifierNumLock | KeyModifierShift; 520 item.m_generates = 0; 521 item.m_client = m_buttonToNumpadVK[i]; 522 addKeyEntry(keyMap, item); 523 } 524 } 525 526 // add other keys 440 } 441 // } 442 443 // add the keys to the map. 527 444 BYTE keys[256]; 528 445 memset(keys, 0, sizeof(keys)); 529 446 for (KeyButton i = 0; i < 512; ++i) { 530 if (m_buttonToVK[i] != 0) { 447 USHORT usChar = i; 448 USHORT fCharShiftState = 0; 449 USHORT fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOVIRTUALKEY, &fCharShiftState); 450 if ( usChar 451 || m_buttonToVK[i]) { 531 452 // initialize item 532 453 item.m_id = getKeyID(m_buttonToVK[i], i); … … 534 455 item.m_required = 0; 535 456 item.m_sensitive = 0; 536 item.m_client = m_buttonToVK[i]; 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 ?? 537 462 538 463 // get flags for modifier keys … … 540 465 541 466 if (item.m_id == 0) { 467 #if 0 542 468 // translate virtual key to a character with and without 543 469 // shift, caps lock, and AltGr. … … 551 477 { VK_SHIFT, VK_SHIFT, 0x80u, KeyModifierShift }, 552 478 { VK_CAPITAL, VK_CAPITAL, 0x01u, KeyModifierCapsLock }, 553 { VK_CONTROL, VK_MENU, 0x80u, KeyModifierControl | 554 KeyModifierAlt } 479 { VK_CONTROL, VK_MENU, 0x80u, KeyModifierControl | KeyModifierAlt } 555 480 }; 556 static const size_t s_numModifiers = 557 sizeof(modifiers) / sizeof(modifiers[0]); 481 static const size_t s_numModifiers = sizeof(modifiers) / sizeof(modifiers[0]); 558 482 static const size_t s_numCombinations = 1 << s_numModifiers; 559 483 KeyID id[s_numCombinations]; … … 572 496 } 573 497 } 574 id[j] = getIDForKey(item, button, 575 m_buttonToVK[i], keys, m_groups[g]); 498 id[j] = getIDForKey(item, button, m_buttonToVK[i], keys, m_groups[g]); 576 499 if (id[j] != 0) { 577 500 anyFound = true; … … 607 530 } 608 531 } 609 } 610 else {611 // found in table 532 #endif 533 } else { 534 // found in table - adjust modifiers and add it. 612 535 switch (m_buttonToVK[i]) { 613 case VK_TAB: 614 // add kKeyLeftTab, too 615 item.m_id = kKeyLeftTab; 536 case VK_BACKTAB: 616 537 item.m_required |= KeyModifierShift; 617 538 item.m_sensitive |= KeyModifierShift; 618 addKeyEntry(keyMap, item);619 item.m_id = kKeyTab;620 item.m_required &= ~KeyModifierShift;621 break;622 623 case VK_CANCEL:624 item.m_required |= KeyModifierControl;625 item.m_sensitive |= KeyModifierControl;626 break;627 628 case VK_SNAPSHOT:629 item.m_sensitive |= KeyModifierAlt;630 if ((i & 0x100u) == 0) {631 // non-extended snapshot key requires alt632 item.m_required |= KeyModifierAlt;633 }634 539 break; 635 540 } … … 637 542 } 638 543 } 639 } 640 } 641 544 } // for buttons 0 thru 511 545 } 546 547 #if 0 642 548 // restore keyboard layout 643 549 ActivateKeyboardLayout(activeLayout, 0); … … 648 554 CPMKeyState::fakeKey(const Keystroke& keystroke) 649 555 { 556 LOG((CLOG_DEBUG "fakeKey:")); 650 557 switch (keystroke.m_type) { 651 558 case Keystroke::kButton: { 652 LOG((CLOG_DEBUG1 " %03x (%08x) %s%s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, 559 LOG((CLOG_DEBUG1 " %03x (%08x) %s%s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, 653 560 keystroke.m_data.m_button.m_press ? "down" : "up", keystroke.m_data.m_button.m_repeat ? " repeate" : "")); 654 561 KeyButton button = keystroke.m_data.m_button.m_button; 655 562 656 // windowsdoesn't send key ups for key repeats563 // OS/2 doesn't send key ups for key repeats 657 564 if (keystroke.m_data.m_button.m_repeat && 658 565 !keystroke.m_data.m_button.m_press) { 659 LOG((CLOG_DEBUG 1" discard key repeat release"));566 LOG((CLOG_DEBUG " discard key repeat release")); 660 567 break; 661 568 } 662 569 663 // get the virtual key for the button 664 ULONG vk = keystroke.m_data.m_button.m_client; 665 666 // synthesize event 667 #if 0///fixme! 668 m_desks->fakeKeyEvent(button, vk, 669 keystroke.m_data.m_button.m_press, 670 keystroke.m_data.m_button.m_repeat); 671 #endif 570 // 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 577 // synthesize message 578 HAB hab = CPMUtil::getHAB();/// @todo fix this 579 QMSG qmsg; 580 qmsg.hwnd = NULLHANDLE; 581 qmsg.msg = WM_CHAR; 582 qmsg.ptl.x = 0; 583 qmsg.ptl.y = 0; 584 qmsg.time = WinGetCurrentTime(hab); 585 qmsg.reserved = 0; 586 587 // mp2 588 if (!keystroke.m_data.m_button.m_press) { 589 pmChar |= 0x0e00; /// @todo figure out what's going on here... 590 } 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? 598 } 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. 613 const char *pszError = m_fakeMsg(hab, &qmsg); 614 if (pszError) { 615 LOG((CLOG_ERR " fakeMsg failed to inject msg=%#lx mp1=%#lx mp2=%#lx: %s", qmsg.msg, qmsg.mp1, qmsg.mp2, pszError)); 616 } 617 618 // remember the previous key for KC_LONEKEY. 619 if (keystroke.m_data.m_button.m_press && !keystroke.m_data.m_button.m_repeat) 620 m_lastButton = scanCode; 672 621 break; 673 622 } … … 689 638 } 690 639 } 691 #endif 640 #endif 692 641 break; 693 642 } … … 697 646 CPMKeyState::getActiveModifiersRValue() 698 647 { 648 LOG((CLOG_DEBUG "getActiveModifiersRValue:")); 699 649 if (m_useSavedModifiers) { 700 650 return m_savedModifiers; 701 651 } 702 else { 703 return CKeyState::getActiveModifiersRValue(); 704 } 652 return CKeyState::getActiveModifiersRValue(); 705 653 } 706 654 … … 708 656 CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button) 709 657 { 710 if ((button & 0x100u) != 0) { 711 virtualKey += 0x100u; 712 } 713 return s_virtualKey[virtualKey]; 658 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; 714 666 } 715 667 … … 719 671 PBYTE keyState) const 720 672 { 673 LOG((CLOG_DEBUG "getIDForKey:")); 721 674 #if 0 722 675 int n; … … 750 703 CPMKeyState::addKeyEntry(CKeyMap& keyMap, CKeyMap::KeyItem& item) 751 704 { 705 LOG((CLOG_DEBUG "addKeyEntry:")); 752 706 keyMap.addKeyEntry(item); 753 707 if (item.m_group == 0) { 754 m_keyToVKMap[item.m_id] = static_cast<ULONG>(item.m_client);755 708 m_keyToVKMap[item.m_id] = item.m_client; 709 } 756 710 } 757 711 -
trunk/synergy/lib/platform/CPMKeyState.h
r2761 r2765 19 19 #include "CKeyState.h" 20 20 #include "CString.h" 21 #include "CPMSynergyHook.h" 21 22 #include "stdvector.h" 22 23 #define INCL_ERRORS … … 34 35 class CPMKeyState : public CKeyState { 35 36 public: 36 CPMKeyState(void* eventTarget );37 CPMKeyState(void* eventTarget, FakeMsgFunc fakeMsg); 37 38 virtual ~CPMKeyState(); 38 39 … … 153 154 154 155 private: 155 typedef std::map<KeyID, ULONG> KeyToVKMap; 156 156 typedef std::map<KeyID, UInt32> KeyToVKMap; 157 157 void* m_eventTarget; 158 158 ULONG m_buttonToVK[512]; 159 ULONG m_buttonToNumpadVK[512];160 159 KeyButton m_virtualKeyToButton[256]; 161 160 KeyToVKMap m_keyToVKMap; 161 162 // function which can inject fake WM_CHAR messages. 163 FakeMsgFunc m_fakeMsg; 164 165 // the last button pressed. 166 KeyButton m_lastButton; 162 167 163 168 // the timer used to check for fixing key state -
trunk/synergy/lib/platform/CPMScreen.cpp
r2764 r2765 96 96 m_hmodHook = openHookLibrary("synrgyhk"); 97 97 m_screensaver = new CPMScreenSaver(); 98 m_keyState = new CPMKeyState(getEventTarget() );98 m_keyState = new CPMKeyState(getEventTarget(), m_fakeMsg); 99 99 updateScreenShape(); 100 100 m_window = createWindow("Synergy"); -
trunk/synergy/lib/platform/CPMUtil.cpp
r2761 r2765 3 3 * Copyright (C) 2004 Chris Schoeneman 4 4 * Copyright (C) 2006 Knut St. Osmundsen 5 * 5 * 6 6 * This package is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License 8 8 * found in the file COPYING that should have accompanied this file. 9 * 9 * 10 10 * This package is distributed in the hope that it will be useful, 11 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 67 67 return result; 68 68 } 69 #endif 69 #endif 70 70 } 71 71 … … 83 83 } 84 84 85 86 /** dynamic resolver */ 87 USHORT APIENTRY WinTranslateChar2(USHORT usCodePage, 88 PUSHORT pusCharInOut, 89 PULONG pulDeadKeyInfo, 90 WINTCOP enmOperation, 91 PUSHORT pfShiftState) 92 { 93 static USHORT (* APIENTRY pfnWinTranslateChar2)(USHORT, PUSHORT, PULONG, WINTCOP, PUSHORT) = NULL; 94 if (!pfnWinTranslateChar2) { 95 /* resolve it */ 96 HMODULE hmod; 97 if ( DosLoadModule(NULL, 0, (PCSZ)"PMWIN", &hmod) != NO_ERROR 98 || DosQueryProcAddr(hmod, 1070, NULL, (PPFN)&pfnWinTranslateChar2) != NO_ERROR) { 99 asm("int3"); 100 *pusCharInOut = 0; 101 return 0; 102 } 103 DosFreeModule(hmod); 104 } 105 return pfnWinTranslateChar2(usCodePage, pusCharInOut, pulDeadKeyInfo, enmOperation, pfShiftState); 106 } 107 -
trunk/synergy/lib/platform/CPMUtil.h
r2761 r2765 3 3 * Copyright (C) 2004 Chris Schoeneman 4 4 * Copyright (C) 2006 Knut St. Osmundsen 5 * 5 * 6 6 * This package is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License 8 8 * found in the file COPYING that should have accompanied this file. 9 * 9 * 10 10 * This package is distributed in the hope that it will be useful, 11 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of … … 37 37 */ 38 38 static CString getErrorString(HMODULE hmod, ULONG error, ULONG id); 39 39 40 40 static HAB getHAB(void); 41 41 static HMQ getHMQ(HAB hab = NULLHANDLE); … … 43 43 }; 44 44 45 46 /** The WinTranlateChar2 operation. */ 47 typedef enum WINTCOP 48 { 49 TC_CHARTOSCANCODE = 0, 50 TC_SCANCODETOCHAR, 51 TC_VIRTUALKEYTOSCANCODE, 52 TC_SCANCODETOVIRTUALKEY, 53 TC_SCANTOOEMSCAN, 54 TC_OEMSCANTOSCAN, 55 TC_SIZE_HACK = 0x7fff 56 } WINTCOP; 57 58 /** @name WinTranslateChar2 shift state. 59 * This state goes with scancode input/output. 60 * @{ */ 61 #define TCF_LSHIFT 0x1 62 #define TCF_RSHIFT 0x2 63 #define TCF_SHIFT (TCF_LSHIFT | TCF_RSHIFT) 64 #define TCF_LCONTROL 0x4 65 #define TCF_RCONTROL 0x8 66 #define TCF_CONTROL (TCF_LCONTROL | TCF_RCONTROL) 67 #define TCF_ALT 0x10 68 #define TCF_ALTGR 0x20 69 #define TCF_CAPSLOCK 0x40 70 #define TCF_NUMLOCK 0x80 71 #define TCF_MAX_BITS 8 /**< bits 0-7 are real shift states */ 72 #define TCF_OEMSCANCODE 0x100 73 #define TCF_EXTENDEDKEY 0x200 74 /** @} */ 75 76 /** 77 * Char to/from keyboard code translator. 78 * 79 * @returns A combination of some of the KC_* values. 80 * @param usCodePage The code page. Anything goes, apparently ignored. 81 * @param pusCharInOut Where to get the char/code to be translated and to 82 * put the output upon return. 83 * @param pulDeadKeyInfo Previous, dead key. 84 * @param enmOperation The kind of translation. 85 * @param pfShiftState Where to read/store the shift state. Used when 86 * translating from/to scancodes. 87 * @remark PMWIN.1070 88 */ 89 extern "C" 90 USHORT APIENTRY WinTranslateChar2(USHORT usCodePage, 91 PUSHORT pusCharInOut, 92 PULONG pulDeadKeyInfo, 93 WINTCOP enmOperation, 94 PUSHORT pfShiftState); 95 45 96 #endif 97
Note:
See TracChangeset
for help on using the changeset viewer.