Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

CMSWindowsEventQueueBuffer.cpp

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2004 Chris Schoeneman
00004  * 
00005  * This package is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * found in the file COPYING that should have accompanied this file.
00008  * 
00009  * This package is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #include "CMSWindowsEventQueueBuffer.h"
00016 #include "CThread.h"
00017 #include "IEventQueue.h"
00018 #include "CArchMiscWindows.h"
00019 
00020 //
00021 // CEventQueueTimer
00022 //
00023 
00024 class CEventQueueTimer { };
00025 
00026 
00027 //
00028 // CMSWindowsEventQueueBuffer
00029 //
00030 
00031 CMSWindowsEventQueueBuffer::CMSWindowsEventQueueBuffer()
00032 {
00033     // remember thread.  we'll be posting messages to it.
00034     m_thread     = GetCurrentThreadId();
00035 
00036     // create a message type for custom events
00037     m_userEvent  = RegisterWindowMessage("SYNERGY_USER_EVENT");
00038 
00039     // get message type for daemon quit
00040     m_daemonQuit = CArchMiscWindows::getDaemonQuitMessage();
00041 
00042     // make sure this thread has a message queue
00043     MSG dummy;
00044     PeekMessage(&dummy, NULL, WM_USER, WM_USER, PM_NOREMOVE);
00045 }
00046 
00047 CMSWindowsEventQueueBuffer::~CMSWindowsEventQueueBuffer()
00048 {
00049     // do nothing
00050 }
00051 
00052 void
00053 CMSWindowsEventQueueBuffer::waitForEvent(double timeout)
00054 {
00055     // check if messages are available first.  if we don't do this then
00056     // MsgWaitForMultipleObjects() will block even if the queue isn't
00057     // empty if the messages in the queue were there before the last
00058     // call to GetMessage()/PeekMessage().
00059     if (HIWORD(GetQueueStatus(QS_ALLINPUT)) != 0) {
00060         return;
00061     }
00062 
00063     // convert timeout
00064     DWORD t;
00065     if (timeout < 0.0) {
00066         t = INFINITE;
00067     }
00068     else {
00069         t = (DWORD)(1000.0 * timeout);
00070     }
00071 
00072     // wait for a message.  we cannot be interrupted by thread
00073     // cancellation but that's okay because we're run in the main
00074     // thread and we never cancel that thread.
00075     HANDLE dummy[1];
00076     MsgWaitForMultipleObjects(0, dummy, FALSE, t, QS_ALLINPUT);
00077 }
00078 
00079 IEventQueueBuffer::Type
00080 CMSWindowsEventQueueBuffer::getEvent(CEvent& event, UInt32& dataID)
00081 {
00082     // peek at messages first.  waiting for QS_ALLINPUT will return
00083     // if a message has been sent to our window but GetMessage will
00084     // dispatch that message behind our backs and block.  PeekMessage
00085     // will also dispatch behind our backs but won't block.
00086     if (!PeekMessage(&m_event, NULL, 0, 0, PM_NOREMOVE) &&
00087         !PeekMessage(&m_event, (HWND)-1, 0, 0, PM_NOREMOVE)) {
00088         return kNone;
00089     }
00090 
00091     // BOOL.  yeah, right.
00092     BOOL result = GetMessage(&m_event, NULL, 0, 0);
00093     if (result == -1) {
00094         return kNone;
00095     }
00096     else if (result == 0) {
00097         event = CEvent(CEvent::kQuit);
00098         return kSystem;
00099     }
00100     else if (m_daemonQuit != 0 && m_event.message == m_daemonQuit) {
00101         event = CEvent(CEvent::kQuit);
00102         return kSystem;
00103     }
00104     else if (m_event.message == m_userEvent) {
00105         dataID = static_cast<UInt32>(m_event.wParam);
00106         return kUser;
00107     }
00108     else {
00109         event = CEvent(CEvent::kSystem,
00110                             IEventQueue::getSystemTarget(), &m_event);
00111         return kSystem;
00112     }
00113 }
00114 
00115 bool
00116 CMSWindowsEventQueueBuffer::addEvent(UInt32 dataID)
00117 {
00118     return (PostThreadMessage(m_thread, m_userEvent,
00119                             static_cast<WPARAM>(dataID), 0) != 0);
00120 }
00121 
00122 bool
00123 CMSWindowsEventQueueBuffer::isEmpty() const
00124 {
00125     return (HIWORD(GetQueueStatus(QS_ALLINPUT)) == 0);
00126 }
00127 
00128 CEventQueueTimer*
00129 CMSWindowsEventQueueBuffer::newTimer(double, bool) const
00130 {
00131     return new CEventQueueTimer;
00132 }
00133 
00134 void
00135 CMSWindowsEventQueueBuffer::deleteTimer(CEventQueueTimer* timer) const
00136 {
00137     delete timer;
00138 }

Generated on Fri Nov 6 00:21:14 2009 for synergy-plus by  doxygen 1.3.9.1