source: trunk/synergy/lib/platform/CPMEventQueueBuffer.cpp

Last change on this file was 2761, checked in by bird, 19 years ago

Hacking and debugging.

File size: 5.1 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2004 Chris Schoeneman
4 * Copyright (C) 2006 Knut St. Osmundsen
5 *
6 * This package is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * found in the file COPYING that should have accompanied this file.
9 *
10 * This package is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include "CPMEventQueueBuffer.h"
17#include "CThread.h"
18#include "CLog.h"
19#include "IEventQueue.h"
20#include "CPMUtil.h"
21#include <unistd.h>
22
23//
24// CEventQueueTimer
25//
26
27class CEventQueueTimer { };
28
29
30//
31// CPMEventQueueBuffer
32//
33
34CPMEventQueueBuffer::CPMEventQueueBuffer()
35{
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);
68
69 // create a message type for custom events
70 m_userEvent = WM_USER + 42 + 42 + 42;
71
72 // get message type for daemon quit
73 m_daemonQuit = WM_USER + 666;
74
75 // create the event semaphore we'll be waiting on when waiting for messages.
76 m_hev = NULLHANDLE;
77 APIRET rc = DosCreateEventSem(NULL, &m_hev, 0, FALSE);
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));
81}
82
83CPMEventQueueBuffer::~CPMEventQueueBuffer()
84{
85 // do nothing
86 DosCloseEventSem(m_hev);
87 if (m_shallDestroyMsgQueue) {
88 WinDestroyMsgQueue(m_hmq);
89 }
90 if (m_shallTerminate) {
91 WinTerminate(m_hab);
92 }
93}
94
95void
96CPMEventQueueBuffer::waitForEvent(double timeout)
97{
98 // check if messages are available first.
99 ULONG fStatus = WinQueryQueueStatus(HWND_DESKTOP);
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) {
107 // convert timeout and wait.
108 ULONG ulPMTimeout = timeout < 0.0
109 ? SEM_INDEFINITE_WAIT
110 : (ULONG)(1000.0 * timeout);
111 WinWaitEventSem(m_hev, ulPMTimeout);
112 LOG((CLOG_DEBUG2 "waitForEvent: ulPMTimeout=%ld", ulPMTimeout));
113 }
114}
115
116IEventQueueBuffer::Type
117CPMEventQueueBuffer::getEvent(CEvent& event, UInt32& dataID)
118{
119 // peek at messages first.
120 QMSG qmsg;
121 if (!WinPeekMsg(m_hab, &qmsg, NULLHANDLE, 0, 0, PM_NOREMOVE)) {
122 LOG((CLOG_DEBUG2 "getEvent: kNone"));
123 return kNone;
124 }
125
126 // get the message
127 if ( !WinGetMsg(m_hab, &m_event, NULLHANDLE, 0, 0)
128 || (m_event.msg == m_daemonQuit && m_daemonQuit != 0)) {
129 event = CEvent(CEvent::kQuit);
130 return kSystem;
131 }
132
133 if (m_event.msg == m_userEvent) {
134 dataID = (UInt32)(uintptr_t)m_event.mp1;
135 LOG((CLOG_DEBUG2 "getEvent: dataID=%#x", dataID));
136 return kUser;
137 }
138
139 event = CEvent(CEvent::kSystem, IEventQueue::getSystemTarget(), &m_event);
140 LOG((CLOG_DEBUG2 "getEvent: kSystem"));
141 return kSystem;
142}
143
144bool
145CPMEventQueueBuffer::addEvent(UInt32 dataID)
146{
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;
155}
156
157bool
158CPMEventQueueBuffer::isEmpty() const
159{
160 ULONG fStatus = WinQueryQueueStatus(HWND_DESKTOP);
161 LOG((CLOG_DEBUG2 "isEmpty: %#lx", fStatus));
162 return fStatus == 0;
163}
164
165CEventQueueTimer*
166CPMEventQueueBuffer::newTimer(double, bool) const
167{
168 return new CEventQueueTimer;
169}
170
171void
172CPMEventQueueBuffer::deleteTimer(CEventQueueTimer* timer) const
173{
174 delete timer;
175}
176
177/*
178 * Local Variables:
179 * mode: c
180 * c-file-style: "k&r"
181 * c-basic-offset: 4
182 * tab-width: 4
183 * indent-tabs-mode: t
184 * End:
185 */
186
Note: See TracBrowser for help on using the repository browser.