Change copyrights from Nokia to Digia
[profile/ivi/qtwayland.git] / src / compositor / wayland_wrapper / wlinputdevice.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Compositor.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 #include "wlinputdevice.h"
42
43 #include "wlcompositor.h"
44 #include "wldatadevice.h"
45 #include "wlsurface.h"
46 #include "wltouch.h"
47 #include "wlqtkey.h"
48 #include "waylandcompositor.h"
49
50 #include <QtGui/QTouchEvent>
51
52 #ifndef QT_NO_WAYLAND_XKB
53 #include <sys/mman.h>
54 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <sys/epoll.h>
57 #include <unistd.h>
58 #include <errno.h>
59 #include <fcntl.h>
60 #include <stdlib.h>
61 #endif
62
63 namespace Wayland {
64
65 static QImage *currentCursor;
66
67 InputDevice::InputDevice(WaylandInputDevice *handle, Compositor *compositor)
68     : m_handle(handle)
69     , m_compositor(compositor)
70 {
71     wl_seat_init(base());
72     initDevices();
73     wl_display_add_global(compositor->wl_display(),
74                           &wl_seat_interface,
75                           this,
76                           InputDevice::bind_func);
77
78 #ifndef QT_NO_WAYLAND_XKB
79     xkb_rule_names xkb_names;
80     xkb_context *context = xkb_context_new(xkb_context_flags(0));
81
82     memset(&xkb_names, 0, sizeof(xkb_names));
83     xkb_names.rules = strdup("evdev");
84     xkb_names.model = strdup("pc105");
85     xkb_names.layout = strdup("us");
86
87     xkb_keymap *keymap = xkb_map_new_from_names(context, &xkb_names, xkb_map_compile_flags(0));
88     if (!keymap)
89         qFatal("Failed to compile global XKB keymap");
90
91     char *keymap_str_data = xkb_map_get_as_string(keymap);
92     QByteArray keymap_str = keymap_str_data;
93     m_keymap_size = keymap_str.size() + 1;
94     free(keymap_str_data);
95
96     const char *path = getenv("XDG_RUNTIME_DIR");
97     if (!path)
98         qFatal("XDG_RUNTIME_DIR not set");
99
100     QByteArray name = QByteArray(path) + "/qtwayland-xkb-map-XXXXXX";
101
102     int fd = mkstemp(name.data());
103     if (fd >= 0) {
104         long flags = fcntl(fd, F_GETFD);
105         if (flags == -1 || fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
106             close(fd);
107             qFatal("Failed to set FD_CLOEXEC on anonymous file");
108         }
109         unlink(name.data());
110     } else {
111         qFatal("Failed to create anonymous file with name %s", name.constData());
112     }
113
114     if (ftruncate(fd, m_keymap_size) < 0)
115         qFatal("Failed to create anonymous file of size %lu", (unsigned long)m_keymap_size);
116
117     m_keymap_fd = fd;
118
119     m_keymap_area = (char *)mmap(0, m_keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_keymap_fd, 0);
120     if (m_keymap_area == MAP_FAILED) {
121         close(m_keymap_fd);
122         qFatal("Failed to map shared memory segment");
123     }
124
125     strcpy(m_keymap_area, keymap_str.constData());
126
127     m_state = xkb_state_new(keymap);
128
129     free((char *)xkb_names.rules);
130     free((char *)xkb_names.model);
131     free((char *)xkb_names.layout);
132     xkb_map_unref(keymap);
133     xkb_context_unref(context);
134 #endif
135 }
136
137 InputDevice::~InputDevice()
138 {
139     qDeleteAll(m_data_devices);
140     releaseDevices();
141
142 #ifndef QT_NO_WAYLAND_XKB
143     if (m_keymap_area)
144         munmap(m_keymap_area, m_keymap_size);
145     close(m_keymap_fd);
146     xkb_state_unref(m_state);
147 #endif
148 }
149
150 void InputDevice::initDevices()
151 {
152     wl_pointer_init(&m_device_interfaces.pointer);
153     wl_seat_set_pointer(base(), &m_device_interfaces.pointer);
154
155     wl_keyboard_init(&m_device_interfaces.keyboard);
156     wl_seat_set_keyboard(base(), &m_device_interfaces.keyboard);
157
158     wl_touch_init(&m_device_interfaces.touch);
159     wl_seat_set_touch(base(), &m_device_interfaces.touch);
160 }
161
162 void InputDevice::releaseDevices()
163 {
164     wl_pointer_release(&m_device_interfaces.pointer);
165     wl_keyboard_release(&m_device_interfaces.keyboard);
166     wl_touch_release(&m_device_interfaces.touch);
167 }
168
169 wl_pointer *InputDevice::pointerDevice()
170 {
171     return &m_device_interfaces.pointer;
172 }
173
174 wl_keyboard *InputDevice::keyboardDevice()
175 {
176     return &m_device_interfaces.keyboard;
177 }
178
179 wl_touch *InputDevice::touchDevice()
180 {
181     return &m_device_interfaces.touch;
182 }
183
184 const wl_pointer *InputDevice::pointerDevice() const
185 {
186     return &m_device_interfaces.pointer;
187 }
188
189 const wl_keyboard *InputDevice::keyboardDevice() const
190 {
191     return &m_device_interfaces.keyboard;
192 }
193
194 const wl_touch *InputDevice::touchDevice() const
195 {
196     return &m_device_interfaces.touch;
197 }
198
199 void InputDevice::destroy_resource(wl_resource *resource)
200 {
201     InputDevice *input_device = static_cast<InputDevice *>(resource->data);
202     if (input_device->keyboardDevice()->focus_resource == resource) {
203         input_device->keyboardDevice()->focus_resource = 0;
204     }
205     if (input_device->pointerDevice()->focus_resource == resource) {
206         input_device->pointerDevice()->focus_resource = 0;
207     }
208
209     input_device->cleanupDataDeviceForClient(resource->client, true);
210
211     wl_list_remove(&resource->link);
212
213     free(resource);
214 }
215
216 void InputDevice::bind_func(struct wl_client *client, void *data,
217                             uint32_t version, uint32_t id)
218 {
219     Q_UNUSED(version);
220     struct wl_resource *resource = wl_client_add_object(client,
221                                                         &wl_seat_interface,
222                                                         &seat_interface,
223                                                         id,
224                                                         data);
225
226     struct wl_seat *seat = static_cast<struct wl_seat *>(data);
227     resource->destroy = destroy_resource;
228     wl_list_insert(&seat->base_resource_list, &resource->link);
229
230     uint32_t caps = WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD;
231     if (!QTouchDevice::devices().isEmpty())
232         caps |= WL_SEAT_CAPABILITY_TOUCH;
233
234     wl_seat_send_capabilities(resource, caps);
235 }
236
237 const struct wl_seat_interface InputDevice::seat_interface = {
238     get_pointer,
239     get_keyboard,
240     get_touch
241 };
242
243 void InputDevice::destroy_device_resource(wl_resource *resource)
244 {
245     wl_list_remove(&resource->link);
246     free(resource);
247 }
248
249 void InputDevice::get_pointer(struct wl_client *client,
250                               struct wl_resource *resource,
251                               uint32_t id)
252 {
253     InputDevice *inputDevice = static_cast<InputDevice *>(resource->data);
254     wl_pointer *pointer = inputDevice->pointerDevice();
255     wl_resource *clientResource = wl_client_add_object(client,
256                                                        &wl_pointer_interface,
257                                                        &pointer_interface,
258                                                        id,
259                                                        pointer);
260     wl_list_insert(&pointer->resource_list, &clientResource->link);
261     clientResource->destroy = InputDevice::destroy_device_resource;
262 }
263
264 void InputDevice::get_keyboard(struct wl_client *client,
265                                struct wl_resource *resource,
266                                uint32_t id)
267 {
268     InputDevice *inputDevice = static_cast<InputDevice *>(resource->data);
269     wl_keyboard *keyboard = inputDevice->keyboardDevice();
270     wl_resource *clientResource = wl_client_add_object(client,
271                                                        &wl_keyboard_interface,
272                                                        0,
273                                                        id,
274                                                        keyboard);
275     wl_list_insert(&keyboard->resource_list, &clientResource->link);
276     clientResource->destroy = InputDevice::destroy_device_resource;
277
278 #ifndef QT_NO_WAYLAND_XKB
279     wl_keyboard_send_keymap(clientResource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
280                             inputDevice->m_keymap_fd, inputDevice->m_keymap_size);
281 #endif
282 }
283
284 void InputDevice::get_touch(struct wl_client *client,
285                             struct wl_resource *resource,
286                             uint32_t id)
287 {
288     InputDevice *inputDevice = static_cast<InputDevice *>(resource->data);
289     wl_touch *touch = inputDevice->touchDevice();
290     wl_resource *clientResource = wl_client_add_object(client,
291                                                        &wl_touch_interface,
292                                                        0,
293                                                        id,
294                                                        touch);
295     wl_list_insert(&touch->resource_list, &clientResource->link);
296     clientResource->destroy = InputDevice::destroy_device_resource;
297 }
298
299 void InputDevice::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos)
300 {
301     sendMouseMoveEvent(localPos,globalPos);
302     wl_pointer *pointer = pointerDevice();
303     pointer->button_count++;
304     uint32_t time = m_compositor->currentTimeMsecs();
305     const struct wl_pointer_grab_interface *interface = pointer->grab->interface;
306     interface->button(pointer->grab, time, toWaylandButton(button), 1);
307 }
308
309 void InputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos)
310 {
311     sendMouseMoveEvent(localPos,globalPos);
312     wl_pointer *pointer = pointerDevice();
313     pointer->button_count--;
314     uint32_t time = m_compositor->currentTimeMsecs();
315     const struct wl_pointer_grab_interface *interface = pointer->grab->interface;
316     interface->button(pointer->grab, time, toWaylandButton(button), 0);
317 }
318
319 void InputDevice::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos)
320 {
321     Q_UNUSED(globalPos);
322     uint32_t time = m_compositor->currentTimeMsecs();
323     wl_pointer *pointer = pointerDevice();
324     const struct wl_pointer_grab_interface *interface = pointer->grab->interface;
325     pointer->x = wl_fixed_from_double(globalPos.x());
326     pointer->y = wl_fixed_from_double(globalPos.y());
327     interface->motion(pointer->grab,
328                       time,
329                       wl_fixed_from_double(localPos.x()), wl_fixed_from_double(localPos.y()));
330 }
331
332 void InputDevice::sendMouseMoveEvent(Surface *surface, const QPointF &localPos, const QPointF &globalPos)
333 {
334     setMouseFocus(surface,localPos,globalPos);
335     sendMouseMoveEvent(localPos,globalPos);
336 }
337
338 void InputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta)
339 {
340     wl_pointer *pointer = pointerDevice();
341     struct wl_resource *resource = pointer->focus_resource;
342     if (!resource)
343         return;
344     uint32_t time = m_compositor->currentTimeMsecs();
345     uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL
346                                                   : WL_POINTER_AXIS_VERTICAL_SCROLL;
347     wl_pointer_send_axis(resource, time, axis, wl_fixed_from_double(delta / 120.0));
348 }
349
350 void InputDevice::updateModifierState(uint code, int state)
351 {
352 #ifndef QT_NO_WAYLAND_XKB
353     xkb_state_update_key(m_state, code, state ? XKB_KEY_DOWN : XKB_KEY_UP);
354
355     uint32_t mods_depressed = xkb_state_serialize_mods(m_state, XKB_STATE_DEPRESSED);
356     uint32_t mods_latched = xkb_state_serialize_mods(m_state, XKB_STATE_LATCHED);
357     uint32_t mods_locked = xkb_state_serialize_mods(m_state, XKB_STATE_LATCHED);
358     uint32_t group = xkb_state_serialize_group(m_state, XKB_STATE_EFFECTIVE);
359
360     wl_keyboard *keyboard = keyboardDevice();
361
362     if (mods_depressed == keyboard->modifiers.mods_depressed
363         && mods_latched == keyboard->modifiers.mods_latched
364         && mods_locked == keyboard->modifiers.mods_locked
365         && group == keyboard->modifiers.group)
366     {
367         return; // no change
368     }
369
370     keyboard->modifiers.mods_depressed = mods_depressed;
371     keyboard->modifiers.mods_latched = mods_latched;
372     keyboard->modifiers.mods_locked = mods_locked;
373     keyboard->modifiers.group = group;
374
375     if (keyboard->focus_resource)
376         sendKeyModifiers(keyboard->focus_resource);
377 #else
378     Q_UNUSED(code);
379     Q_UNUSED(state);
380 #endif
381 }
382
383 void InputDevice::sendKeyModifiers(wl_resource *resource)
384 {
385     wl_keyboard *keyboard = keyboardDevice();
386     uint32_t serial = wl_display_next_serial(m_compositor->wl_display());
387     wl_keyboard_send_modifiers(resource, serial, keyboard->modifiers.mods_depressed,
388         keyboard->modifiers.mods_latched, keyboard->modifiers.mods_locked, keyboard->modifiers.group);
389 }
390
391 void InputDevice::sendKeyPressEvent(uint code)
392 {
393     wl_keyboard *keyboard = keyboardDevice();
394     if (keyboard->focus_resource) {
395         uint32_t time = m_compositor->currentTimeMsecs();
396         uint32_t serial = wl_display_next_serial(m_compositor->wl_display());
397         wl_keyboard_send_key(keyboard->focus_resource,
398                              serial, time, code - 8, 1);
399     }
400     updateModifierState(code, 1);
401 }
402
403 void InputDevice::sendKeyReleaseEvent(uint code)
404 {
405     wl_keyboard *keyboard = keyboardDevice();
406     if (keyboard->focus_resource) {
407         uint32_t time = m_compositor->currentTimeMsecs();
408         uint32_t serial = wl_display_next_serial(m_compositor->wl_display());
409         wl_keyboard_send_key(keyboard->focus_resource,
410                              serial, time, code - 8, 0);
411     }
412     updateModifierState(code, 0);
413 }
414
415 void InputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state)
416 {
417     uint32_t time = m_compositor->currentTimeMsecs();
418     uint32_t serial = 0;
419     wl_touch *touch = touchDevice();
420     wl_resource *resource = touch->focus_resource;
421     if (!resource)
422         return;
423     switch (state) {
424     case Qt::TouchPointPressed:
425         wl_touch_send_down(resource, serial, time, &touch->focus->resource, id,
426                            wl_fixed_from_double(x), wl_fixed_from_double(y));
427         break;
428     case Qt::TouchPointMoved:
429         wl_touch_send_motion(resource, time, id,
430                              wl_fixed_from_double(x), wl_fixed_from_double(y));
431         break;
432     case Qt::TouchPointReleased:
433         wl_touch_send_up(resource, serial, time, id);
434         break;
435     case Qt::TouchPointStationary:
436         // stationary points are not sent through wayland, the client must cache them
437         break;
438     default:
439         break;
440     }
441 }
442
443 void InputDevice::sendTouchFrameEvent()
444 {
445     wl_touch *touch = touchDevice();
446     wl_resource *resource = touch->focus_resource;
447     if (resource)
448         wl_touch_send_frame(resource);
449 }
450
451 void InputDevice::sendTouchCancelEvent()
452 {
453     wl_touch *touch = touchDevice();
454     wl_resource *resource = touch->focus_resource;
455     if (resource)
456         wl_touch_send_cancel(resource);
457 }
458
459 void InputDevice::sendFullKeyEvent(QKeyEvent *event)
460 {
461     if (!keyboardFocus()) {
462         qWarning("Cannot send key event, no keyboard focus, fix the compositor");
463         return;
464     }
465
466     QtKeyExtensionGlobal *ext = m_compositor->qtkeyExtension();
467     if (ext && ext->postQtKeyEvent(event, keyboardFocus()))
468         return;
469
470     if (event->type() == QEvent::KeyPress)
471         sendKeyPressEvent(event->nativeScanCode());
472     else if (event->type() == QEvent::KeyRelease)
473         sendKeyReleaseEvent(event->nativeScanCode());
474 }
475
476 void InputDevice::sendFullTouchEvent(QTouchEvent *event)
477 {
478     if (!mouseFocus()) {
479         qWarning("Cannot send touch event, no pointer focus, fix the compositor");
480         return;
481     }
482
483     if (event->type() == QEvent::TouchCancel) {
484         sendTouchCancelEvent();
485         return;
486     }
487
488     TouchExtensionGlobal *ext = m_compositor->touchExtension();
489     if (ext && ext->postTouchEvent(event, mouseFocus()))
490         return;
491
492     const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
493     if (points.isEmpty())
494         return;
495
496     const int pointCount = points.count();
497     QPointF pos = mouseFocus()->pos();
498     for (int i = 0; i < pointCount; ++i) {
499         const QTouchEvent::TouchPoint &tp(points.at(i));
500         // Convert the local pos in the compositor window to surface-relative.
501         QPointF p = tp.pos() - pos;
502         sendTouchPointEvent(tp.id(), p.x(), p.y(), tp.state());
503     }
504     sendTouchFrameEvent();
505 }
506
507 Surface *InputDevice::keyboardFocus() const
508 {
509     return wayland_cast<Surface>(keyboardDevice()->focus);
510 }
511
512 /*!
513  * \return True if the keyboard focus is changed successfully. False for inactive transient surfaces.
514  */
515 bool InputDevice::setKeyboardFocus(Surface *surface)
516 {
517     if (surface && surface->transientInactive())
518         return false;
519
520     sendSelectionFocus(surface);
521     wl_keyboard_set_focus(keyboardDevice(), surface ? surface->base() : 0);
522     return true;
523 }
524
525 Surface *InputDevice::mouseFocus() const
526 {
527     return wayland_cast<Surface>(pointerDevice()->focus);
528 }
529
530 void InputDevice::setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos)
531 {
532     wl_pointer *pointer = pointerDevice();
533     pointer->x = wl_fixed_from_double(globalPos.x());
534     pointer->y = wl_fixed_from_double(globalPos.y());
535     pointer->current = surface ? surface->base() : 0;
536     pointer->current_x = wl_fixed_from_double(localPos.x());
537     pointer->current_y = wl_fixed_from_double(localPos.y());
538     pointer->grab->interface->focus(pointer->grab,
539                                     surface ? surface->base() : 0,
540                                     wl_fixed_from_double(localPos.x()), wl_fixed_from_double(localPos.y()));
541
542     // We have no separate touch focus management so make it match the pointer focus always.
543     // No wl_touch_set_focus() is available so set it manually.
544     wl_touch *touch = touchDevice();
545     touch->focus = surface ? surface->base() : 0;
546     touch->focus_resource = Compositor::resourceForSurface(&touch->resource_list, surface);
547 }
548
549 void InputDevice::cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev)
550 {
551     for (int i = 0; i < m_data_devices.size(); i++) {
552         struct wl_resource *data_device_resource =
553                 m_data_devices.at(i)->dataDeviceResource();
554         if (data_device_resource->client == client) {
555             if (destroyDev)
556                 delete m_data_devices.at(i);
557             m_data_devices.removeAt(i);
558             break;
559         }
560     }
561 }
562
563 void InputDevice::clientRequestedDataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id)
564 {
565     cleanupDataDeviceForClient(client, false);
566     DataDevice *dataDevice = new DataDevice(data_device_manager,client,id);
567     m_data_devices.append(dataDevice);
568 }
569
570 void InputDevice::sendSelectionFocus(Surface *surface)
571 {
572     if (!surface)
573         return;
574     DataDevice *device = dataDevice(surface->base()->resource.client);
575     if (device) {
576         device->sendSelectionFocus();
577     }
578 }
579
580 Compositor *InputDevice::compositor() const
581 {
582     return m_compositor;
583 }
584
585 WaylandInputDevice *InputDevice::handle() const
586 {
587     return m_handle;
588 }
589
590 uint32_t InputDevice::toWaylandButton(Qt::MouseButton button)
591 {
592 #ifndef BTN_LEFT
593     uint32_t BTN_LEFT = 0x110;
594 #endif
595     // the range of valid buttons (evdev module) is from 0x110
596     // through 0x11f. 0x120 is the first 'Joystick' button.
597     switch (button) {
598     case Qt::LeftButton: return BTN_LEFT;
599     case Qt::RightButton: return uint32_t(0x111);
600     case Qt::MiddleButton: return uint32_t(0x112);
601     case Qt::ExtraButton1: return uint32_t(0x113);  // AKA Qt::BackButton, Qt::XButton1
602     case Qt::ExtraButton2: return uint32_t(0x114);  // AKA Qt::ForwardButton, Qt::XButton2
603     case Qt::ExtraButton3: return uint32_t(0x115);
604     case Qt::ExtraButton4: return uint32_t(0x116);
605     case Qt::ExtraButton5: return uint32_t(0x117);
606     case Qt::ExtraButton6: return uint32_t(0x118);
607     case Qt::ExtraButton7: return uint32_t(0x119);
608     case Qt::ExtraButton8: return uint32_t(0x11a);
609     case Qt::ExtraButton9: return uint32_t(0x11b);
610     case Qt::ExtraButton10: return uint32_t(0x11c);
611     case Qt::ExtraButton11: return uint32_t(0x11d);
612     case Qt::ExtraButton12: return uint32_t(0x11e);
613     case Qt::ExtraButton13: return uint32_t(0x11f);
614         // default should not occur; but if it does, then return Wayland's highest possible button number.
615     default: return uint32_t(0x11f);
616     }
617 }
618
619 DataDevice *InputDevice::dataDevice(struct wl_client *client) const
620 {
621     for (int i = 0; i < m_data_devices.size();i++) {
622         if (m_data_devices.at(i)->dataDeviceResource()->client == client) {
623             return m_data_devices.at(i);
624         }
625     }
626     return 0;
627 }
628
629 const struct wl_pointer_interface InputDevice::pointer_interface = {
630     InputDevice::pointer_attach
631 };
632
633 void InputDevice::pointer_attach(struct wl_client *client,
634                                  struct wl_resource *device_resource,
635                                  uint32_t serial,
636                                  struct wl_resource *buffer_resource, int32_t x, int32_t y)
637 {
638     Q_UNUSED(client);
639     Q_UNUSED(serial);
640
641     wl_pointer *pointer = reinterpret_cast<wl_pointer *>(device_resource->data);
642     InputDevice *inputDevice = wayland_cast<InputDevice>(pointer->seat);
643     wl_buffer *buffer = reinterpret_cast<wl_buffer *>(buffer_resource);
644
645     if (buffer && wl_buffer_is_shm(buffer)) {
646         int stride = wl_shm_buffer_get_stride(buffer);
647         uint format = wl_shm_buffer_get_format(buffer);
648         (void) format;
649         void *data = wl_shm_buffer_get_data(buffer);
650         const uchar *char_data = static_cast<const uchar *>(data);
651         if (char_data) {
652             QImage *img = new QImage(char_data, buffer->width, buffer->height, stride, QImage::Format_ARGB32_Premultiplied);
653             inputDevice->m_compositor->waylandCompositor()->changeCursor(*img, x, y);
654             delete currentCursor;
655             currentCursor = img;
656         }
657     } else {
658         inputDevice->m_compositor->waylandCompositor()->changeCursor(QImage(), x, y);
659     }
660 }
661
662
663 }