Follow protocol changes in pointer attach
[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::setCursor(wl_surface *surface, int x, int y)
202 {
203     if (mCaps & WL_SEAT_CAPABILITY_POINTER)
204         wl_pointer_set_cursor(mDeviceInterfaces.pointer, mTime, surface, 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     if (sym >= XK_F1 && sym <= XK_F35)
453         return Qt::Key_F1 + (int(sym) - XK_F1);
454
455     for (int i = 0; KeyTbl[i]; i += 2)
456         if (sym == KeyTbl[i])
457             return KeyTbl[i + 1];
458
459     string[0] = sym;
460     string[1] = '\0';
461     return toupper(sym);
462 }
463
464 #endif // QT_NO_WAYLAND_XKB
465
466 void QWaylandInputDevice::keyboard_keymap(void *data,
467                                           struct wl_keyboard *keyboard,
468                                           uint32_t format,
469                                           int32_t fd,
470                                           uint32_t size)
471 {
472     Q_UNUSED(data);
473     Q_UNUSED(keyboard);
474     Q_UNUSED(format);
475     Q_UNUSED(fd);
476     Q_UNUSED(size);
477 }
478
479 void QWaylandInputDevice::keyboard_enter(void *data,
480                                          struct wl_keyboard *keyboard,
481                                          uint32_t time,
482                                          struct wl_surface *surface,
483                                          struct wl_array *keys)
484 {
485     Q_UNUSED(keyboard);
486     Q_UNUSED(time);
487     Q_UNUSED(keys);
488
489     if (!surface)
490         return;
491
492     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
493     QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface);
494     inputDevice->mKeyboardFocus = window;
495     inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(inputDevice);
496     QWindowSystemInterface::handleWindowActivated(window->window());
497 }
498
499 void QWaylandInputDevice::keyboard_leave(void *data,
500                                          struct wl_keyboard *keyboard,
501                                          uint32_t time,
502                                          struct wl_surface *surface)
503 {
504     Q_UNUSED(keyboard);
505     Q_UNUSED(time);
506     Q_UNUSED(surface);
507
508     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
509     inputDevice->mKeyboardFocus = NULL;
510     inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(0);
511     QWindowSystemInterface::handleWindowActivated(0);
512 }
513
514 void QWaylandInputDevice::keyboard_key(void *data,
515                                        struct wl_keyboard *keyboard,
516                                        uint32_t serial, uint32_t time,
517                                        uint32_t key, uint32_t state)
518 {
519     Q_UNUSED(keyboard);
520     Q_UNUSED(serial);
521     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
522     QWaylandWindow *window = inputDevice->mKeyboardFocus;
523 #ifndef QT_NO_WAYLAND_XKB
524     if (!inputDevice->mXkbMap)
525         return;
526
527     uint32_t code = key + 8;
528     bool isDown = state != 0;
529     const xkb_keysym_t *syms;
530     uint32_t numSyms = xkb_key_get_syms(inputDevice->mXkbState, code, &syms);
531     xkb_state_update_key(inputDevice->mXkbState, code,
532                          isDown ? XKB_KEY_DOWN : XKB_KEY_UP);
533
534     if (!window) {
535         // We destroyed the keyboard focus surface, but the server
536         // didn't get the message yet.
537         return;
538     }
539
540     if (numSyms == 1) {
541         xkb_keysym_t sym = syms[0];
542         Qt::KeyboardModifiers modifiers = translateModifiers(inputDevice->mXkbState);
543         QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease;
544
545         char s[2];
546         sym = translateKey(sym, s, sizeof s);
547
548         if (window)
549             QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
550                                                            time, type, sym,
551                                                            modifiers,
552                                                            code, 0, 0,
553                                                            QString::fromLatin1(s));
554     }
555 #else
556     // Generic fallback for single hard keys: Assume 'key' is a Qt key code.
557     if (window) {
558         QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
559                                                        time, state ? QEvent::KeyPress : QEvent::KeyRelease,
560                                                        key + 8, // qt-compositor substracts 8 for some reason
561                                                        Qt::NoModifier,
562                                                        key + 8, 0, 0);
563     }
564 #endif
565 }
566
567 void QWaylandInputDevice::keyboard_modifiers(void *data,
568                                              struct wl_keyboard *keyboard,
569                                              uint32_t serial,
570                                              uint32_t mods_depressed,
571                                              uint32_t mods_latched,
572                                              uint32_t mods_locked,
573                                              uint32_t group)
574 {
575     Q_UNUSED(keyboard);
576     Q_UNUSED(serial);
577 #ifndef QT_NO_WAYLAND_XKB
578     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
579     if (inputDevice->mXkbState)
580         xkb_state_update_mask(inputDevice->mXkbState,
581                               mods_depressed, mods_latched, mods_locked,
582                               0, 0, group);
583 #else
584     Q_UNUSED(data);
585     Q_UNUSED(mods_depressed);
586     Q_UNUSED(mods_latched);
587     Q_UNUSED(mods_locked);
588     Q_UNUSED(group);
589 #endif
590 }
591
592 void QWaylandInputDevice::touch_down(void *data,
593                                      struct wl_touch *touch,
594                                      uint32_t serial,
595                                      uint32_t time,
596                                      struct wl_surface *surface,
597                                      int32_t id,
598                                      wl_fixed_t x,
599                                      wl_fixed_t y)
600 {
601     Q_UNUSED(touch);
602     Q_UNUSED(serial);
603     Q_UNUSED(time);
604     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
605     inputDevice->mTouchFocus = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface));
606     inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed);
607 }
608
609 void QWaylandInputDevice::touch_up(void *data,
610                                    struct wl_touch *touch,
611                                    uint32_t serial,
612                                    uint32_t time,
613                                    int32_t id)
614 {
615     Q_UNUSED(touch);
616     Q_UNUSED(serial);
617     Q_UNUSED(time);
618     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
619     inputDevice->mTouchFocus = 0;
620     inputDevice->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased);
621 }
622
623 void QWaylandInputDevice::touch_motion(void *data,
624                                        struct wl_touch *touch,
625                                        uint32_t time,
626                                        int32_t id,
627                                        wl_fixed_t x,
628                                        wl_fixed_t y)
629 {
630     Q_UNUSED(touch);
631     Q_UNUSED(time);
632     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
633     inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved);
634 }
635
636 void QWaylandInputDevice::touch_frame(void *data, struct wl_touch *touch)
637 {
638     Q_UNUSED(touch);
639     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
640     inputDevice->handleTouchFrame();
641 }
642
643 void QWaylandInputDevice::touch_cancel(void *data, struct wl_touch *touch)
644 {
645     Q_UNUSED(touch);
646     QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data);
647
648     self->mPrevTouchPoints.clear();
649     self->mTouchPoints.clear();
650
651     QWaylandTouchExtension *touchExt = self->mQDisplay->touchExtension();
652     if (touchExt)
653         touchExt->touchCanceled();
654
655     QWindowSystemInterface::handleTouchCancelEvent(0, self->mTouchDevice);
656 }
657
658 void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state)
659 {
660     QWindowSystemInterface::TouchPoint tp;
661
662     // Find out the coordinates for Released events.
663     bool coordsOk = false;
664     if (state == Qt::TouchPointReleased)
665         for (int i = 0; i < mPrevTouchPoints.count(); ++i)
666             if (mPrevTouchPoints.at(i).id == id) {
667                 tp.area = mPrevTouchPoints.at(i).area;
668                 coordsOk = true;
669                 break;
670             }
671
672     if (!coordsOk) {
673         // x and y are surface relative.
674         // We need a global (screen) position.
675         QWaylandWindow *win = mTouchFocus;
676
677         //is it possible that mTouchFocus is null;
678         if (!win)
679             win = mPointerFocus;
680         if (!win)
681             win = mKeyboardFocus;
682         if (!win || !win->window())
683             return;
684
685         tp.area = QRectF(0, 0, 8, 8);
686         QMargins margins = win->frameMargins();
687         tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x+margins.left(), y+margins.top())));
688     }
689
690     tp.state = state;
691     tp.id = id;
692     tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1;
693     mTouchPoints.append(tp);
694 }
695
696 void QWaylandInputDevice::handleTouchFrame()
697 {
698     // Copy all points, that are in the previous but not in the current list, as stationary.
699     for (int i = 0; i < mPrevTouchPoints.count(); ++i) {
700         const QWindowSystemInterface::TouchPoint &prevPoint(mPrevTouchPoints.at(i));
701         if (prevPoint.state == Qt::TouchPointReleased)
702             continue;
703         bool found = false;
704         for (int j = 0; j < mTouchPoints.count(); ++j)
705             if (mTouchPoints.at(j).id == prevPoint.id) {
706                 found = true;
707                 break;
708             }
709         if (!found) {
710             QWindowSystemInterface::TouchPoint p = prevPoint;
711             p.state = Qt::TouchPointStationary;
712             mTouchPoints.append(p);
713         }
714     }
715
716     if (mTouchPoints.isEmpty()) {
717         mPrevTouchPoints.clear();
718         return;
719     }
720
721     QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints);
722
723     bool allReleased = true;
724     for (int i = 0; i < mTouchPoints.count(); ++i)
725         if (mTouchPoints.at(i).state != Qt::TouchPointReleased) {
726             allReleased = false;
727             break;
728         }
729
730     mPrevTouchPoints = mTouchPoints;
731     mTouchPoints.clear();
732
733     if (allReleased) {
734         QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints);
735         mPrevTouchPoints.clear();
736     }
737 }