Fix no-xkb build
[profile/ivi/qtwayland.git] / src / plugins / platforms / wayland / qwaylandinputdevice.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qwaylandinputdevice.h"
43
44 #include "qwaylandintegration.h"
45 #include "qwaylandwindow.h"
46 #include "qwaylandbuffer.h"
47 #include "qwaylanddatadevicemanager.h"
48 #include "qwaylandtouch.h"
49
50 #include <QtGui/private/qpixmap_raster_p.h>
51 #include <qpa/qplatformwindow.h>
52 #include <QDebug>
53
54 #include <unistd.h>
55 #include <fcntl.h>
56
57 #include <QtGui/QGuiApplication>
58
59 #ifndef QT_NO_WAYLAND_XKB
60 #include <xkbcommon/xkbcommon.h>
61 #include <X11/keysym.h>
62 #endif
63
64 QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id)
65     : mQDisplay(display)
66     , mDisplay(display->wl_display())
67     , mCaps(0)
68     , mTransferDevice(0)
69     , mPointerFocus(0)
70     , mKeyboardFocus(0)
71     , mTouchFocus(0)
72     , mButtons(0)
73     , mTouchDevice(0)
74     #ifndef QT_NO_WAYLAND_XKB
75     , mXkbContext(0)
76     , mXkbMap(0)
77     , mXkbState(0)
78     #endif
79 {
80     mSeat = static_cast<struct wl_seat *>(wl_display_bind(mDisplay, id, &wl_seat_interface));
81     wl_seat_add_listener(mSeat, &seatListener, this);
82     wl_seat_set_user_data(mSeat, this);
83
84 #ifndef QT_NO_WAYLAND_XKB
85     xkb_rule_names names;
86     names.rules = strdup("evdev");
87     names.model = strdup("pc105");
88     names.layout = strdup("us");
89     names.variant = strdup("");
90     names.options = strdup("");
91
92     xkb_context *mXkbContext = xkb_context_new(xkb_context_flags(0));
93     if (mXkbContext) {
94         mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0));
95         if (mXkbMap) {
96             mXkbState = xkb_state_new(mXkbMap);
97         }
98     }
99
100     if (!mXkbContext || !mXkbMap || !mXkbState)
101         qWarning() << "xkb_map_new_from_names failed, no key input";
102 #endif
103
104     if (mQDisplay->dndSelectionHandler()) {
105         mTransferDevice = mQDisplay->dndSelectionHandler()->getDataDevice(this);
106     }
107 }
108
109 QWaylandInputDevice::~QWaylandInputDevice()
110 {
111 #ifndef QT_NO_WAYLAND_XKB
112     if (mXkbState)
113         xkb_state_unref(mXkbState);
114     if (mXkbMap)
115         xkb_map_unref(mXkbMap);
116     if (mXkbContext)
117         xkb_context_unref(mXkbContext);
118 #endif
119 }
120
121 const struct wl_seat_listener QWaylandInputDevice::seatListener = {
122     QWaylandInputDevice::seat_capabilities
123 };
124
125 const struct wl_pointer_listener QWaylandInputDevice::pointerListener = {
126     QWaylandInputDevice::pointer_enter,
127     QWaylandInputDevice::pointer_leave,
128     QWaylandInputDevice::pointer_motion,
129     QWaylandInputDevice::pointer_button,
130     QWaylandInputDevice::pointer_axis
131 };
132
133 const struct wl_keyboard_listener QWaylandInputDevice::keyboardListener = {
134     QWaylandInputDevice::keyboard_enter,
135     QWaylandInputDevice::keyboard_leave,
136     QWaylandInputDevice::keyboard_key
137 };
138
139 const struct wl_touch_listener QWaylandInputDevice::touchListener = {
140     QWaylandInputDevice::touch_down,
141     QWaylandInputDevice::touch_up,
142     QWaylandInputDevice::touch_motion,
143     QWaylandInputDevice::touch_frame,
144     QWaylandInputDevice::touch_cancel
145 };
146
147 void QWaylandInputDevice::seat_capabilities(void *data, struct wl_seat *seat, uint32_t caps)
148 {
149     QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data);
150     self->mCaps = caps;
151
152     if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
153         self->mDeviceInterfaces.keyboard = wl_seat_get_keyboard(seat);
154         wl_keyboard_add_listener(self->mDeviceInterfaces.keyboard, &keyboardListener, self);
155     }
156
157     if (caps & WL_SEAT_CAPABILITY_POINTER) {
158         self->mDeviceInterfaces.pointer = wl_seat_get_pointer(seat);
159         wl_pointer_add_listener(self->mDeviceInterfaces.pointer, &pointerListener, self);
160     }
161
162     if (caps & WL_SEAT_CAPABILITY_TOUCH) {
163         self->mDeviceInterfaces.touch = wl_seat_get_touch(seat);
164         wl_touch_add_listener(self->mDeviceInterfaces.touch, &touchListener, self);
165
166         if (!self->mTouchDevice) {
167             self->mTouchDevice = new QTouchDevice;
168             self->mTouchDevice->setType(QTouchDevice::TouchScreen);
169             self->mTouchDevice->setCapabilities(QTouchDevice::Position);
170             QWindowSystemInterface::registerTouchDevice(self->mTouchDevice);
171         }
172     }
173 }
174
175 void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
176 {
177     if (window == mPointerFocus)
178         mPointerFocus = 0;
179     if (window == mKeyboardFocus)
180         mKeyboardFocus = 0;
181 }
182
183 void QWaylandInputDevice::setTransferDevice(struct wl_data_device *device)
184 {
185     mTransferDevice =  device;
186 }
187
188 struct wl_data_device *QWaylandInputDevice::transferDevice() const
189 {
190     Q_ASSERT(mTransferDevice);
191     return mTransferDevice;
192 }
193
194 void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button)
195 {
196     mButtons = mButtons & !button;
197 }
198
199 void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
200 {
201     if (mCaps & WL_SEAT_CAPABILITY_POINTER)
202         wl_pointer_attach(mDeviceInterfaces.pointer, mTime, buffer->buffer(), x, y);
203 }
204
205 void QWaylandInputDevice::pointer_enter(void *data,
206                                         struct wl_pointer *pointer,
207                                         uint32_t time, struct wl_surface *surface,
208                                         wl_fixed_t sx, wl_fixed_t sy)
209 {
210     Q_UNUSED(pointer);
211     Q_UNUSED(sx);
212     Q_UNUSED(sy);
213     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
214
215     if (!surface)
216         return;
217
218     QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface);
219     window->handleMouseEnter();
220     inputDevice->mPointerFocus = window;
221
222     inputDevice->mTime = time;
223 }
224
225 void QWaylandInputDevice::pointer_leave(void *data,
226                                         struct wl_pointer *pointer,
227                                         uint32_t time, struct wl_surface *surface)
228 {
229     Q_UNUSED(pointer);
230     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
231
232     // The event may arrive after destroying the window, indicated by
233     // a null surface.
234     if (!surface)
235         return;
236
237     QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface);
238     window->handleMouseLeave();
239     inputDevice->mPointerFocus = 0;
240     inputDevice->mButtons = Qt::NoButton;
241
242     inputDevice->mTime = time;
243 }
244
245 void QWaylandInputDevice::pointer_motion(void *data,
246                                          struct wl_pointer *pointer,
247                                          uint32_t time,
248                                          wl_fixed_t surface_x, wl_fixed_t surface_y)
249 {
250     Q_UNUSED(pointer);
251     Q_UNUSED(surface_x);
252     Q_UNUSED(surface_y);
253     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
254     QWaylandWindow *window = inputDevice->mPointerFocus;
255
256     if (window == NULL) {
257         // We destroyed the pointer focus surface, but the server
258         // didn't get the message yet.
259         return;
260     }
261
262     QPointF pos(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y));
263     QPointF delta = pos - pos.toPoint();
264     QPointF global = window->window()->mapToGlobal(pos.toPoint());
265     global += delta;
266
267     inputDevice->mSurfacePos = pos;
268     inputDevice->mGlobalPos = global;
269     inputDevice->mTime = time;
270
271     window->handleMouse(inputDevice,
272                         time,
273                         inputDevice->mSurfacePos,
274                         inputDevice->mGlobalPos,
275                         inputDevice->mButtons,
276                         Qt::NoModifier);
277 }
278
279 void QWaylandInputDevice::pointer_button(void *data,
280                                          struct wl_pointer *pointer,
281                                          uint32_t serial, uint32_t time,
282                                          uint32_t button, uint32_t state)
283 {
284     Q_UNUSED(pointer);
285     Q_UNUSED(serial);
286     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
287     QWaylandWindow *window = inputDevice->mPointerFocus;
288     Qt::MouseButton qt_button;
289
290
291     // translate from kernel (input.h) 'button' to corresponding Qt:MouseButton.
292     // The range of mouse values is 0x110 <= mouse_button < 0x120, the first Joystick button.
293     switch (button) {
294     case 0x110: qt_button = Qt::LeftButton; break;    // kernel BTN_LEFT
295     case 0x111: qt_button = Qt::RightButton; break;
296     case 0x112: qt_button = Qt::MiddleButton; break;
297     case 0x113: qt_button = Qt::ExtraButton1; break;  // AKA Qt::BackButton
298     case 0x114: qt_button = Qt::ExtraButton2; break;  // AKA Qt::ForwardButton
299     case 0x115: qt_button = Qt::ExtraButton3; break;  // AKA Qt::TaskButton
300     case 0x116: qt_button = Qt::ExtraButton4; break;
301     case 0x117: qt_button = Qt::ExtraButton5; break;
302     case 0x118: qt_button = Qt::ExtraButton6; break;
303     case 0x119: qt_button = Qt::ExtraButton7; break;
304     case 0x11a: qt_button = Qt::ExtraButton8; break;
305     case 0x11b: qt_button = Qt::ExtraButton9; break;
306     case 0x11c: qt_button = Qt::ExtraButton10; break;
307     case 0x11d: qt_button = Qt::ExtraButton11; break;
308     case 0x11e: qt_button = Qt::ExtraButton12; break;
309     case 0x11f: qt_button = Qt::ExtraButton13; break;
310     default: return; // invalid button number (as far as Qt is concerned)
311     }
312
313     if (state)
314         inputDevice->mButtons |= qt_button;
315     else
316         inputDevice->mButtons &= ~qt_button;
317
318     inputDevice->mTime = time;
319
320     if (window) {
321         window->handleMouse(inputDevice,
322                             time,
323                             inputDevice->mSurfacePos,
324                             inputDevice->mGlobalPos,
325                             inputDevice->mButtons,
326                             Qt::NoModifier);
327     }
328 }
329
330 void QWaylandInputDevice::pointer_axis(void *data,
331                                        struct wl_pointer *pointer,
332                                        uint32_t time,
333                                        uint32_t axis,
334                                        int32_t value)
335 {
336     Q_UNUSED(pointer);
337     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
338     QWaylandWindow *window = inputDevice->mPointerFocus;
339     Qt::Orientation orientation = axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL ? Qt::Horizontal
340                                                                             : Qt::Vertical;
341     QWindowSystemInterface::handleWheelEvent(window->window(),
342                                              time,
343                                              inputDevice->mSurfacePos,
344                                              inputDevice->mGlobalPos,
345                                              value * 120,
346                                              orientation);
347 }
348
349 #ifndef QT_NO_WAYLAND_XKB
350
351 static Qt::KeyboardModifiers translateModifiers(xkb_state *state)
352 {
353     Qt::KeyboardModifiers ret = Qt::NoModifier;
354     xkb_state_component cstate = xkb_state_component(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED);
355
356     if (xkb_state_mod_name_is_active(state, "Shift", cstate))
357         ret |= Qt::ShiftModifier;
358     if (xkb_state_mod_name_is_active(state, "Control", cstate))
359         ret |= Qt::ControlModifier;
360     if (xkb_state_mod_name_is_active(state, "Alt", cstate))
361         ret |= Qt::AltModifier;
362     if (xkb_state_mod_name_is_active(state, "Mod1", cstate))
363         ret |= Qt::AltModifier;
364     if (xkb_state_mod_name_is_active(state, "Mod4", cstate))
365         ret |= Qt::MetaModifier;
366
367     return ret;
368 }
369
370 static const uint32_t KeyTbl[] = {
371     XK_Escape,                  Qt::Key_Escape,
372     XK_Tab,                     Qt::Key_Tab,
373     XK_ISO_Left_Tab,            Qt::Key_Backtab,
374     XK_BackSpace,               Qt::Key_Backspace,
375     XK_Return,                  Qt::Key_Return,
376     XK_Insert,                  Qt::Key_Insert,
377     XK_Delete,                  Qt::Key_Delete,
378     XK_Clear,                   Qt::Key_Delete,
379     XK_Pause,                   Qt::Key_Pause,
380     XK_Print,                   Qt::Key_Print,
381
382     XK_Home,                    Qt::Key_Home,
383     XK_End,                     Qt::Key_End,
384     XK_Left,                    Qt::Key_Left,
385     XK_Up,                      Qt::Key_Up,
386     XK_Right,                   Qt::Key_Right,
387     XK_Down,                    Qt::Key_Down,
388     XK_Prior,                   Qt::Key_PageUp,
389     XK_Next,                    Qt::Key_PageDown,
390
391     XK_Shift_L,                 Qt::Key_Shift,
392     XK_Shift_R,                 Qt::Key_Shift,
393     XK_Shift_Lock,              Qt::Key_Shift,
394     XK_Control_L,               Qt::Key_Control,
395     XK_Control_R,               Qt::Key_Control,
396     XK_Meta_L,                  Qt::Key_Meta,
397     XK_Meta_R,                  Qt::Key_Meta,
398     XK_Alt_L,                   Qt::Key_Alt,
399     XK_Alt_R,                   Qt::Key_Alt,
400     XK_Caps_Lock,               Qt::Key_CapsLock,
401     XK_Num_Lock,                Qt::Key_NumLock,
402     XK_Scroll_Lock,             Qt::Key_ScrollLock,
403     XK_Super_L,                 Qt::Key_Super_L,
404     XK_Super_R,                 Qt::Key_Super_R,
405     XK_Menu,                    Qt::Key_Menu,
406     XK_Hyper_L,                 Qt::Key_Hyper_L,
407     XK_Hyper_R,                 Qt::Key_Hyper_R,
408     XK_Help,                    Qt::Key_Help,
409
410     XK_KP_Space,                Qt::Key_Space,
411     XK_KP_Tab,                  Qt::Key_Tab,
412     XK_KP_Enter,                Qt::Key_Enter,
413     XK_KP_Home,                 Qt::Key_Home,
414     XK_KP_Left,                 Qt::Key_Left,
415     XK_KP_Up,                   Qt::Key_Up,
416     XK_KP_Right,                Qt::Key_Right,
417     XK_KP_Down,                 Qt::Key_Down,
418     XK_KP_Prior,                Qt::Key_PageUp,
419     XK_KP_Next,                 Qt::Key_PageDown,
420     XK_KP_End,                  Qt::Key_End,
421     XK_KP_Begin,                Qt::Key_Clear,
422     XK_KP_Insert,               Qt::Key_Insert,
423     XK_KP_Delete,               Qt::Key_Delete,
424     XK_KP_Equal,                Qt::Key_Equal,
425     XK_KP_Multiply,             Qt::Key_Asterisk,
426     XK_KP_Add,                  Qt::Key_Plus,
427     XK_KP_Separator,            Qt::Key_Comma,
428     XK_KP_Subtract,             Qt::Key_Minus,
429     XK_KP_Decimal,              Qt::Key_Period,
430     XK_KP_Divide,               Qt::Key_Slash,
431
432     XK_ISO_Level3_Shift,        Qt::Key_AltGr,
433     XK_Multi_key,               Qt::Key_Multi_key,
434     XK_Codeinput,               Qt::Key_Codeinput,
435     XK_SingleCandidate,         Qt::Key_SingleCandidate,
436     XK_MultipleCandidate,       Qt::Key_MultipleCandidate,
437     XK_PreviousCandidate,       Qt::Key_PreviousCandidate,
438
439     XK_Mode_switch,             Qt::Key_Mode_switch,
440     XK_script_switch,           Qt::Key_Mode_switch,
441
442     0,                          0
443 };
444
445 static uint32_t translateKey(uint32_t sym, char *string, size_t size)
446 {
447     Q_UNUSED(size);
448     string[0] = '\0';
449
450     int code = -1;
451     for (int i = 0; KeyTbl[i]; i += 2) {
452         if (sym == KeyTbl[i]) {
453             code = KeyTbl[i + 1];
454             break;
455         }
456     }
457     if (code == -1) {
458         string[0] = sym;
459         string[1] = '\0';
460         return toupper(sym);
461     }
462     return code;
463 }
464
465 #endif // QT_NO_WAYLAND_XKB
466
467 void QWaylandInputDevice::keyboard_enter(void *data,
468                                          struct wl_keyboard *keyboard,
469                                          uint32_t time,
470                                          struct wl_surface *surface,
471                                          struct wl_array *keys)
472 {
473     Q_UNUSED(keyboard);
474     Q_UNUSED(time);
475     Q_UNUSED(keys);
476
477     if (!surface)
478         return;
479
480     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
481     QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface);
482     inputDevice->mKeyboardFocus = window;
483     inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(inputDevice);
484     QWindowSystemInterface::handleWindowActivated(window->window());
485 }
486
487 void QWaylandInputDevice::keyboard_leave(void *data,
488                                          struct wl_keyboard *keyboard,
489                                          uint32_t time,
490                                          struct wl_surface *surface)
491 {
492     Q_UNUSED(keyboard);
493     Q_UNUSED(time);
494     Q_UNUSED(surface);
495
496     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
497     inputDevice->mKeyboardFocus = NULL;
498     inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(0);
499     QWindowSystemInterface::handleWindowActivated(0);
500 }
501
502 void QWaylandInputDevice::keyboard_key(void *data,
503                                        struct wl_keyboard *keyboard,
504                                        uint32_t serial, uint32_t time,
505                                        uint32_t key, uint32_t state)
506 {
507     Q_UNUSED(keyboard);
508     Q_UNUSED(serial);
509     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
510     QWaylandWindow *window = inputDevice->mKeyboardFocus;
511 #ifndef QT_NO_WAYLAND_XKB
512     uint32_t numSyms, code;
513     const xkb_keysym_t *syms;
514     Qt::KeyboardModifiers modifiers;
515     QEvent::Type type;
516     char s[2];
517
518     if (!inputDevice->mXkbMap)
519         return;
520
521     code = key + 8;
522     bool isDown = state != 0;
523     numSyms = xkb_key_get_syms(inputDevice->mXkbState, code, &syms);
524     xkb_state_update_key(inputDevice->mXkbState, code,
525                          isDown ? XKB_KEY_DOWN : XKB_KEY_UP);
526
527     if (!window) {
528         // We destroyed the keyboard focus surface, but the server
529         // didn't get the message yet.
530         return;
531     }
532
533     if (numSyms == 1) {
534         xkb_keysym_t sym = syms[0];
535         Qt::KeyboardModifiers modifiers = translateModifiers(inputDevice->mXkbState);
536         type = isDown ? QEvent::KeyPress : QEvent::KeyRelease;
537
538         sym = translateKey(sym, s, sizeof s);
539
540         if (window)
541             QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
542                                                            time, type, sym,
543                                                            modifiers,
544                                                            code, 0, 0,
545                                                            QString::fromLatin1(s));
546     }
547 #else
548     // Generic fallback for single hard keys: Assume 'key' is a Qt key code.
549     if (window) {
550         QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
551                                                        time, state ? QEvent::KeyPress : QEvent::KeyRelease,
552                                                        key + 8, // qt-compositor substracts 8 for some reason
553                                                        Qt::NoModifier,
554                                                        key + 8, 0, 0);
555     }
556 #endif
557 }
558
559 void QWaylandInputDevice::touch_down(void *data,
560                                      struct wl_touch *touch,
561                                      uint32_t serial,
562                                      uint32_t time,
563                                      struct wl_surface *surface,
564                                      int32_t id,
565                                      wl_fixed_t x,
566                                      wl_fixed_t y)
567 {
568     Q_UNUSED(touch);
569     Q_UNUSED(serial);
570     Q_UNUSED(time);
571     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
572     inputDevice->mTouchFocus = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface));
573     inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed);
574 }
575
576 void QWaylandInputDevice::touch_up(void *data,
577                                    struct wl_touch *touch,
578                                    uint32_t serial,
579                                    uint32_t time,
580                                    int32_t id)
581 {
582     Q_UNUSED(touch);
583     Q_UNUSED(serial);
584     Q_UNUSED(time);
585     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
586     inputDevice->mTouchFocus = 0;
587     inputDevice->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased);
588 }
589
590 void QWaylandInputDevice::touch_motion(void *data,
591                                        struct wl_touch *touch,
592                                        uint32_t time,
593                                        int32_t id,
594                                        wl_fixed_t x,
595                                        wl_fixed_t y)
596 {
597     Q_UNUSED(touch);
598     Q_UNUSED(time);
599     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
600     inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved);
601 }
602
603 void QWaylandInputDevice::touch_frame(void *data, struct wl_touch *touch)
604 {
605     Q_UNUSED(touch);
606     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
607     inputDevice->handleTouchFrame();
608 }
609
610 void QWaylandInputDevice::touch_cancel(void *data, struct wl_touch *touch)
611 {
612     Q_UNUSED(touch);
613     QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data);
614
615     self->mPrevTouchPoints.clear();
616     self->mTouchPoints.clear();
617
618     QWaylandTouchExtension *touchExt = self->mQDisplay->touchExtension();
619     if (touchExt)
620         touchExt->touchCanceled();
621
622     QWindowSystemInterface::handleTouchCancelEvent(0, self->mTouchDevice);
623 }
624
625 void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state)
626 {
627     QWindowSystemInterface::TouchPoint tp;
628
629     // Find out the coordinates for Released events.
630     bool coordsOk = false;
631     if (state == Qt::TouchPointReleased)
632         for (int i = 0; i < mPrevTouchPoints.count(); ++i)
633             if (mPrevTouchPoints.at(i).id == id) {
634                 tp.area = mPrevTouchPoints.at(i).area;
635                 coordsOk = true;
636                 break;
637             }
638
639     if (!coordsOk) {
640         // x and y are surface relative.
641         // We need a global (screen) position.
642         QWaylandWindow *win = mTouchFocus;
643
644         //is it possible that mTouchFocus is null;
645         if (!win)
646             win = mPointerFocus;
647         if (!win)
648             win = mKeyboardFocus;
649         if (!win || !win->window())
650             return;
651
652         tp.area = QRectF(0, 0, 8, 8);
653         QMargins margins = win->frameMargins();
654         tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x+margins.left(), y+margins.top())));
655     }
656
657     tp.state = state;
658     tp.id = id;
659     tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1;
660     mTouchPoints.append(tp);
661 }
662
663 void QWaylandInputDevice::handleTouchFrame()
664 {
665     // Copy all points, that are in the previous but not in the current list, as stationary.
666     for (int i = 0; i < mPrevTouchPoints.count(); ++i) {
667         const QWindowSystemInterface::TouchPoint &prevPoint(mPrevTouchPoints.at(i));
668         if (prevPoint.state == Qt::TouchPointReleased)
669             continue;
670         bool found = false;
671         for (int j = 0; j < mTouchPoints.count(); ++j)
672             if (mTouchPoints.at(j).id == prevPoint.id) {
673                 found = true;
674                 break;
675             }
676         if (!found) {
677             QWindowSystemInterface::TouchPoint p = prevPoint;
678             p.state = Qt::TouchPointStationary;
679             mTouchPoints.append(p);
680         }
681     }
682
683     if (mTouchPoints.isEmpty()) {
684         mPrevTouchPoints.clear();
685         return;
686     }
687
688     QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints);
689
690     bool allReleased = true;
691     for (int i = 0; i < mTouchPoints.count(); ++i)
692         if (mTouchPoints.at(i).state != Qt::TouchPointReleased) {
693             allReleased = false;
694             break;
695         }
696
697     mPrevTouchPoints = mTouchPoints;
698     mTouchPoints.clear();
699
700     if (allReleased) {
701         QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints);
702         mPrevTouchPoints.clear();
703     }
704 }