1 /*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2012-2016 Symless Ltd.
4 * Copyright (C) 2004 Chris Schoeneman
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 LICENSE 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 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "platform/OSXEventQueueBuffer.h"
20
21 #include "base/Event.h"
22 #include "base/IEventQueue.h"
23
24 //
25 // EventQueueTimer
26 //
27
28 class EventQueueTimer { };
29
30 //
31 // OSXEventQueueBuffer
32 //
33
OSXEventQueueBuffer(IEventQueue * events)34 OSXEventQueueBuffer::OSXEventQueueBuffer(IEventQueue* events) :
35 m_event(NULL),
36 m_eventQueue(events),
37 m_carbonEventQueue(NULL)
38 {
39 // do nothing
40 }
41
~OSXEventQueueBuffer()42 OSXEventQueueBuffer::~OSXEventQueueBuffer()
43 {
44 // release the last event
45 if (m_event != NULL) {
46 ReleaseEvent(m_event);
47 }
48 }
49
50 void
init()51 OSXEventQueueBuffer::init()
52 {
53 m_carbonEventQueue = GetCurrentEventQueue();
54 }
55
56 void
waitForEvent(double timeout)57 OSXEventQueueBuffer::waitForEvent(double timeout)
58 {
59 EventRef event;
60 ReceiveNextEvent(0, NULL, timeout, false, &event);
61 }
62
63 IEventQueueBuffer::Type
getEvent(Event & event,UInt32 & dataID)64 OSXEventQueueBuffer::getEvent(Event& event, UInt32& dataID)
65 {
66 // release the previous event
67 if (m_event != NULL) {
68 ReleaseEvent(m_event);
69 m_event = NULL;
70 }
71
72 // get the next event
73 OSStatus error = ReceiveNextEvent(0, NULL, 0.0, true, &m_event);
74
75 // handle the event
76 if (error == eventLoopQuitErr) {
77 event = Event(Event::kQuit);
78 return kSystem;
79 }
80 else if (error != noErr) {
81 return kNone;
82 }
83 else {
84 UInt32 eventClass = GetEventClass(m_event);
85 switch (eventClass) {
86 case 'Syne':
87 dataID = GetEventKind(m_event);
88 return kUser;
89
90 default:
91 event = Event(Event::kSystem,
92 m_eventQueue->getSystemTarget(), &m_event);
93 return kSystem;
94 }
95 }
96 }
97
98 bool
addEvent(UInt32 dataID)99 OSXEventQueueBuffer::addEvent(UInt32 dataID)
100 {
101 EventRef event;
102 OSStatus error = CreateEvent(
103 kCFAllocatorDefault,
104 'Syne',
105 dataID,
106 0,
107 kEventAttributeNone,
108 &event);
109
110 if (error == noErr) {
111
112 assert(m_carbonEventQueue != NULL);
113
114 error = PostEventToQueue(
115 m_carbonEventQueue,
116 event,
117 kEventPriorityStandard);
118
119 ReleaseEvent(event);
120 }
121
122 return (error == noErr);
123 }
124
125 bool
isEmpty() const126 OSXEventQueueBuffer::isEmpty() const
127 {
128 EventRef event;
129 OSStatus status = ReceiveNextEvent(0, NULL, 0.0, false, &event);
130 return (status == eventLoopTimedOutErr);
131 }
132
133 EventQueueTimer*
newTimer(double,bool) const134 OSXEventQueueBuffer::newTimer(double, bool) const
135 {
136 return new EventQueueTimer;
137 }
138
139 void
deleteTimer(EventQueueTimer * timer) const140 OSXEventQueueBuffer::deleteTimer(EventQueueTimer* timer) const
141 {
142 delete timer;
143 }
144