Changeset 2752 for trunk/synergy/lib/platform/CPMEventQueueBuffer.cpp
- Timestamp:
- Jul 29, 2006, 6:43:07 AM (19 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/synergy/lib/platform/CPMEventQueueBuffer.cpp
r2751 r2752 2 2 * synergy -- mouse and keyboard sharing utility 3 3 * Copyright (C) 2004 Chris Schoeneman 4 * Copyright (C) 2006 Knut St. Osmundsen 4 5 * 5 6 * This package is free software; you can redistribute it and/or … … 13 14 */ 14 15 15 #include "C MSWindowsEventQueueBuffer.h"16 #include "CPMEventQueueBuffer.h" 16 17 #include "CThread.h" 17 18 #include "IEventQueue.h" 18 #include "CArchMiscWindows.h"19 19 20 20 // … … 26 26 27 27 // 28 // C MSWindowsEventQueueBuffer28 // CPMEventQueueBuffer 29 29 // 30 30 31 C MSWindowsEventQueueBuffer::CMSWindowsEventQueueBuffer()31 CPMEventQueueBuffer::CPMEventQueueBuffer() 32 32 { 33 // remember thread. we'll be posting messages to it. 34 m_thread = GetCurrentThreadId(); 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); 35 37 36 38 // create a message type for custom events 37 m_userEvent = RegisterWindowMessage("SYNERGY_USER_EVENT");39 m_userEvent = WM_USER + 42 + 42 + 42; 38 40 39 41 // get message type for daemon quit 40 m_daemonQuit = CArchMiscWindows::getDaemonQuitMessage();42 m_daemonQuit = WM_USER + 666; 41 43 42 // make sure this thread has a message queue 43 MSG dummy; 44 PeekMessage(&dummy, NULL, WM_USER, WM_USER, PM_NOREMOVE); 44 // create the event semaphore we'll be waiting on when waiting for messages. 45 m_hev = NULLHANDLE; 46 APIRET rc = DosCreateEventSem(NULL, &m_hev, 0, FALSE); 47 assert(rc == NO_ERROR); 45 48 } 46 49 47 C MSWindowsEventQueueBuffer::~CMSWindowsEventQueueBuffer()50 CPMEventQueueBuffer::~CPMEventQueueBuffer() 48 51 { 49 52 // do nothing 53 DosCloseEventSem(m_hev); 54 WinDestroyMsgQueue(m_hmq); 55 WinTerminate(m_hab); 50 56 } 51 57 52 58 void 53 C MSWindowsEventQueueBuffer::waitForEvent(double timeout)59 CPMEventQueueBuffer::waitForEvent(double timeout) 54 60 { 55 // check if messages are available first. if we don't do this then 56 // MsgWaitForMultipleObjects() will block even if the queue isn't 57 // empty if the messages in the queue were there before the last 58 // call to GetMessage()/PeekMessage(). 59 if (HIWORD(GetQueueStatus(QS_ALLINPUT)) != 0) { 60 return; 61 } 62 63 // convert timeout 64 DWORD t; 65 if (timeout < 0.0) { 66 t = INFINITE; 67 } 68 else { 69 t = (DWORD)(1000.0 * timeout); 70 } 71 72 // wait for a message. we cannot be interrupted by thread 73 // cancellation but that's okay because we're run in the main 74 // thread and we never cancel that thread. 75 HANDLE dummy[1]; 76 MsgWaitForMultipleObjects(0, dummy, FALSE, t, QS_ALLINPUT); 61 // check if messages are available first. 62 ULONG fStatus = WinQueryQueueStatus(HWND_DESKTOP); 63 if (!fStatus) { 64 // convert timeout and wait. 65 ULONG ulPMTimeout = timeout < 0.0 66 ? SEM_INDEFINITE_WAIT 67 : (ULONG)(1000.0 * timeout); 68 WinWaitEventSem(m_hev, ulPMTimeout); 69 } 77 70 } 78 71 79 72 IEventQueueBuffer::Type 80 C MSWindowsEventQueueBuffer::getEvent(CEvent& event, UInt32& dataID)73 CPMEventQueueBuffer::getEvent(CEvent& event, UInt32& dataID) 81 74 { 82 // peek at messages first. waiting for QS_ALLINPUT will return 83 // if a message has been sent to our window but GetMessage will 84 // dispatch that message behind our backs and block. PeekMessage 85 // will also dispatch behind our backs but won't block. 86 if (!PeekMessage(&m_event, NULL, 0, 0, PM_NOREMOVE) && 87 !PeekMessage(&m_event, (HWND)-1, 0, 0, PM_NOREMOVE)) { 75 // peek at messages first. 76 QMSG qmsg; 77 if (!WinPeekMsg(m_hab, &qmsg, NULLHANDLE, 0, 0, PM_NOREMOVE)) { 88 78 return kNone; 89 79 } 90 80 91 // BOOL. yeah, right. 92 BOOL result = GetMessage(&m_event, NULL, 0, 0); 93 if (result == -1) { 94 return kNone; 95 } 96 else if (result == 0) { 81 // get the message 82 if ( !WinGetMsg(m_hab, &m_event, NULLHANDLE, 0, 0) 83 || (m_event.msg == m_daemonQuit && m_daemonQuit != 0)) { 97 84 event = CEvent(CEvent::kQuit); 98 85 return kSystem; 99 86 } 100 else if (m_daemonQuit != 0 && m_event.message == m_daemonQuit) { 101 event = CEvent(CEvent::kQuit); 102 return kSystem; 103 } 104 else if (m_event.message == m_userEvent) { 105 dataID = static_cast<UInt32>(m_event.wParam); 87 88 if (m_event.msg == m_userEvent) { 89 dataID = (UInt32)(uintptr_t)m_event.mp1; 106 90 return kUser; 107 91 } 108 else { 109 event = CEvent(CEvent::kSystem, 110 IEventQueue::getSystemTarget(), &m_event); 111 return kSystem; 112 } 92 93 event = CEvent(CEvent::kSystem, IEventQueue::getSystemTarget(), &m_event); 94 return kSystem; 113 95 } 114 96 115 97 bool 116 C MSWindowsEventQueueBuffer::addEvent(UInt32 dataID)98 CPMEventQueueBuffer::addEvent(UInt32 dataID) 117 99 { 118 return (PostThreadMessage(m_thread, m_userEvent, 119 static_cast<WPARAM>(dataID), 0) != 0); 100 return WinPostQueueMsg(m_hmq, m_userEvent, (MPARAM)dataID, 0) != FALSE; 120 101 } 121 102 122 103 bool 123 C MSWindowsEventQueueBuffer::isEmpty() const104 CPMEventQueueBuffer::isEmpty() const 124 105 { 125 return (HIWORD(GetQueueStatus(QS_ALLINPUT)) == 0); 106 ULONG fStatus = WinQueryQueueStatus(HWND_DESKTOP); 107 return fStatus != 0; 126 108 } 127 109 128 110 CEventQueueTimer* 129 C MSWindowsEventQueueBuffer::newTimer(double, bool) const111 CPMEventQueueBuffer::newTimer(double, bool) const 130 112 { 131 113 return new CEventQueueTimer; … … 133 115 134 116 void 135 C MSWindowsEventQueueBuffer::deleteTimer(CEventQueueTimer* timer) const117 CPMEventQueueBuffer::deleteTimer(CEventQueueTimer* timer) const 136 118 { 137 119 delete timer; 138 120 } 121
Note:
See TracChangeset
for help on using the changeset viewer.