Bump sha
[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_keymap,
135     QWaylandInputDevice::keyboard_enter,
136     QWaylandInputDevice::keyboard_leave,
137     QWaylandInputDevice::keyboard_key,
138     QWaylandInputDevice::keyboard_modifiers
139 };
140
141 const struct wl_touch_listener QWaylandInputDevice::touchListener = {
142     QWaylandInputDevice::touch_down,
143     QWaylandInputDevice::touch_up,
144     QWaylandInputDevice::touch_motion,
145     QWaylandInputDevice::touch_frame,
146     QWaylandInputDevice::touch_cancel
147 };
148
149 void QWaylandInputDevice::seat_capabilities(void *data, struct wl_seat *seat, uint32_t caps)
150 {
151     QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data);
152     self->mCaps = caps;
153
154     if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
155         self->mDeviceInterfaces.keyboard = wl_seat_get_keyboard(seat);
156         wl_keyboard_add_listener(self->mDeviceInterfaces.keyboard, &keyboardListener, self);
157     }
158
159     if (caps & WL_SEAT_CAPABILITY_POINTER) {
160         self->mDeviceInterfaces.pointer = wl_seat_get_pointer(seat);
161         wl_pointer_add_listener(self->mDeviceInterfaces.pointer, &pointerListener, self);
162     }
163
164     if (caps & WL_SEAT_CAPABILITY_TOUCH) {
165         self->mDeviceInterfaces.touch = wl_seat_get_touch(seat);
166         wl_touch_add_listener(self->mDeviceInterfaces.touch, &touchListener, self);
167
168         if (!self->mTouchDevice) {
169             self->mTouchDevice = new QTouchDevice;
170             self->mTouchDevice->setType(QTouchDevice::TouchScreen);
171             self->mTouchDevice->setCapabilities(QTouchDevice::Position);
172             QWindowSystemInterface::registerTouchDevice(self->mTouchDevice);
173         }
174     }
175 }
176
177 void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
178 {
179     if (window == mPointerFocus)
180         mPointerFocus = 0;
181     if (window == mKeyboardFocus)
182         mKeyboardFocus = 0;
183 }
184
185 void QWaylandInputDevice::setTransferDevice(struct wl_data_device *device)
186 {
187     mTransferDevice =  device;
188 }
189
190 struct wl_data_device *QWaylandInputDevice::transferDevice() const
191 {
192     Q_ASSERT(mTransferDevice);
193     return mTransferDevice;
194 }
195
196 void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button)
197 {
198     mButtons = mButtons & !button;
199 }
200
201 void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
202 {
203     if (mCaps & WL_SEAT_CAPABILITY_POINTER)
204         wl_pointer_attach(mDeviceInterfaces.pointer, mTime, buffer->buffer(), x, y);
205 }
206
207 void QWaylandInputDevice::pointer_enter(void *data,
208                                         struct wl_pointer *pointer,
209                                         uint32_t time, struct wl_surface *surface,
210                                         wl_fixed_t sx, wl_fixed_t sy)
211 {
212     Q_UNUSED(pointer);
213     Q_UNUSED(sx);
214     Q_UNUSED(sy);
215     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
216
217     if (!surface)
218         return;
219
220     QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface);
221     window->handleMouseEnter();
222     inputDevice->mPointerFocus = window;
223
224     inputDevice->mTime = time;
225 }
226
227 void QWaylandInputDevice::pointer_leave(void *data,
228                                         struct wl_pointer *pointer,
229                                         uint32_t time, struct wl_surface *surface)
230 {
231     Q_UNUSED(pointer);
232     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
233
234     // The event may arrive after destroying the window, indicated by
235     // a null surface.
236     if (!surface)
237         return;
238
239     QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface);
240     window->handleMouseLeave();
241     inputDevice->mPointerFocus = 0;
242     inputDevice->mButtons = Qt::NoButton;
243
244     inputDevice->mTime = time;
245 }
246
247 void QWaylandInputDevice::pointer_motion(void *data,
248                                          struct wl_pointer *pointer,
249                                          uint32_t time,
250                                          wl_fixed_t surface_x, wl_fixed_t surface_y)
251 {
252     Q_UNUSED(pointer);
253     Q_UNUSED(surface_x);
254     Q_UNUSED(surface_y);
255     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
256     QWaylandWindow *window = inputDevice->mPointerFocus;
257
258     if (window == NULL) {
259         // We destroyed the pointer focus surface, but the server
260         // didn't get the message yet.
261         return;
262     }
263
264     QPointF pos(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y));
265     QPointF delta = pos - pos.toPoint();
266     QPointF global = window->window()->mapToGlobal(pos.toPoint());
267     global += delta;
268
269     inputDevice->mSurfacePos = pos;
270     inputDevice->mGlobalPos = global;
271     inputDevice->mTime = time;
272
273     window->handleMouse(inputDevice,
274                         time,
275                         inputDevice->mSurfacePos,
276                         inputDevice->mGlobalPos,
277                         inputDevice->mButtons,
278                         Qt::NoModifier);
279 }
280
281 void QWaylandInputDevice::pointer_button(void *data,
282                                          struct wl_pointer *pointer,
283                                          uint32_t serial, uint32_t time,
284                                          uint32_t button, uint32_t state)
285 {
286     Q_UNUSED(pointer);
287     Q_UNUSED(serial);
288     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
289     QWaylandWindow *window = inputDevice->mPointerFocus;
290     Qt::MouseButton qt_button;
291
292
293     // translate from kernel (input.h) 'button' to corresponding Qt:MouseButton.
294     // The range of mouse values is 0x110 <= mouse_button < 0x120, the first Joystick button.
295     switch (button) {
296     case 0x110: qt_button = Qt::LeftButton; break;    // kernel BTN_LEFT
297     case 0x111: qt_button = Qt::RightButton; break;
298     case 0x112: qt_button = Qt::MiddleButton; break;
299     case 0x113: qt_button = Qt::ExtraButton1; break;  // AKA Qt::BackButton
300     case 0x114: qt_button = Qt::ExtraButton2; break;  // AKA Qt::ForwardButton
301     case 0x115: qt_button = Qt::ExtraButton3; break;  // AKA Qt::TaskButton
302     case 0x116: qt_button = Qt::ExtraButton4; break;
303     case 0x117: qt_button = Qt::ExtraButton5; break;
304     case 0x118: qt_button = Qt::ExtraButton6; break;
305     case 0x119: qt_button = Qt::ExtraButton7; break;
306     case 0x11a: qt_button = Qt::ExtraButton8; break;
307     case 0x11b: qt_button = Qt::ExtraButton9; break;
308     case 0x11c: qt_button = Qt::ExtraButton10; break;
309     case 0x11d: qt_button = Qt::ExtraButton11; break;
310     case 0x11e: qt_button = Qt::ExtraButton12; break;
311     case 0x11f: qt_button = Qt::ExtraButton13; break;
312     default: return; // invalid button number (as far as Qt is concerned)
313     }
314
315     if (state)
316         inputDevice->mButtons |= qt_button;
317     else
318         inputDevice->mButtons &= ~qt_button;
319
320     inputDevice->mTime = time;
321
322     if (window) {
323         window->handleMouse(inputDevice,
324                             time,
325                             inputDevice->mSurfacePos,
326                             inputDevice->mGlobalPos,
327                             inputDevice->mButtons,
328                             Qt::NoModifier);
329     }
330 }
331
332 void QWaylandInputDevice::pointer_axis(void *data,
333                                        struct wl_pointer *pointer,
334                                        uint32_t time,
335                                        uint32_t axis,
336                                        int32_t value)
337 {
338     Q_UNUSED(pointer);
339     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
340     QWaylandWindow *window = inputDevice->mPointerFocus;
341     Qt::Orientation orientation = axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL ? Qt::Horizontal
342                                                                             : Qt::Vertical;
343     QWindowSystemInterface::handleWheelEvent(window->window(),
344                                              time,
345                                              inputDevice->mSurfacePos,
346                                              inputDevice->mGlobalPos,
347                                              int(wl_fixed_to_double(value) * 120.0),
348                                              orientation);
349 }
350
351 #ifndef QT_NO_WAYLAND_XKB
352
353 static Qt::KeyboardModifiers translateModifiers(xkb_state *state)
354 {
355     Qt::KeyboardModifiers ret = Qt::NoModifier;
356     xkb_state_component cstate = xkb_state_component(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED);
357
358     if (xkb_state_mod_name_is_active(state, "Shift", cstate))
359         ret |= Qt::ShiftModifier;
360     if (xkb_state_mod_name_is_active(state, "Control", cstate))
361         ret |= Qt::ControlModifier;
362     if (xkb_state_mod_name_is_active(state, "Alt", cstate))
363         ret |= Qt::AltModifier;
364     if (xkb_state_mod_name_is_active(state, "Mod1", cstate))
365         ret |= Qt::AltModifier;
366     if (xkb_state_mod_name_is_active(state, "Mod4", cstate))
367         ret |= Qt::MetaModifier;
368
369     return ret;
370 }
371
372 static const uint32_t KeyTbl[] = {
373     XK_Escape,                  Qt::Key_Escape,
374     XK_Tab,                     Qt::Key_Tab,
375     XK_ISO_Left_Tab,            Qt::Key_Backtab,
376     XK_BackSpace,               Qt::Key_Backspace,
377     XK_Return,                  Qt::Key_Return,
378     XK_Insert,                  Qt::Key_Insert,
379     XK_Delete,                  Qt::Key_Delete,
380     XK_Clear,                   Qt::Key_Delete,
381     XK_Pause,                   Qt::Key_Pause,
382     XK_Print,                   Qt::Key_Print,
383
384     XK_Home,                    Qt::Key_Home,
385     XK_End,                     Qt::Key_End,
386     XK_Left,                    Qt::Key_Left,
387     XK_Up,                      Qt::Key_Up,
388     XK_Right,                   Qt::Key_Right,
389     XK_Down,                    Qt::Key_Down,
390     XK_Prior,                   Qt::Key_PageUp,
391     XK_Next,                    Qt::Key_PageDown,
392
393     XK_Shift_L,                 Qt::Key_Shift,
394     XK_Shift_R,                 Qt::Key_Shift,
395     XK_Shift_Lock,              Qt::Key_Shift,
396     XK_Control_L,               Qt::Key_Control,
397     XK_Control_R,               Qt::Key_Control,
398     XK_Meta_L,                  Qt::Key_Meta,
399     XK_Meta_R,                  Qt::Key_Meta,
400     XK_Alt_L,                   Qt::Key_Alt,
401     XK_Alt_R,                   Qt::Key_Alt,
402     XK_Caps_Lock,               Qt::Key_CapsLock,
403     XK_Num_Lock,                Qt::Key_NumLock,
404     XK_Scroll_Lock,             Qt::Key_ScrollLock,
405     XK_Super_L,                 Qt::Key_Super_L,
406     XK_Super_R,                 Qt::Key_Super_R,
407     XK_Menu,                    Qt::Key_Menu,
408     XK_Hyper_L,                 Qt::Key_Hyper_L,
409     XK_Hyper_R,                 Qt::Key_Hyper_R,
410     XK_Help,                    Qt::Key_Help,
411
412     XK_KP_Space,                Qt::Key_Space,
413     XK_KP_Tab,                  Qt::Key_Tab,
414     XK_KP_Enter,                Qt::Key_Enter,
415     XK_KP_Home,                 Qt::Key_Home,
416     XK_KP_Left,                 Qt::Key_Left,
417     XK_KP_Up,                   Qt::Key_Up,
418     XK_KP_Right,                Qt::Key_Right,
419     XK_KP_Down,                 Qt::Key_Down,
420     XK_KP_Prior,                Qt::Key_PageUp,
421     XK_KP_Next,                 Qt::Key_PageDown,
422     XK_KP_End,                  Qt::Key_End,
423     XK_KP_Begin,                Qt::Key_Clear,
424     XK_KP_Insert,               Qt::Key_Insert,
425     XK_KP_Delete,               Qt::Key_Delete,
426     XK_KP_Equal,                Qt::Key_Equal,
427     XK_KP_Multiply,             Qt::Key_Asterisk,
428     XK_KP_Add,                  Qt::Key_Plus,
429     XK_KP_Separator,            Qt::Key_Comma,
430     XK_KP_Subtract,             Qt::Key_Minus,
431     XK_KP_Decimal,              Qt::Key_Period,
432     XK_KP_Divide,               Qt::Key_Slash,
433
434     XK_ISO_Level3_Shift,        Qt::Key_AltGr,
435     XK_Multi_key,               Qt::Key_Multi_key,
436     XK_Codeinput,               Qt::Key_Codeinput,
437     XK_SingleCandidate,         Qt::Key_SingleCandidate,
438     XK_MultipleCandidate,       Qt::Key_MultipleCandidate,
439     XK_PreviousCandidate,       Qt::Key_PreviousCandidate,
440
441     XK_Mode_switch,             Qt::Key_Mode_switch,
442     XK_script_switch,           Qt::Key_Mode_switch,
443
444     0,                          0
445 };
446
447 static uint32_t translateKey(uint32_t sym, char *string, size_t size)
448 {
449     Q_UNUSED(size);
450     string[0] = '\0';
451
452     int code = -1;
453     for (int i = 0; KeyTbl[i]; i += 2) {
454         if (sym == KeyTbl[i]) {
455             code = KeyTbl[i + 1];
456             break;
457         }
458     }
459     if (code == -1) {
460         string[0] = sym;
461         string[1] = '\0';
462         return toupper(sym);
463     }
464     return code;
465 }
466
467 #endif // QT_NO_WAYLAND_XKB
468
469 void QWaylandInputDevice::keyboard_keymap(void *data,
470                                           struct wl_keyboard *keyboard,
471                                           uint32_t format,
472                                           int32_t fd,
473                                           uint32_t size)
474 {
475     Q_UNUSED(data);
476     Q_UNUSED(keyboard);
477     Q_UNUSED(format);
478     Q_UNUSED(fd);
479     Q_UNUSED(size);
480 }
481
482 void QWaylandInputDevice::keyboard_enter(void *data,
483                                          struct wl_keyboard *keyboard,
484                                          uint32_t time,
485                                          struct wl_surface *surface,
486                                          struct wl_array *keys)
487 {
488     Q_UNUSED(keyboard);
489     Q_UNUSED(time);
490     Q_UNUSED(keys);
491
492     if (!surface)
493         return;
494
495     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
496     QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface);
497     inputDevice->mKeyboardFocus = window;
498     inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(inputDevice);
499     QWindowSystemInterface::handleWindowActivated(window->window());
500 }
501
502 void QWaylandInputDevice::keyboard_leave(void *data,
503                                          struct wl_keyboard *keyboard,
504                                          uint32_t time,
505                                          struct wl_surface *surface)
506 {
507     Q_UNUSED(keyboard);
508     Q_UNUSED(time);
509     Q_UNUSED(surface);
510
511     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
512     inputDevice->mKeyboardFocus = NULL;
513     inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(0);
514     QWindowSystemInterface::handleWindowActivated(0);
515 }
516
517 void QWaylandInputDevice::keyboard_key(void *data,
518                                        struct wl_keyboard *keyboard,
519                                        uint32_t serial, uint32_t time,
520                                        uint32_t key, uint32_t state)
521 {
522     Q_UNUSED(keyboard);
523     Q_UNUSED(serial);
524     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
525     QWaylandWindow *window = inputDevice->mKeyboardFocus;
526 #ifndef QT_NO_WAYLAND_XKB
527     if (!inputDevice->mXkbMap)
528         return;
529
530     uint32_t code = key + 8;
531     bool isDown = state != 0;
532     const xkb_keysym_t *syms;
533     uint32_t numSyms = xkb_key_get_syms(inputDevice->mXkbState, code, &syms);
534     xkb_state_update_key(inputDevice->mXkbState, code,
535                          isDown ? XKB_KEY_DOWN : XKB_KEY_UP);
536
537     if (!window) {
538         // We destroyed the keyboard focus surface, but the server
539         // didn't get the message yet.
540         return;
541     }
542
543     if (numSyms == 1) {
544         xkb_keysym_t sym = syms[0];
545         Qt::KeyboardModifiers modifiers = translateModifiers(inputDevice->mXkbState);
546         QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease;
547
548         char s[2];
549         sym = translateKey(sym, s, sizeof s);
550
551         if (window)
552             QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
553                                                            time, type, sym,
554                                                            modifiers,
555                                                            code, 0, 0,
556                                                            QString::fromLatin1(s));
557     }
558 #else
559     // Generic fallback for single hard keys: Assume 'key' is a Qt key code.
560     if (window) {
561         QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
562                                                        time, state ? QEvent::KeyPress : QEvent::KeyRelease,
563                                                        key + 8, // qt-compositor substracts 8 for some reason
564                                                        Qt::NoModifier,
565                                                        key + 8, 0, 0);
566     }
567 #endif
568 }
569
570 void QWaylandInputDevice::keyboard_modifiers(void *data,
571                                              struct wl_keyboard *keyboard,
572                                              uint32_t serial,
573                                              uint32_t mods_depressed,
574                                              uint32_t mods_latched,
575                                              uint32_t mods_locked,
576                                              uint32_t group)
577 {
578     Q_UNUSED(keyboard);
579     Q_UNUSED(serial);
580 #ifndef QT_NO_WAYLAND_XKB
581     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
582     if (inputDevice->mXkbState)
583         xkb_state_update_mask(inputDevice->mXkbState,
584                               mods_depressed, mods_latched, mods_locked,
585                               0, 0, group);
586 #else
587     Q_UNUSED(data);
588     Q_UNUSED(mods_depressed);
589     Q_UNUSED(mods_latched);
590     Q_UNUSED(mods_locked);
591     Q_UNUSED(group);
592 #endif
593 }
594
595 void QWaylandInputDevice::touch_down(void *data,
596                                      struct wl_touch *touch,
597                                      uint32_t serial,
598                                      uint32_t time,
599                                      struct wl_surface *surface,
600                                      int32_t id,
601                                      wl_fixed_t x,
602                                      wl_fixed_t y)
603 {
604     Q_UNUSED(touch);
605     Q_UNUSED(serial);
606     Q_UNUSED(time);
607     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
608     inputDevice->mTouchFocus = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface));
609     inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed);
610 }
611
612 void QWaylandInputDevice::touch_up(void *data,
613                                    struct wl_touch *touch,
614                                    uint32_t serial,
615                                    uint32_t time,
616                                    int32_t id)
617 {
618     Q_UNUSED(touch);
619     Q_UNUSED(serial);
620     Q_UNUSED(time);
621     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
622     inputDevice->mTouchFocus = 0;
623     inputDevice->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased);
624 }
625
626 void QWaylandInputDevice::touch_motion(void *data,
627                                        struct wl_touch *touch,
628                                        uint32_t time,
629                                        int32_t id,
630                                        wl_fixed_t x,
631                                        wl_fixed_t y)
632 {
633     Q_UNUSED(touch);
634     Q_UNUSED(time);
635     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
636     inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved);
637 }
638
639 void QWaylandInputDevice::touch_frame(void *data, struct wl_touch *touch)
640 {
641     Q_UNUSED(touch);
642     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
643     inputDevice->handleTouchFrame();
644 }
645
646 void QWaylandInputDevice::touch_cancel(void *data, struct wl_touch *touch)
647 {
648     Q_UNUSED(touch);
649     QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data);
650
651     self->mPrevTouchPoints.clear();
652     self->mTouchPoints.clear();
653
654     QWaylandTouchExtension *touchExt = self->mQDisplay->touchExtension();
655     if (touchExt)
656         touchExt->touchCanceled();
657
658     QWindowSystemInterface::handleTouchCancelEvent(0, self->mTouchDevice);
659 }
660
661 void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state)
662 {
663     QWindowSystemInterface::TouchPoint tp;
664
665     // Find out the coordinates for Released events.
666     bool coordsOk = false;
667     if (state == Qt::TouchPointReleased)
668         for (int i = 0; i < mPrevTouchPoints.count(); ++i)
669             if (mPrevTouchPoints.at(i).id == id) {
670                 tp.area = mPrevTouchPoints.at(i).area;
671                 coordsOk = true;
672                 break;
673             }
674
675     if (!coordsOk) {
676         // x and y are surface relative.
677         // We need a global (screen) position.
678         QWaylandWindow *win = mTouchFocus;
679
680         //is it possible that mTouchFocus is null;
681         if (!win)
682             win = mPointerFocus;
683         if (!win)
684             win = mKeyboardFocus;
685         if (!win || !win->window())
686             return;
687
688         tp.area = QRectF(0, 0, 8, 8);
689         QMargins margins = win->frameMargins();
690         tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x+margins.left(), y+margins.top())));
691     }
692
693     tp.state = state;
694     tp.id = id;
695     tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1;
696     mTouchPoints.append(tp);
697 }
698
699 void QWaylandInputDevice::handleTouchFrame()
700 {
701     // Copy all points, that are in the previous but not in the current list, as stationary.
702     for (int i = 0; i < mPrevTouchPoints.count(); ++i) {
703         const QWindowSystemInterface::TouchPoint &prevPoint(mPrevTouchPoints.at(i));
704         if (prevPoint.state == Qt::TouchPointReleased)
705             continue;
706         bool found = false;
707         for (int j = 0; j < mTouchPoints.count(); ++j)
708             if (mTouchPoints.at(j).id == prevPoint.id) {
709                 found = true;
710                 break;
711             }
712         if (!found) {
713             QWindowSystemInterface::TouchPoint p = prevPoint;
714             p.state = Qt::TouchPointStationary;
715             mTouchPoints.append(p);
716         }
717     }
718
719     if (mTouchPoints.isEmpty()) {
720         mPrevTouchPoints.clear();
721         return;
722     }
723
724     QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints);
725
726     bool allReleased = true;
727     for (int i = 0; i < mTouchPoints.count(); ++i)
728         if (mTouchPoints.at(i).state != Qt::TouchPointReleased) {
729             allReleased = false;
730             break;
731         }
732
733     mPrevTouchPoints = mTouchPoints;
734     mTouchPoints.clear();
735
736     if (allReleased) {
737         QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints);
738         mPrevTouchPoints.clear();
739     }
740 }