Changeset 2761
- Timestamp:
- Aug 13, 2006, 1:41:05 AM (19 years ago)
- Location:
- trunk/synergy/lib/platform
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/synergy/lib/platform/CPMEventQueueBuffer.cpp
r2755 r2761 16 16 #include "CPMEventQueueBuffer.h" 17 17 #include "CThread.h" 18 #include "CLog.h" 18 19 #include "IEventQueue.h" 20 #include "CPMUtil.h" 21 #include <unistd.h> 19 22 20 23 // … … 31 34 CPMEventQueueBuffer::CPMEventQueueBuffer() 32 35 { 33 // remember the queue (/ thread / hab). we'll be posting messages to it. 34 m_hab = WinInitialize(0); 35 m_hmq = WinCreateMsgQueue(m_hab, 0); 36 assert(m_hmq != NULLHANDLE); 36 // the anchor block. Remeber it for use when waiting, peeking, and getting events. 37 m_hab = NULLHANDLE; 38 PTIB pTib; 39 PPIB pPib; 40 DosGetInfoBlocks(&pTib, &pPib); 41 LOG((CLOG_DEBUG2 "CPMEventQueueBuffer: ultype=%lx tid=%lx", pPib->pib_ultype, pTib->tib_ptib2->tib2_ultid)); 42 if (pPib->pib_ultype != 3) { 43 pPib->pib_ultype = 3; 44 m_shallTerminate = true; 45 m_hab = WinInitialize(0); 46 } 47 if (m_hab == NULLHANDLE) { 48 m_hab = CPMUtil::getHAB(); 49 if (m_hab == NULLHANDLE) { 50 m_shallTerminate = true; 51 m_hab = WinInitialize(0); 52 } 53 } 54 55 // the message queue. remember it so we can post and get messages. 56 m_hmq = CPMUtil::getHMQ(m_hab); 57 if (m_hmq == NULLHANDLE) { 58 m_shallDestroyMsgQueue = true; 59 m_hmq = WinCreateMsgQueue(m_hab, 0); 60 } 61 62 // check that we succeeded the two previous steps. 63 if (m_hab == NULLHANDLE || m_hmq == NULLHANDLE) { 64 LOG((CLOG_CRIT "couldn't get the hab(%lx)/hmq(%lx) of the current thread!", m_hab, m_hmq)); 65 assert(m_hab != NULLHANDLE && m_hmq != NULLHANDLE); 66 } 67 assert(CPMUtil::getHAB() == m_hab); 37 68 38 69 // create a message type for custom events … … 46 77 APIRET rc = DosCreateEventSem(NULL, &m_hev, 0, FALSE); 47 78 assert(rc == NO_ERROR); 79 LOG((CLOG_DEBUG2 "CPMEventQueueBuffer: m_userEvent=%#lx m_daemonQuit=%#lx m_hev=%#lx m_hab=%#lx m_hmq=%#lx m_shallTermiate=%d m_shallDestroyMsgQueue=%d", 80 m_userEvent, m_daemonQuit, m_hev, m_hab, m_hmq, m_shallTerminate, m_shallDestroyMsgQueue)); 48 81 } 49 82 … … 52 85 // do nothing 53 86 DosCloseEventSem(m_hev); 54 WinDestroyMsgQueue(m_hmq); 55 WinTerminate(m_hab); 87 if (m_shallDestroyMsgQueue) { 88 WinDestroyMsgQueue(m_hmq); 89 } 90 if (m_shallTerminate) { 91 WinTerminate(m_hab); 92 } 56 93 } 57 94 … … 62 99 ULONG fStatus = WinQueryQueueStatus(HWND_DESKTOP); 63 100 if (!fStatus) { 101 ULONG cPosts; 102 DosResetEventSem(m_hev, &cPosts); 103 fStatus = WinQueryQueueStatus(HWND_DESKTOP); 104 } 105 LOG((CLOG_DEBUG2 "waitForEvent: %#lx", fStatus)); 106 if (!fStatus) { 64 107 // convert timeout and wait. 65 108 ULONG ulPMTimeout = timeout < 0.0 … … 67 110 : (ULONG)(1000.0 * timeout); 68 111 WinWaitEventSem(m_hev, ulPMTimeout); 112 LOG((CLOG_DEBUG2 "waitForEvent: ulPMTimeout=%ld", ulPMTimeout)); 69 113 } 70 114 } … … 76 120 QMSG qmsg; 77 121 if (!WinPeekMsg(m_hab, &qmsg, NULLHANDLE, 0, 0, PM_NOREMOVE)) { 122 LOG((CLOG_DEBUG2 "getEvent: kNone")); 78 123 return kNone; 79 124 } … … 88 133 if (m_event.msg == m_userEvent) { 89 134 dataID = (UInt32)(uintptr_t)m_event.mp1; 135 LOG((CLOG_DEBUG2 "getEvent: dataID=%#x", dataID)); 90 136 return kUser; 91 137 } 92 138 93 139 event = CEvent(CEvent::kSystem, IEventQueue::getSystemTarget(), &m_event); 140 LOG((CLOG_DEBUG2 "getEvent: kSystem")); 94 141 return kSystem; 95 142 } … … 98 145 CPMEventQueueBuffer::addEvent(UInt32 dataID) 99 146 { 100 return WinPostQueueMsg(m_hmq, m_userEvent, (MPARAM)dataID, 0) != FALSE; 147 LOG((CLOG_DEBUG2 "addEvent: dataID=%#x", dataID)); 148 BOOL fRc = WinPostQueueMsg(m_hmq, m_userEvent, (MPARAM)dataID, 0) != FALSE; 149 if (fRc) { 150 DosPostEventSem(m_hev); 151 } else { 152 LOG((CLOG_CRIT "addEvent: dataID=%#x fRc=%d lasterr=%d", dataID, WinGetLastError(CPMUtil::getHAB()))); 153 } 154 return fRc; 101 155 } 102 156 … … 105 159 { 106 160 ULONG fStatus = WinQueryQueueStatus(HWND_DESKTOP); 107 return fStatus != 0; 161 LOG((CLOG_DEBUG2 "isEmpty: %#lx", fStatus)); 162 return fStatus == 0; 108 163 } 109 164 -
trunk/synergy/lib/platform/CPMEventQueueBuffer.h
r2752 r2761 39 39 40 40 private: 41 bool m_shallTerminate; 41 42 HAB m_hab; 43 bool m_shallDestroyMsgQueue; 42 44 HMQ m_hmq; 43 45 HEV m_hev; -
trunk/synergy/lib/platform/CPMKeyState.cpp
r2755 r2761 181 181 // extract character, virtual key, and if we didn't use AltGr 182 182 char c = (char)((charAndVirtKey & 0xff00u) >> 8); 183 U INT vkCode= (charAndVirtKey & 0xffu);183 ULONG vkCode = (charAndVirtKey & 0xffu); 184 184 bool noAltGr = ((charAndVirtKey & 0xff0000u) != 0); 185 185 … … 240 240 241 241 void 242 CPMKeyState::onKey(KeyButton button, bool down, KeyModifierMask newState)243 {244 // handle win32 brokenness and forward to superclass245 fixKeys();246 CKeyState::onKey(button, down, newState);247 fixKeys();248 }249 250 void251 242 CPMKeyState::sendKeyEvent(void* target, 252 243 bool press, bool isAutoRepeat, … … 316 307 CPMKeyState::pollActiveGroup() const 317 308 { 318 // determine the thread that'll receive this event 319 HWND targetWindow = GetForegroundWindow(); 320 ULONG targetThread = GetWindowThreadProcessId(targetWindow, NULL); 321 322 // get keyboard layout for the thread 309 #if 0 323 310 HKL hkl = GetKeyboardLayout(targetThread); 324 311 … … 331 318 332 319 return i->second; 320 #else 321 return 0; 322 #endif 333 323 } 334 324 … … 337 327 { 338 328 BYTE keyState[256]; 339 GetKeyboardState(keyState); 340 for (KeyButton i = 1; i < 256; ++i) { 341 if ((keyState[i] & 0x80) != 0) { 342 pressedKeys.insert(i); 343 } 344 } 329 if (WinSetKeyboardStateTable(HWND_DESKTOP, keyState, FALSE)) { 330 for (KeyButton i = 1; i < 256; ++i) { 331 if ((keyState[i] & 0x80) != 0) { 332 pressedKeys.insert(i); 333 } 334 } 335 } 345 336 } 346 337 … … 348 339 CPMKeyState::getKeyMap(CKeyMap& keyMap) 349 340 { 341 #if 0 350 342 // update keyboard groups 351 343 if (getGroups(m_groups)) { … … 374 366 // map buttons (scancodes) to virtual keys 375 367 for (KeyButton i = 1; i < 256; ++i) { 376 U INTvk = MapVirtualKey(i, 1);368 ULONG vk = MapVirtualKey(i, 1); 377 369 if (vk == 0) { 378 370 // unmapped … … 453 445 // either a numpad key and we use the button as is or it's an 454 446 // extended button. 455 for (U INTi = 1; i < 255; ++i) {447 for (ULONG i = 1; i < 255; ++i) { 456 448 // skip virtual keys we don't want 457 449 switch (i) { … … 551 543 // shift, caps lock, and AltGr. 552 544 struct Modifier { 553 U INTm_vk1;554 U INTm_vk2;545 ULONG m_vk1; 546 ULONG m_vk2; 555 547 BYTE m_state; 556 548 KeyModifierMask m_mask; … … 650 642 // restore keyboard layout 651 643 ActivateKeyboardLayout(activeLayout, 0); 644 #endif 652 645 } 653 646 … … 668 661 669 662 // get the virtual key for the button 670 UINT vk = keystroke.m_data.m_button.m_client; 671 672 // special handling of VK_SNAPSHOT 673 if (vk == VK_SNAPSHOT) { 674 if ((getActiveModifiers() & KeyModifierAlt) != 0) { 675 // snapshot active window 676 button = 1; 677 } 678 else { 679 // snapshot full screen 680 button = 0; 681 } 682 } 683 684 // synthesize event 663 ULONG vk = keystroke.m_data.m_button.m_client; 664 665 // synthesize event 666 #if 0///fixme! 685 667 m_desks->fakeKeyEvent(button, vk, 686 668 keystroke.m_data.m_button.m_press, 687 669 keystroke.m_data.m_button.m_repeat); 670 #endif 688 671 break; 689 672 } 690 673 691 674 case Keystroke::kGroup: 675 #if 0 692 676 // we don't restore the group. we'd like to but we can't be 693 677 // sure the restoring group change will be processed after the … … 704 688 } 705 689 } 690 #endif 706 691 break; 707 692 } … … 719 704 } 720 705 721 void722 CPMKeyState::fixKeys()723 {724 // fake key releases for the windows keys if we think they're725 // down but they're really up. we have to do this because if the726 // user presses and releases a windows key without pressing any727 // other key while it's down then the system will eat the key728 // release. if we don't detect that and synthesize the release729 // then the client won't take the usual windows key release action730 // (which on windows is to show the start menu).731 //732 // only check on the windows 95 family since the NT family reports733 // the key releases as usual.734 if (!m_is95Family) {735 return;736 }737 738 KeyButton leftButton = virtualKeyToButton(VK_LWIN);739 KeyButton rightButton = virtualKeyToButton(VK_RWIN);740 bool leftDown = isKeyDown(leftButton);741 bool rightDown = isKeyDown(rightButton);742 bool fix = (leftDown || rightDown);743 if (fix) {744 // check if either button is not really down745 bool leftAsyncDown = ((GetAsyncKeyState(VK_LWIN) & 0x8000) != 0);746 bool rightAsyncDown = ((GetAsyncKeyState(VK_RWIN) & 0x8000) != 0);747 748 if (leftAsyncDown != leftDown || rightAsyncDown != rightDown) {749 KeyModifierMask state = getActiveModifiers();750 if (!leftAsyncDown && !rightAsyncDown) {751 // no win keys are down so remove super modifier752 state &= ~KeyModifierSuper;753 }754 755 // report up events756 if (leftDown && !leftAsyncDown) {757 LOG((CLOG_DEBUG1 "event: fake key release left windows key (0x%03x)", leftButton));758 CKeyState::onKey(leftButton, false, state);759 CKeyState::sendKeyEvent(m_eventTarget, false, false, kKeySuper_L, state, 1, leftButton);760 }761 if (rightDown && !rightAsyncDown) {762 LOG((CLOG_DEBUG1 "event: fake key release right windows key (0x%03x)", rightButton));763 CKeyState::onKey(rightButton, false, state);764 CKeyState::sendKeyEvent(m_eventTarget, false, false, kKeySuper_R, state, 1, rightButton);765 }766 }767 }768 769 if (fix && m_fixTimer == NULL) {770 // schedule check771 m_fixTimer = EVENTQUEUE->newTimer(0.1, NULL);772 EVENTQUEUE->adoptHandler(CEvent::kTimer, m_fixTimer,773 new TMethodEventJob<CPMKeyState>(774 this, &CPMKeyState::handleFixKeys));775 }776 else if (!fix && m_fixTimer != NULL) {777 // remove scheduled check778 EVENTQUEUE->removeHandler(CEvent::kTimer, m_fixTimer);779 EVENTQUEUE->deleteTimer(m_fixTimer);780 m_fixTimer = NULL;781 }782 }783 784 void785 CPMKeyState::handleFixKeys(const CEvent&, void*)786 {787 fixKeys();788 }789 790 706 KeyID 791 CPMKeyState::getKeyID(U INTvirtualKey, KeyButton button)707 CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button) 792 708 { 793 709 if ((button & 0x100u) != 0) { … … 799 715 KeyID 800 716 CPMKeyState::getIDForKey(CKeyMap::KeyItem& item, 801 KeyButton button, UINT virtualKey, 802 PBYTE keyState, HKL hkl) const 803 { 717 KeyButton button, ULONG virtualKey, 718 PBYTE keyState) const 719 { 720 #if 0 804 721 int n; 805 722 KeyID id; 806 if (m_is95Family) { 807 // XXX -- how do we get characters not in Latin-1? 808 WORD ascii; 809 n = ToAsciiEx(virtualKey, button, keyState, &ascii, 0, hkl); 810 id = static_cast<KeyID>(ascii & 0xffu); 811 } 812 else { 813 WCHAR unicode[2]; 814 n = m_ToUnicodeEx(virtualKey, button, keyState, 815 unicode, sizeof(unicode) / sizeof(unicode[0]), 816 0, hkl); 817 id = static_cast<KeyID>(unicode[0]); 818 } 723 WORD ascii; 724 n = ToAsciiEx(virtualKey, button, keyState, &ascii, 0, hkl); 725 id = static_cast<KeyID>(ascii & 0xffu); 819 726 switch (n) { 820 727 case -1: … … 833 740 return getIDForKey(item, button, virtualKey, keyState, hkl); 834 741 } 742 #else 743 //fixme! 744 return 0; 745 #endif 835 746 } 836 747 … … 840 751 keyMap.addKeyEntry(item); 841 752 if (item.m_group == 0) { 842 m_keyToVKMap[item.m_id] = static_cast<U INT>(item.m_client);753 m_keyToVKMap[item.m_id] = static_cast<ULONG>(item.m_client); 843 754 } 844 755 } -
trunk/synergy/lib/platform/CPMKeyState.h
r2755 r2761 128 128 129 129 // CKeyState overrides 130 virtual void onKey(KeyButton button, bool down,131 KeyModifierMask newState);132 130 virtual void sendKeyEvent(void* target, 133 131 bool press, bool isAutoRepeat, … … 143 141 144 142 private: 145 void fixKeys();146 void handleFixKeys(const CEvent&, void*);147 148 143 KeyID getIDForKey(CKeyMap::KeyItem& item, 149 144 KeyButton button, ULONG virtualKey, -
trunk/synergy/lib/platform/CPMScreen.cpp
r2755 r2761 70 70 { 71 71 assert(s_screen == NULL); 72 73 72 s_screen = this; 73 74 // create the event queue buffer first so we know there is a message queue. 75 CPMEventQueueBuffer *eventQueue = new CPMEventQueueBuffer(); 74 76 75 77 // query curren thread bits. 76 78 m_threadID = _gettid(); 77 79 m_hab = WinQueryAnchorBlock(HWND_DESKTOP); 80 //if (m_hab == NULLHANDLE) { 81 // m_hab = WinInitialize(0); 82 //} 78 83 m_hmq = WinQueueFromID(m_hab, getpid(), _gettid()); 84 //if (m_hab != NULLHANDLE && m_hmq == NULLHANDLE) { 85 // m_hmq = WinCreateMsgQueue(m_hab, 0); 86 //} 79 87 if (m_hab == NULLHANDLE || m_hmq == NULLHANDLE) { 80 LOG((CLOG_CRIT "couldn't get the hab/hmq of the current thread!\n")); 88 LOG((CLOG_CRIT "couldn't get the hab(%ld)/hmq(%ld) of the current thread! %d\n", m_hab, m_hmq)); 89 delete eventQueue; 90 s_screen = NULL; 81 91 throw XScreenOpenFailure(); 82 92 } … … 97 107 destroyWindow(m_window); 98 108 closeHookLibrary(m_hmodHook); 109 delete eventQueue; 99 110 s_screen = NULL; 100 111 throw; … … 626 637 0, //WS_?, 627 638 0, 0, 1, 1, 628 HWND_DESKTOP,629 639 NULLHANDLE, 640 HWND_TOP, 630 641 0, 631 642 this, 632 643 NULL); 633 644 if (hwnd == NULLHANDLE) { 634 LOG((CLOG_ERR "failed to create window: %l d", WinGetLastError(m_hab)));645 LOG((CLOG_ERR "failed to create window: %lx", WinGetLastError(m_hab))); 635 646 throw XScreenOpenFailure(); 636 647 } -
trunk/synergy/lib/platform/CPMUtil.cpp
r2752 r2761 17 17 #include "CStringUtil.h" 18 18 #include <stdio.h> 19 #include <process.h> 19 20 20 21 // … … 74 75 } 75 76 77 HMQ CPMUtil::getHMQ(HAB hab /* = NULLHANDLE */) 78 { 79 if (hab == NULLHANDLE) { 80 hab = getHAB(); 81 } 82 return WinQueueFromID(hab, getpid(), _gettid()); 83 } 84 -
trunk/synergy/lib/platform/CPMUtil.h
r2752 r2761 39 39 40 40 static HAB getHAB(void); 41 static HMQ getHMQ(HAB hab = NULLHANDLE); 41 42 42 43 };
Note:
See TracChangeset
for help on using the changeset viewer.