Line data Source code
1 :
2 : /* Copyright (c) 2013-2017, Daniel Nachbaur <daniel.nachbaur@epfl.ch>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #include "eventHandler.h"
19 : #include "proxy.h"
20 :
21 : #include "../channel.h"
22 : #include "../config.h"
23 : #include "../messagePump.h"
24 : #include "../pipe.h"
25 : #include "../window.h"
26 :
27 : #include <deflect/Stream.h>
28 : #include <eq/fabric/keyEvent.h>
29 : #include <eq/fabric/sizeEvent.h>
30 : #include <lunchbox/algorithm.h>
31 : #include <lunchbox/perThread.h>
32 :
33 : namespace eq
34 : {
35 : namespace deflect
36 : {
37 : namespace
38 : {
39 : typedef std::vector<EventHandler*> EventHandlers;
40 10 : static lunchbox::PerThread<EventHandlers> _eventHandlers;
41 :
42 : const float wheelFactor = 1.f / 40.f;
43 :
44 : // Values come from QtCore/qnamespace.h, but don't want to depend on Qt just for
45 : // that
46 0 : uint32_t _getKey(const int key)
47 : {
48 0 : switch (key)
49 : {
50 : case 0x01000000:
51 0 : return KC_ESCAPE;
52 : case 0x01000001:
53 0 : return KC_TAB;
54 : case 0x01000003:
55 0 : return KC_BACKSPACE;
56 : case 0x01000004:
57 0 : return KC_RETURN;
58 : case 0x01000010:
59 0 : return KC_HOME;
60 : case 0x01000011:
61 0 : return KC_END;
62 : case 0x01000012:
63 0 : return KC_LEFT;
64 : case 0x01000013:
65 0 : return KC_UP;
66 : case 0x01000014:
67 0 : return KC_RIGHT;
68 : case 0x01000015:
69 0 : return KC_DOWN;
70 : case 0x01000016:
71 0 : return KC_PAGE_UP;
72 : case 0x01000017:
73 0 : return KC_PAGE_DOWN;
74 : case 0x01000020:
75 0 : return KC_SHIFT_L;
76 : case 0x01000021:
77 0 : return KC_CONTROL_L;
78 : case 0x01000023:
79 0 : return KC_ALT_L;
80 : case 0x01000030:
81 0 : return KC_F1;
82 : case 0x01000031:
83 0 : return KC_F2;
84 : case 0x01000032:
85 0 : return KC_F3;
86 : case 0x01000033:
87 0 : return KC_F4;
88 : case 0x01000034:
89 0 : return KC_F5;
90 : case 0x01000035:
91 0 : return KC_F6;
92 : case 0x01000036:
93 0 : return KC_F7;
94 : case 0x01000037:
95 0 : return KC_F8;
96 : case 0x01000038:
97 0 : return KC_F9;
98 : case 0x01000039:
99 0 : return KC_F10;
100 : case 0x0100003a:
101 0 : return KC_F11;
102 : case 0x0100003b:
103 0 : return KC_F12;
104 : case 0x0100003c:
105 0 : return KC_F13;
106 : case 0x0100003d:
107 0 : return KC_F14;
108 : case 0x0100003e:
109 0 : return KC_F15;
110 : case 0x0100003f:
111 0 : return KC_F16;
112 : case 0x01000040:
113 0 : return KC_F17;
114 : case 0x01000041:
115 0 : return KC_F18;
116 : case 0x01000042:
117 0 : return KC_F19;
118 : case 0x01000043:
119 0 : return KC_F20;
120 : case 0x01000044:
121 0 : return KC_F21;
122 : case 0x01000045:
123 0 : return KC_F22;
124 : case 0x01000046:
125 0 : return KC_F23;
126 : case 0x01000047:
127 0 : return KC_F24;
128 : case 0x01001103:
129 0 : return KC_ALT_R;
130 : case 0x01ffffff:
131 0 : return KC_VOID;
132 : case 0x20:
133 0 : return key; // space
134 : default:
135 0 : return key + 32;
136 : }
137 : }
138 :
139 0 : uint32_t _getButtons(const ::deflect::Event& deflectEvent)
140 : {
141 0 : uint32_t buttons = 0;
142 0 : if (deflectEvent.mouseLeft)
143 0 : buttons |= PTR_BUTTON1;
144 0 : if (deflectEvent.mouseMiddle)
145 0 : buttons |= PTR_BUTTON2;
146 0 : if (deflectEvent.mouseRight)
147 0 : buttons |= PTR_BUTTON3;
148 0 : return buttons;
149 : }
150 : }
151 :
152 0 : EventHandler::EventHandler(Proxy* proxy)
153 0 : : _proxy(proxy)
154 : {
155 0 : LBASSERT(proxy);
156 :
157 0 : if (!_eventHandlers)
158 0 : _eventHandlers = new EventHandlers;
159 0 : _eventHandlers->push_back(this);
160 :
161 0 : Pipe* pipe = proxy->getChannel().getPipe();
162 0 : MessagePump* messagePump = pipe->isThreaded()
163 0 : ? pipe->getMessagePump()
164 0 : : pipe->getConfig()->getMessagePump();
165 0 : if (messagePump)
166 0 : messagePump->register_(proxy);
167 : else
168 0 : LBINFO << "Using deflect::EventHandler without MessagePump, "
169 0 : << "external event dispatch assumed" << std::endl;
170 0 : }
171 :
172 0 : EventHandler::~EventHandler()
173 : {
174 0 : Pipe* pipe = _proxy->getChannel().getPipe();
175 : MessagePump* messagePump = dynamic_cast<MessagePump*>(
176 0 : pipe->isThreaded() ? pipe->getMessagePump()
177 0 : : pipe->getConfig()->getMessagePump());
178 0 : if (messagePump)
179 0 : messagePump->deregister(_proxy);
180 :
181 0 : EventHandlers::iterator i = lunchbox::find(*_eventHandlers, this);
182 0 : LBASSERT(i != _eventHandlers->end());
183 0 : _eventHandlers->erase(i);
184 0 : if (_eventHandlers->empty())
185 : {
186 0 : delete _eventHandlers.get();
187 0 : _eventHandlers = 0;
188 : }
189 0 : }
190 :
191 7014 : void EventHandler::processEvents(const Proxy* proxy)
192 : {
193 7014 : if (!_eventHandlers)
194 7014 : return;
195 :
196 0 : for (EventHandler* handler : *_eventHandlers)
197 0 : handler->_processEvents(proxy);
198 : }
199 :
200 0 : void EventHandler::_processEvents(const Proxy* proxy)
201 : {
202 0 : LB_TS_THREAD(_thread);
203 0 : if (!_proxy || (proxy && _proxy != proxy))
204 0 : return;
205 :
206 0 : Channel& channel = _proxy->getChannel();
207 0 : const PixelViewport& pvp = channel.getPixelViewport();
208 0 : Window* window = channel.getWindow();
209 :
210 0 : while (_proxy->hasNewEvent())
211 : {
212 0 : const ::deflect::Event deflectEvent = _proxy->getEvent();
213 0 : const float x = deflectEvent.mouseX * pvp.w;
214 0 : const float y = deflectEvent.mouseY * pvp.h;
215 :
216 0 : switch (deflectEvent.type)
217 : {
218 : case ::deflect::Event::EVT_CLOSE:
219 0 : _proxy->stopRunning();
220 0 : window->processEvent(EVENT_EXIT);
221 0 : return;
222 :
223 : case ::deflect::Event::EVT_KEY_PRESS:
224 : case ::deflect::Event::EVT_KEY_RELEASE:
225 : {
226 0 : KeyEvent event;
227 : const EventType type =
228 0 : deflectEvent.type == ::deflect::Event::EVT_KEY_PRESS
229 0 : ? EVENT_KEY_PRESS
230 0 : : EVENT_KEY_RELEASE;
231 0 : event.key = _getKey(deflectEvent.key);
232 0 : channel.processEvent(type, event);
233 0 : break;
234 : }
235 : case ::deflect::Event::EVT_PRESS:
236 : case ::deflect::Event::EVT_RELEASE:
237 : {
238 0 : PointerEvent event;
239 : const EventType type =
240 0 : deflectEvent.type == ::deflect::Event::EVT_PRESS
241 0 : ? EVENT_CHANNEL_POINTER_BUTTON_PRESS
242 0 : : EVENT_CHANNEL_POINTER_BUTTON_RELEASE;
243 0 : event.x = x;
244 0 : event.y = y;
245 0 : event.buttons = _getButtons(deflectEvent);
246 0 : event.button = event.buttons;
247 0 : _computePointerDelta(type, event);
248 :
249 0 : channel.processEvent(type, event);
250 0 : break;
251 : }
252 : case ::deflect::Event::EVT_MOVE:
253 : case ::deflect::Event::EVT_PAN:
254 : {
255 0 : PointerEvent event;
256 0 : event.x = x;
257 0 : event.y = y;
258 0 : event.dx = deflectEvent.dx * pvp.w;
259 0 : event.dy = deflectEvent.dy * pvp.h;
260 :
261 0 : if (deflectEvent.type == ::deflect::Event::EVT_PAN)
262 0 : event.buttons = PTR_BUTTON3;
263 : else
264 0 : event.buttons = _getButtons(deflectEvent);
265 0 : event.button = event.buttons;
266 :
267 0 : channel.processEvent(EVENT_CHANNEL_POINTER_MOTION, event);
268 0 : break;
269 : }
270 : case ::deflect::Event::EVT_WHEEL:
271 : {
272 0 : PointerEvent event;
273 0 : event.x = x;
274 0 : event.y = pvp.h - y;
275 0 : event.xAxis = deflectEvent.dx * wheelFactor;
276 0 : event.yAxis = deflectEvent.dy * wheelFactor;
277 0 : event.dx = -deflectEvent.dx;
278 0 : event.dy = -deflectEvent.dy;
279 :
280 0 : channel.processEvent(EVENT_CHANNEL_POINTER_WHEEL, event);
281 0 : break;
282 : }
283 : case ::deflect::Event::EVT_PINCH:
284 : {
285 0 : PointerEvent event;
286 0 : event.x = x;
287 0 : event.y = pvp.h - y;
288 0 : const auto dx = deflectEvent.dx * pvp.w;
289 0 : const auto dy = deflectEvent.dy * pvp.h;
290 0 : const auto sign = dx + dy;
291 0 : const auto zoom = std::copysign(std::sqrt(dx * dx + dy * dy), sign);
292 0 : event.xAxis = 0.f;
293 0 : event.yAxis = zoom * wheelFactor;
294 :
295 0 : channel.processEvent(EVENT_CHANNEL_POINTER_WHEEL, event);
296 0 : break;
297 : }
298 :
299 : case ::deflect::Event::EVT_DOUBLECLICK:
300 : case ::deflect::Event::EVT_NONE:
301 : default:
302 0 : break;
303 : }
304 : }
305 : }
306 : }
307 30 : }
|