Line data Source code
1 :
2 : /* Copyright (c) 2014-2016, Daniel Nachbaur <danielnachbaur@gmail.com>
3 : * Juan Hernando <jhernando@fi.upm.es>
4 : * Stefan.Eilemann@epfl.ch
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "eventHandler.h"
21 :
22 : #include "event.h"
23 : #include "window.h"
24 : #include <eq/fabric/keyEvent.h>
25 : #include <eq/fabric/sizeEvent.h>
26 :
27 : #include <QApplication>
28 : #include <QKeyEvent>
29 : #include <QThread>
30 :
31 : namespace eq
32 : {
33 : namespace qt
34 : {
35 : namespace
36 : {
37 0 : uint32_t _getKey(const QKeyEvent& keyEvent)
38 : {
39 0 : switch (keyEvent.key())
40 : {
41 : case Qt::Key_Escape:
42 0 : return KC_ESCAPE;
43 : case Qt::Key_Backspace:
44 0 : return KC_BACKSPACE;
45 : case Qt::Key_Return:
46 0 : return KC_RETURN;
47 : case Qt::Key_Tab:
48 0 : return KC_TAB;
49 : case Qt::Key_Home:
50 0 : return KC_HOME;
51 : case Qt::Key_Left:
52 0 : return KC_LEFT;
53 : case Qt::Key_Up:
54 0 : return KC_UP;
55 : case Qt::Key_Right:
56 0 : return KC_RIGHT;
57 : case Qt::Key_Down:
58 0 : return KC_DOWN;
59 : case Qt::Key_PageUp:
60 0 : return KC_PAGE_UP;
61 : case Qt::Key_PageDown:
62 0 : return KC_PAGE_DOWN;
63 : case Qt::Key_End:
64 0 : return KC_END;
65 : case Qt::Key_F1:
66 0 : return KC_F1;
67 : case Qt::Key_F2:
68 0 : return KC_F2;
69 : case Qt::Key_F3:
70 0 : return KC_F3;
71 : case Qt::Key_F4:
72 0 : return KC_F4;
73 : case Qt::Key_F5:
74 0 : return KC_F5;
75 : case Qt::Key_F6:
76 0 : return KC_F6;
77 : case Qt::Key_F7:
78 0 : return KC_F7;
79 : case Qt::Key_F8:
80 0 : return KC_F8;
81 : case Qt::Key_F9:
82 0 : return KC_F9;
83 : case Qt::Key_F10:
84 0 : return KC_F10;
85 : case Qt::Key_F11:
86 0 : return KC_F11;
87 : case Qt::Key_F12:
88 0 : return KC_F12;
89 : case Qt::Key_F13:
90 0 : return KC_F13;
91 : case Qt::Key_F14:
92 0 : return KC_F14;
93 : case Qt::Key_F15:
94 0 : return KC_F15;
95 : case Qt::Key_F16:
96 0 : return KC_F16;
97 : case Qt::Key_F17:
98 0 : return KC_F17;
99 : case Qt::Key_F18:
100 0 : return KC_F18;
101 : case Qt::Key_F19:
102 0 : return KC_F19;
103 : case Qt::Key_F20:
104 0 : return KC_F20;
105 : case Qt::Key_F21:
106 0 : return KC_F21;
107 : case Qt::Key_F22:
108 0 : return KC_F22;
109 : case Qt::Key_F23:
110 0 : return KC_F23;
111 : case Qt::Key_F24:
112 0 : return KC_F24;
113 : case Qt::Key_Shift:
114 0 : return KC_SHIFT_L;
115 : case Qt::Key_Control:
116 0 : return KC_CONTROL_L;
117 : case Qt::Key_Alt:
118 0 : return KC_ALT_L;
119 : case Qt::Key_AltGr:
120 0 : return KC_ALT_R;
121 : case Qt::Key_unknown:
122 0 : return KC_VOID;
123 : default:
124 0 : if (keyEvent.text().isEmpty())
125 0 : return KC_VOID;
126 0 : return keyEvent.text().at(0).unicode();
127 : }
128 : }
129 :
130 0 : KeyModifier _getKeyModifiers(const QInputEvent& event)
131 : {
132 0 : Qt::KeyboardModifiers modifiers = event.modifiers();
133 0 : KeyModifier result = KeyModifier::none;
134 0 : if (modifiers & Qt::AltModifier)
135 0 : result |= KeyModifier::alt;
136 0 : if (modifiers & Qt::ControlModifier)
137 0 : result |= KeyModifier::control;
138 0 : if (modifiers & Qt::ShiftModifier)
139 0 : result |= KeyModifier::shift;
140 0 : return result;
141 : }
142 :
143 : // Qt buttons 2 & 3 are inversed with EQ (X11/AGL/WGL)
144 0 : uint32_t _getButtons(const Qt::MouseButtons& eventButtons)
145 : {
146 0 : if ((eventButtons & (Qt::MidButton | Qt::RightButton)) ==
147 0 : (Qt::MidButton | Qt::RightButton))
148 : {
149 0 : return eventButtons;
150 : }
151 :
152 0 : uint32_t buttons = eventButtons;
153 0 : if (eventButtons & Qt::MidButton || eventButtons & Qt::RightButton)
154 0 : buttons ^= PTR_BUTTON2 | PTR_BUTTON3;
155 0 : return buttons;
156 : }
157 :
158 0 : uint32_t _getButton(const Qt::MouseButton button)
159 : {
160 0 : if (button == Qt::RightButton)
161 0 : return PTR_BUTTON2;
162 0 : if (button == Qt::MidButton)
163 0 : return PTR_BUTTON3;
164 0 : return button;
165 : }
166 :
167 : // Performs a (derived) copy of the incoming event. QApplication::postEvent()
168 : // takes ownership of the given event, and the incoming event is only valid
169 : // within the event function, it is destroyed afterwards by Qt.
170 0 : QEvent* _clone(const QEvent* event)
171 : {
172 0 : switch (event->type())
173 : {
174 : case QEvent::Close:
175 0 : return new QCloseEvent;
176 : case QEvent::Expose:
177 : {
178 0 : const QExposeEvent* e = static_cast<const QExposeEvent*>(event);
179 0 : return new QExposeEvent(e->region());
180 : }
181 : case QEvent::Hide:
182 0 : return new QHideEvent;
183 : case QEvent::Resize:
184 : {
185 0 : const QResizeEvent* e = static_cast<const QResizeEvent*>(event);
186 0 : return new QResizeEvent(e->size(), e->oldSize());
187 : }
188 : case QEvent::MouseMove:
189 : case QEvent::MouseButtonPress:
190 : case QEvent::MouseButtonRelease:
191 : {
192 0 : const QMouseEvent* e = static_cast<const QMouseEvent*>(event);
193 0 : return new QMouseEvent(e->type(), e->localPos(), e->windowPos(),
194 0 : e->screenPos(), e->button(), e->buttons(),
195 0 : e->modifiers());
196 : }
197 : case QEvent::Wheel:
198 : {
199 0 : const QWheelEvent* e = static_cast<const QWheelEvent*>(event);
200 0 : return new QWheelEvent(e->pos(), e->globalPos(), e->pixelDelta(),
201 0 : e->angleDelta(), e->delta(), e->orientation(),
202 0 : e->buttons(), e->modifiers(), e->phase()
203 : #if QT_VERSION >= 0x050500
204 : ,
205 : e->source()
206 : #endif
207 0 : );
208 : }
209 : case QEvent::KeyPress:
210 : case QEvent::KeyRelease:
211 : {
212 0 : const QKeyEvent* e = static_cast<const QKeyEvent*>(event);
213 0 : return new QKeyEvent(e->type(), e->key(), e->modifiers(),
214 0 : e->nativeScanCode(), e->nativeVirtualKey(),
215 0 : e->nativeModifiers(), e->text(), e->isAutoRepeat(),
216 0 : ushort(e->count()));
217 : }
218 : default:
219 0 : return nullptr;
220 : }
221 : }
222 : }
223 :
224 0 : EventHandler::EventHandler(WindowIF& window)
225 0 : : _window(window)
226 : {
227 0 : }
228 :
229 0 : EventHandler::~EventHandler()
230 : {
231 0 : }
232 :
233 0 : bool EventHandler::event(QEvent* qevent)
234 : {
235 0 : if (thread() != QThread::currentThread())
236 : {
237 : // Event did not arrive in the current thread, repost to correct thread.
238 0 : QEvent* clone = _clone(qevent);
239 0 : if (clone)
240 0 : QApplication::postEvent(this, clone);
241 : // else not cloned because unknown/not handled by us later (see below)
242 :
243 0 : return true;
244 : }
245 :
246 0 : return _processEvent(qevent);
247 : }
248 :
249 0 : bool EventHandler::_processEvent(QEvent* qEvent)
250 : {
251 0 : switch (qEvent->type())
252 : {
253 : case QEvent::Close:
254 0 : return _window.processEvent(EVENT_WINDOW_CLOSE, qEvent);
255 : case QEvent::Expose:
256 0 : return _window.processEvent(EVENT_WINDOW_EXPOSE, qEvent);
257 : case QEvent::Hide:
258 0 : return _window.processEvent(EVENT_WINDOW_HIDE, qEvent);
259 : case QEvent::Resize:
260 0 : return _processSizeEvent(EVENT_WINDOW_RESIZE, qEvent);
261 : case QEvent::MouseMove:
262 0 : return _processPointerEvent(EVENT_WINDOW_POINTER_MOTION, qEvent);
263 : case QEvent::MouseButtonPress:
264 0 : return _processPointerEvent(EVENT_WINDOW_POINTER_BUTTON_PRESS, qEvent);
265 : case QEvent::MouseButtonRelease:
266 : return _processPointerEvent(EVENT_WINDOW_POINTER_BUTTON_RELEASE,
267 0 : qEvent);
268 : #ifndef QT_NO_WHEELEVENT
269 : case QEvent::Wheel:
270 0 : return _processWheelEvent(qEvent);
271 : #endif
272 : case QEvent::KeyPress:
273 0 : return _processKeyEvent(EVENT_KEY_PRESS, qEvent);
274 : case QEvent::KeyRelease:
275 0 : return _processKeyEvent(EVENT_KEY_RELEASE, qEvent);
276 : default:
277 0 : return false;
278 : }
279 : }
280 :
281 0 : bool EventHandler::_processSizeEvent(const EventType type, QEvent* qev)
282 : {
283 0 : QResizeEvent* qevent = static_cast<QResizeEvent*>(qev);
284 0 : SizeEvent sizeEvent;
285 0 : sizeEvent.w = qevent->size().width();
286 0 : sizeEvent.h = qevent->size().height();
287 0 : return _window.processEvent(type, qev, sizeEvent);
288 : }
289 :
290 0 : bool EventHandler::_processPointerEvent(const EventType type, QEvent* qev)
291 : {
292 0 : QMouseEvent* qevent = static_cast<QMouseEvent*>(qev);
293 0 : PointerEvent pointerEvent;
294 0 : pointerEvent.x = qevent->x();
295 0 : pointerEvent.y = qevent->y();
296 0 : pointerEvent.buttons = _getButtons(qevent->buttons());
297 0 : pointerEvent.button = _getButton(qevent->button());
298 0 : pointerEvent.modifiers = _getKeyModifiers(*qevent);
299 0 : _computePointerDelta(type, pointerEvent);
300 0 : return _window.processEvent(type, qev, pointerEvent);
301 : }
302 :
303 : #ifndef QT_NO_WHEELEVENT
304 0 : bool EventHandler::_processWheelEvent(QEvent* qev)
305 : {
306 0 : QWheelEvent* qevent = static_cast<QWheelEvent*>(qev);
307 0 : PointerEvent pointerEvent;
308 0 : switch (qevent->orientation())
309 : {
310 : case Qt::Horizontal:
311 0 : pointerEvent.xAxis = qevent->delta() > 0 ? 1 : -1;
312 0 : break;
313 : case Qt::Vertical:
314 0 : pointerEvent.yAxis = qevent->delta() > 0 ? 1 : -1;
315 0 : break;
316 : }
317 0 : pointerEvent.buttons = _getButtons(qevent->buttons());
318 0 : pointerEvent.button = PTR_BUTTON_NONE;
319 0 : pointerEvent.modifiers = _getKeyModifiers(*qevent);
320 0 : return _window.processEvent(EVENT_WINDOW_POINTER_WHEEL, qev, pointerEvent);
321 : }
322 : #endif
323 :
324 0 : bool EventHandler::_processKeyEvent(const EventType type, QEvent* qev)
325 : {
326 0 : QKeyEvent* qevent = static_cast<QKeyEvent*>(qev);
327 0 : KeyEvent keyEvent;
328 0 : keyEvent.key = _getKey(*qevent);
329 0 : keyEvent.modifiers = _getKeyModifiers(*qevent);
330 0 : return _window.processEvent(type, qev, keyEvent);
331 : }
332 : }
333 30 : }
|