From 8b991cabcc9289455f963aadb8c0666068efe476 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 17 May 2012 13:03:57 +0300 Subject: [PATCH] Migrate from wl_input_device to wl_seat MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I0d218c32478c2acce4d7012bdb26b0cde50ee633 Reviewed-by: Samuel Rødal --- src/compositor/wayland_wrapper/wlcompositor.cpp | 18 +- src/compositor/wayland_wrapper/wlcompositor.h | 3 + src/compositor/wayland_wrapper/wlinputdevice.cpp | 342 +++++++++++----- src/compositor/wayland_wrapper/wlinputdevice.h | 44 +- src/compositor/wayland_wrapper/wlshellsurface.cpp | 36 +- .../wayland/qwaylanddatadevicemanager.cpp | 6 +- src/plugins/platforms/wayland/qwaylanddisplay.cpp | 5 +- .../platforms/wayland/qwaylandinputdevice.cpp | 446 +++++++++++---------- .../platforms/wayland/qwaylandinputdevice.h | 146 ++++--- .../platforms/wayland/qwaylandshellsurface.cpp | 8 +- tests/auto/client/mockcompositor.cpp | 10 +- tests/auto/client/mockcompositor.h | 10 +- tests/auto/client/mockinput.cpp | 109 +++-- wayland_sha1.txt | 2 +- 14 files changed, 743 insertions(+), 442 deletions(-) diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp index 5a1bf6d..2364c08 100644 --- a/src/compositor/wayland_wrapper/wlcompositor.cpp +++ b/src/compositor/wayland_wrapper/wlcompositor.cpp @@ -277,7 +277,7 @@ void Compositor::surfaceDestroyed(Surface *surface) // Make sure the surface is reset regardless of what the grabber // interface's focus() does. (e.g. the default implementation does // nothing when a button is down which would be disastrous here) - wl_input_device_set_pointer_focus(dev->base(), 0, 0, 0); + wl_pointer_set_focus(dev->pointerDevice(), 0, 0, 0); } m_surfaces.removeOne(surface); m_dirty_surfaces.remove(surface); @@ -449,6 +449,22 @@ QList Compositor::surfacesForClient(wl_client *client) return ret; } +wl_resource *Compositor::resourceForSurface(wl_list *resourceList, Surface *surface) +{ + if (!surface) + return 0; + + wl_resource *r; + wl_client *surfaceClient = surface->base()->resource.client; + + wl_list_for_each(r, resourceList, link) { + if (r->client == surfaceClient) + return r; + } + + return 0; +} + void Compositor::configureTouchExtension(int flags) { if (m_touchExtension) diff --git a/src/compositor/wayland_wrapper/wlcompositor.h b/src/compositor/wayland_wrapper/wlcompositor.h index c0c1772..e3acad9 100644 --- a/src/compositor/wayland_wrapper/wlcompositor.h +++ b/src/compositor/wayland_wrapper/wlcompositor.h @@ -148,6 +148,9 @@ public: void feedRetainedSelectionData(QMimeData *data); void scheduleReleaseBuffer(SurfaceBuffer *screenBuffer); + + static wl_resource *resourceForSurface(wl_list *resourceList, Surface *surface); + private slots: void releaseBuffer(SurfaceBuffer *screenBuffer); diff --git a/src/compositor/wayland_wrapper/wlinputdevice.cpp b/src/compositor/wayland_wrapper/wlinputdevice.cpp index 2e11153..10be24b 100644 --- a/src/compositor/wayland_wrapper/wlinputdevice.cpp +++ b/src/compositor/wayland_wrapper/wlinputdevice.cpp @@ -57,43 +57,193 @@ InputDevice::InputDevice(WaylandInputDevice *handle, Compositor *compositor) : m_handle(handle) , m_compositor(compositor) { - wl_input_device_init(base()); - wl_display_add_global(compositor->wl_display(),&wl_input_device_interface,this,InputDevice::bind_func); + wl_seat_init(base()); + initDevices(); + wl_display_add_global(compositor->wl_display(), + &wl_seat_interface, + this, + InputDevice::bind_func); } InputDevice::~InputDevice() { qDeleteAll(m_data_devices); + releaseDevices(); +} + +void InputDevice::initDevices() +{ + wl_pointer_init(&m_device_interfaces.pointer); + wl_seat_set_pointer(base(), &m_device_interfaces.pointer); + + wl_keyboard_init(&m_device_interfaces.keyboard); + wl_seat_set_keyboard(base(), &m_device_interfaces.keyboard); + + wl_touch_init(&m_device_interfaces.touch); + wl_seat_set_touch(base(), &m_device_interfaces.touch); +} + +void InputDevice::releaseDevices() +{ + wl_pointer_release(&m_device_interfaces.pointer); + wl_keyboard_release(&m_device_interfaces.keyboard); + wl_touch_release(&m_device_interfaces.touch); +} + +wl_pointer *InputDevice::pointerDevice() +{ + return &m_device_interfaces.pointer; +} + +wl_keyboard *InputDevice::keyboardDevice() +{ + return &m_device_interfaces.keyboard; +} + +wl_touch *InputDevice::touchDevice() +{ + return &m_device_interfaces.touch; +} + +const wl_pointer *InputDevice::pointerDevice() const +{ + return &m_device_interfaces.pointer; +} + +const wl_keyboard *InputDevice::keyboardDevice() const +{ + return &m_device_interfaces.keyboard; +} + +const wl_touch *InputDevice::touchDevice() const +{ + return &m_device_interfaces.touch; +} + +void InputDevice::destroy_resource(wl_resource *resource) +{ + InputDevice *input_device = static_cast(resource->data); + if (input_device->keyboardDevice()->focus_resource == resource) { + input_device->keyboardDevice()->focus_resource = 0; + } + if (input_device->pointerDevice()->focus_resource == resource) { + input_device->pointerDevice()->focus_resource = 0; + } + + input_device->cleanupDataDeviceForClient(resource->client, true); + + wl_list_remove(&resource->link); + + free(resource); +} + +void InputDevice::bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id) +{ + Q_UNUSED(version); + struct wl_resource *resource = wl_client_add_object(client, + &wl_seat_interface, + &seat_interface, + id, + data); + + struct wl_seat *seat = static_cast(data); + resource->destroy = destroy_resource; + wl_list_insert(&seat->base_resource_list, &resource->link); + + uint32_t caps = WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD; + if (!QTouchDevice::devices().isEmpty()) + caps |= WL_SEAT_CAPABILITY_TOUCH; + + wl_seat_send_capabilities(resource, caps); +} + +const struct wl_seat_interface InputDevice::seat_interface = { + get_pointer, + get_keyboard, + get_touch +}; + +void InputDevice::destroy_device_resource(wl_resource *resource) +{ + wl_list_remove(&resource->link); + free(resource); +} + +void InputDevice::get_pointer(struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + InputDevice *inputDevice = static_cast(resource->data); + wl_pointer *pointer = inputDevice->pointerDevice(); + wl_resource *clientResource = wl_client_add_object(client, + &wl_pointer_interface, + &pointer_interface, + id, + pointer); + wl_list_insert(&pointer->resource_list, &clientResource->link); + clientResource->destroy = InputDevice::destroy_device_resource; +} + +void InputDevice::get_keyboard(struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + InputDevice *inputDevice = static_cast(resource->data); + wl_keyboard *keyboard = inputDevice->keyboardDevice(); + wl_resource *clientResource = wl_client_add_object(client, + &wl_keyboard_interface, + 0, + id, + keyboard); + wl_list_insert(&keyboard->resource_list, &clientResource->link); + clientResource->destroy = InputDevice::destroy_device_resource; +} + +void InputDevice::get_touch(struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + InputDevice *inputDevice = static_cast(resource->data); + wl_touch *touch = inputDevice->touchDevice(); + wl_resource *clientResource = wl_client_add_object(client, + &wl_touch_interface, + 0, + id, + touch); + wl_list_insert(&touch->resource_list, &clientResource->link); + clientResource->destroy = InputDevice::destroy_device_resource; } void InputDevice::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) { sendMouseMoveEvent(localPos,globalPos); - - base()->button_count++; + wl_pointer *pointer = pointerDevice(); + pointer->button_count++; uint32_t time = m_compositor->currentTimeMsecs(); - const struct wl_pointer_grab_interface *interface = base()->pointer_grab->interface; - interface->button(base()->pointer_grab,time,toWaylandButton(button),1); + const struct wl_pointer_grab_interface *interface = pointer->grab->interface; + interface->button(pointer->grab, time, toWaylandButton(button), 1); } void InputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) { sendMouseMoveEvent(localPos,globalPos); - - base()->button_count--; + wl_pointer *pointer = pointerDevice(); + pointer->button_count--; uint32_t time = m_compositor->currentTimeMsecs(); - const struct wl_pointer_grab_interface *interface = base()->pointer_grab->interface; - interface->button(base()->pointer_grab,time,toWaylandButton(button),0); + const struct wl_pointer_grab_interface *interface = pointer->grab->interface; + interface->button(pointer->grab, time, toWaylandButton(button), 0); } void InputDevice::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos) { Q_UNUSED(globalPos); uint32_t time = m_compositor->currentTimeMsecs(); - const struct wl_pointer_grab_interface *interface = base()->pointer_grab->interface; - base()->x = wl_fixed_from_double(globalPos.x()); - base()->y = wl_fixed_from_double(globalPos.y()); - interface->motion(base()->pointer_grab, + wl_pointer *pointer = pointerDevice(); + const struct wl_pointer_grab_interface *interface = pointer->grab->interface; + pointer->x = wl_fixed_from_double(globalPos.x()); + pointer->y = wl_fixed_from_double(globalPos.y()); + interface->motion(pointer->grab, time, wl_fixed_from_double(localPos.x()), wl_fixed_from_double(localPos.y())); } @@ -106,32 +256,35 @@ void InputDevice::sendMouseMoveEvent(Surface *surface, const QPointF &localPos, void InputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta) { - struct wl_resource *resource = base()->pointer_focus_resource; + wl_pointer *pointer = pointerDevice(); + struct wl_resource *resource = pointer->focus_resource; if (!resource) return; uint32_t time = m_compositor->currentTimeMsecs(); - uint32_t axis = orientation == Qt::Horizontal ? WL_INPUT_DEVICE_AXIS_HORIZONTAL_SCROLL - : WL_INPUT_DEVICE_AXIS_VERTICAL_SCROLL; - wl_input_device_send_axis(resource, time, axis, delta); + uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL + : WL_POINTER_AXIS_VERTICAL_SCROLL; + wl_pointer_send_axis(resource, time, axis, delta); } void InputDevice::sendKeyPressEvent(uint code) { - if (base()->keyboard_focus_resource != NULL) { + wl_keyboard *keyboard = keyboardDevice(); + if (keyboard->focus_resource) { uint32_t time = m_compositor->currentTimeMsecs(); uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - wl_input_device_send_key(base()->keyboard_focus_resource, - serial, time, code - 8, 1); + wl_keyboard_send_key(keyboard->focus_resource, + serial, time, code - 8, 1); } } void InputDevice::sendKeyReleaseEvent(uint code) { - if (base()->keyboard_focus_resource != NULL) { + wl_keyboard *keyboard = keyboardDevice(); + if (keyboard->focus_resource) { uint32_t time = m_compositor->currentTimeMsecs(); uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - wl_input_device_send_key(base()->keyboard_focus_resource, - serial, time, code - 8, 0); + wl_keyboard_send_key(keyboard->focus_resource, + serial, time, code - 8, 0); } } @@ -139,20 +292,21 @@ void InputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPoint { uint32_t time = m_compositor->currentTimeMsecs(); uint32_t serial = 0; - struct wl_resource *resource = base()->pointer_focus_resource; + wl_touch *touch = touchDevice(); + wl_resource *resource = touch->focus_resource; if (!resource) return; switch (state) { case Qt::TouchPointPressed: - wl_input_device_send_touch_down(resource, serial, time, &base()->pointer_focus->resource, id, - wl_fixed_from_double(x), wl_fixed_from_double(y)); + wl_touch_send_down(resource, serial, time, &touch->focus->resource, id, + wl_fixed_from_double(x), wl_fixed_from_double(y)); break; case Qt::TouchPointMoved: - wl_input_device_send_touch_motion(resource, time, id, - wl_fixed_from_double(x), wl_fixed_from_double(y)); + wl_touch_send_motion(resource, time, id, + wl_fixed_from_double(x), wl_fixed_from_double(y)); break; case Qt::TouchPointReleased: - wl_input_device_send_touch_up(resource, serial, time, id); + wl_touch_send_up(resource, serial, time, id); break; case Qt::TouchPointStationary: // stationary points are not sent through wayland, the client must cache them @@ -164,18 +318,18 @@ void InputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPoint void InputDevice::sendTouchFrameEvent() { - struct wl_resource *resource = base()->pointer_focus_resource; - if (resource) { - wl_input_device_send_touch_frame(resource); - } + wl_touch *touch = touchDevice(); + wl_resource *resource = touch->focus_resource; + if (resource) + wl_touch_send_frame(resource); } void InputDevice::sendTouchCancelEvent() { - struct wl_resource *resource = base()->pointer_focus_resource; - if (resource) { - wl_input_device_send_touch_cancel(resource); - } + wl_touch *touch = touchDevice(); + wl_resource *resource = touch->focus_resource; + if (resource) + wl_touch_send_cancel(resource); } void InputDevice::sendFullKeyEvent(QKeyEvent *event) @@ -228,30 +382,37 @@ void InputDevice::sendFullTouchEvent(QTouchEvent *event) Surface *InputDevice::keyboardFocus() const { - return wayland_cast(base()->keyboard_focus); + return wayland_cast(keyboardDevice()->focus); } void InputDevice::setKeyboardFocus(Surface *surface) { sendSelectionFocus(surface); - wl_input_device_set_keyboard_focus(base(), surface ? surface->base() : 0); + wl_keyboard_set_focus(keyboardDevice(), surface ? surface->base() : 0); } Surface *InputDevice::mouseFocus() const { - return wayland_cast(base()->pointer_focus); + return wayland_cast(pointerDevice()->focus); } void InputDevice::setMouseFocus(Surface *surface, const QPointF &globalPos, const QPointF &localPos) { - base()->x = wl_fixed_from_double(globalPos.x()); - base()->y = wl_fixed_from_double(globalPos.y()); - base()->current = surface ? surface->base() : 0; - base()->current_x = wl_fixed_from_double(localPos.x()); - base()->current_y = wl_fixed_from_double(localPos.y()); - base()->pointer_grab->interface->focus(base()->pointer_grab, - surface ? surface->base() : 0, - wl_fixed_from_double(localPos.x()), wl_fixed_from_double(localPos.y())); + wl_pointer *pointer = pointerDevice(); + pointer->x = wl_fixed_from_double(globalPos.x()); + pointer->y = wl_fixed_from_double(globalPos.y()); + pointer->current = surface ? surface->base() : 0; + pointer->current_x = wl_fixed_from_double(localPos.x()); + pointer->current_y = wl_fixed_from_double(localPos.y()); + pointer->grab->interface->focus(pointer->grab, + surface ? surface->base() : 0, + wl_fixed_from_double(localPos.x()), wl_fixed_from_double(localPos.y())); + + // We have no separate touch focus management so make it match the pointer focus always. + // No wl_touch_set_focus() is available so set it manually. + wl_touch *touch = touchDevice(); + touch->focus = surface ? surface->base() : 0; + touch->focus_resource = Compositor::resourceForSurface(&touch->resource_list, surface); } void InputDevice::cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev) @@ -303,24 +464,24 @@ uint32_t InputDevice::toWaylandButton(Qt::MouseButton button) // the range of valid buttons (evdev module) is from 0x110 // through 0x11f. 0x120 is the first 'Joystick' button. switch (button) { - case Qt::LeftButton: return BTN_LEFT; - case Qt::RightButton: return uint32_t(0x111); - case Qt::MiddleButton: return uint32_t(0x112); - case Qt::ExtraButton1: return uint32_t(0x113); // AKA Qt::BackButton, Qt::XButton1 - case Qt::ExtraButton2: return uint32_t(0x114); // AKA Qt::ForwardButton, Qt::XButton2 - case Qt::ExtraButton3: return uint32_t(0x115); - case Qt::ExtraButton4: return uint32_t(0x116); - case Qt::ExtraButton5: return uint32_t(0x117); - case Qt::ExtraButton6: return uint32_t(0x118); - case Qt::ExtraButton7: return uint32_t(0x119); - case Qt::ExtraButton8: return uint32_t(0x11a); - case Qt::ExtraButton9: return uint32_t(0x11b); - case Qt::ExtraButton10: return uint32_t(0x11c); - case Qt::ExtraButton11: return uint32_t(0x11d); - case Qt::ExtraButton12: return uint32_t(0x11e); - case Qt::ExtraButton13: return uint32_t(0x11f); + case Qt::LeftButton: return BTN_LEFT; + case Qt::RightButton: return uint32_t(0x111); + case Qt::MiddleButton: return uint32_t(0x112); + case Qt::ExtraButton1: return uint32_t(0x113); // AKA Qt::BackButton, Qt::XButton1 + case Qt::ExtraButton2: return uint32_t(0x114); // AKA Qt::ForwardButton, Qt::XButton2 + case Qt::ExtraButton3: return uint32_t(0x115); + case Qt::ExtraButton4: return uint32_t(0x116); + case Qt::ExtraButton5: return uint32_t(0x117); + case Qt::ExtraButton6: return uint32_t(0x118); + case Qt::ExtraButton7: return uint32_t(0x119); + case Qt::ExtraButton8: return uint32_t(0x11a); + case Qt::ExtraButton9: return uint32_t(0x11b); + case Qt::ExtraButton10: return uint32_t(0x11c); + case Qt::ExtraButton11: return uint32_t(0x11d); + case Qt::ExtraButton12: return uint32_t(0x11e); + case Qt::ExtraButton13: return uint32_t(0x11f); // default should not occur; but if it does, then return Wayland's highest possible button number. - default: return uint32_t(0x11f); + default: return uint32_t(0x11f); } } @@ -334,29 +495,22 @@ DataDevice *InputDevice::dataDevice(struct wl_client *client) const return 0; } -void InputDevice::bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id) -{ - Q_UNUSED(version); - struct wl_resource *resource = wl_client_add_object(client,&wl_input_device_interface ,&input_device_interface,id,data); - - struct wl_input_device *input_device = static_cast(data); - resource->destroy = destroy_resource; - wl_list_insert(&input_device->resource_list,&resource->link); -} +const struct wl_pointer_interface InputDevice::pointer_interface = { + InputDevice::pointer_attach +}; -void InputDevice::input_device_attach(struct wl_client *client, - struct wl_resource *device_resource, - uint32_t time, - struct wl_resource *buffer_resource, int32_t x, int32_t y) +void InputDevice::pointer_attach(struct wl_client *client, + struct wl_resource *device_resource, + uint32_t serial, + struct wl_resource *buffer_resource, int32_t x, int32_t y) { Q_UNUSED(client); - Q_UNUSED(time); + Q_UNUSED(serial); - struct wl_input_device *device_base = reinterpret_cast(device_resource->data); - struct wl_buffer *buffer = reinterpret_cast(buffer_resource); + wl_pointer *pointer = reinterpret_cast(device_resource->data); + InputDevice *inputDevice = wayland_cast(pointer->seat); + wl_buffer *buffer = reinterpret_cast(buffer_resource); - InputDevice *inputDevice = wayland_cast(device_base); if (wl_buffer_is_shm(buffer)) { int stride = wl_shm_buffer_get_stride(buffer); uint format = wl_shm_buffer_get_format(buffer); @@ -372,25 +526,5 @@ void InputDevice::input_device_attach(struct wl_client *client, } } -const struct wl_input_device_interface InputDevice::input_device_interface = { - InputDevice::input_device_attach, -}; - -void InputDevice::destroy_resource(wl_resource *resource) -{ - InputDevice *input_device = static_cast(resource->data); - if (input_device->base()->keyboard_focus_resource == resource) { - input_device->base()->keyboard_focus_resource = 0; - } - if (input_device->base()->pointer_focus_resource == resource) { - input_device->base()->pointer_focus_resource = 0; - } - - input_device->cleanupDataDeviceForClient(resource->client, true); - - wl_list_remove(&resource->link); - - free(resource); -} } diff --git a/src/compositor/wayland_wrapper/wlinputdevice.h b/src/compositor/wayland_wrapper/wlinputdevice.h index 060a671..9bfb423 100644 --- a/src/compositor/wayland_wrapper/wlinputdevice.h +++ b/src/compositor/wayland_wrapper/wlinputdevice.h @@ -59,7 +59,7 @@ class DataDevice; class Surface; class DataDeviceManager; -class InputDevice : public Object +class InputDevice : public Object { public: InputDevice(WaylandInputDevice *handle, Compositor *compositor); @@ -94,23 +94,51 @@ public: Compositor *compositor() const; WaylandInputDevice *handle() const; + wl_pointer *pointerDevice(); + wl_keyboard *keyboardDevice(); + wl_touch *touchDevice(); + const wl_pointer *pointerDevice() const; + const wl_keyboard *keyboardDevice() const; + const wl_touch *touchDevice() const; + private: + void initDevices(); + void releaseDevices(); void cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev); WaylandInputDevice *m_handle; Compositor *m_compositor; - QListm_data_devices; + QList m_data_devices; + struct { + wl_pointer pointer; + wl_keyboard keyboard; + wl_touch touch; + } m_device_interfaces; uint32_t toWaylandButton(Qt::MouseButton button); static void bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id); - static void input_device_attach(struct wl_client *client, - struct wl_resource *device_base, - uint32_t time, - struct wl_resource *buffer, int32_t x, int32_t y); - const static struct wl_input_device_interface input_device_interface; - static void destroy_resource(struct wl_resource *resource); + + static void pointer_attach(struct wl_client *client, + struct wl_resource *device_base, + uint32_t serial, + struct wl_resource *buffer, int32_t x, int32_t y); + const static struct wl_pointer_interface pointer_interface; + + static void get_pointer(struct wl_client *client, + struct wl_resource *resource, + uint32_t id); + static void get_keyboard(struct wl_client *client, + struct wl_resource *resource, + uint32_t id); + static void get_touch(struct wl_client *client, + struct wl_resource *resource, + uint32_t id); + const static struct wl_seat_interface seat_interface; + + static void destroy_resource(wl_resource *resource); + static void destroy_device_resource(wl_resource *resource); }; } diff --git a/src/compositor/wayland_wrapper/wlshellsurface.cpp b/src/compositor/wayland_wrapper/wlshellsurface.cpp index 5dad93c..12adf82 100644 --- a/src/compositor/wayland_wrapper/wlshellsurface.cpp +++ b/src/compositor/wayland_wrapper/wlshellsurface.cpp @@ -161,12 +161,13 @@ void ShellSurface::move(struct wl_client *client, } self->m_moveGrabber = new ShellSurfaceMoveGrabber(self); - self->m_moveGrabber->base()->x = input_device->base()->x; - self->m_moveGrabber->base()->y = input_device->base()->y; - self->m_moveGrabber->offset_x = wl_fixed_to_int(input_device->base()->x) - self->surface()->pos().x(); - self->m_moveGrabber->offset_y = wl_fixed_to_int(input_device->base()->y) - self->surface()->pos().y(); + wl_pointer *pointer = input_device->pointerDevice(); + self->m_moveGrabber->base()->x = pointer->x; + self->m_moveGrabber->base()->y = pointer->y; + self->m_moveGrabber->offset_x = wl_fixed_to_int(pointer->x) - self->surface()->pos().x(); + self->m_moveGrabber->offset_y = wl_fixed_to_int(pointer->y) - self->surface()->pos().y(); - wl_input_device_start_pointer_grab(input_device->base(),self->m_moveGrabber->base()); + wl_pointer_start_grab(pointer, self->m_moveGrabber->base()); } void ShellSurface::resize(struct wl_client *client, @@ -186,13 +187,14 @@ void ShellSurface::resize(struct wl_client *client, return; } self->m_resizeGrabber = new ShellSurfaceResizeGrabber(self); - self->m_resizeGrabber->base()->x = input_device->base()->x; - self->m_resizeGrabber->base()->y = input_device->base()->y; + wl_pointer *pointer = input_device->pointerDevice(); + self->m_resizeGrabber->base()->x = pointer->x; + self->m_resizeGrabber->base()->y = pointer->y; self->m_resizeGrabber->resize_edges = wl_shell_surface_resize(edges); self->m_resizeGrabber->width = self->surface()->size().width(); self->m_resizeGrabber->height = self->surface()->size().height(); - wl_input_device_start_pointer_grab(input_device->base(),self->m_resizeGrabber->base()); + wl_pointer_start_grab(pointer, self->m_resizeGrabber->base()); } void ShellSurface::set_toplevel(struct wl_client *client, @@ -361,9 +363,9 @@ void ShellSurfaceResizeGrabber::motion(wl_pointer_grab *grab, uint32_t time, int //Should be more structured ShellSurfaceResizeGrabber *resize_grabber = reinterpret_cast(grab); ShellSurface *shell_surface = resize_grabber->shell_surface; - InputDevice *input_device = reinterpret_cast(grab->input_device); - int width_delta = wl_fixed_to_int(grab->x) - wl_fixed_to_int(input_device->base()->x); - int height_delta = wl_fixed_to_int(grab->y) - wl_fixed_to_int(input_device->base()->y); + wl_pointer *pointer = grab->pointer; + int width_delta = wl_fixed_to_int(grab->x) - wl_fixed_to_int(pointer->x); + int height_delta = wl_fixed_to_int(grab->y) - wl_fixed_to_int(pointer->y); int new_width = resize_grabber->width; int new_height = resize_grabber->height; if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP_LEFT) { @@ -407,7 +409,7 @@ void ShellSurfaceResizeGrabber::button(wl_pointer_grab *grab, uint32_t time, uin ShellSurfaceResizeGrabber *self = reinterpret_cast(grab); ShellSurface *shell_surface = self->shell_surface; if (toQtButton(button) == Qt::LeftButton && !state) { - wl_input_device_end_pointer_grab(grab->input_device); + wl_pointer_end_grab(grab->pointer); shell_surface->resetResizeGrabber(); delete self; } @@ -439,9 +441,9 @@ void ShellSurfaceMoveGrabber::motion(wl_pointer_grab *grab, uint32_t time, int32 Q_UNUSED(y); ShellSurfaceMoveGrabber *shell_surface_grabber = reinterpret_cast(grab); ShellSurface *shell_surface = shell_surface_grabber->shell_surface; - InputDevice *input_device = reinterpret_cast(grab->input_device); - QPointF pos(wl_fixed_to_int(input_device->base()->x) - shell_surface_grabber->offset_x, - wl_fixed_to_int(input_device->base()->y) - shell_surface_grabber->offset_y); + wl_pointer *pointer = grab->pointer; + QPointF pos(wl_fixed_to_int(pointer->x) - shell_surface_grabber->offset_x, + wl_fixed_to_int(pointer->y) - shell_surface_grabber->offset_y); shell_surface->surface()->setPos(pos); if (shell_surface->transientParent()) shell_surface->setOffset(pos - shell_surface->transientParent()->surface()->pos()); @@ -454,8 +456,8 @@ void ShellSurfaceMoveGrabber::button(wl_pointer_grab *grab, uint32_t time, uint3 ShellSurfaceResizeGrabber *self = reinterpret_cast(grab); ShellSurface *shell_surface = self->shell_surface; if (toQtButton(button) == Qt::LeftButton && !state) { - wl_input_device_set_pointer_focus(grab->input_device,0,0,0); - wl_input_device_end_pointer_grab(grab->input_device); + wl_pointer_set_focus(grab->pointer, 0, 0, 0); + wl_pointer_end_grab(grab->pointer); shell_surface->resetMoveGrabber(); delete self; } diff --git a/src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp b/src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp index 21adf26..81972e8 100644 --- a/src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp +++ b/src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp @@ -205,7 +205,8 @@ QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, u { m_data_device_manager = static_cast(wl_display_bind(display->wl_display(),id,&wl_data_device_manager_interface)); - //create transfer devices for all input devices + // Create transfer devices for all input devices. + // ### This only works if we get the global before all devices and is surely wrong when hotplugging. QList inputDevices = m_display->inputDevices(); for (int i = 0; i < inputDevices.size();i++) { inputDevices.at(i)->setTransferDevice(getDataDevice(inputDevices.at(i))); @@ -219,7 +220,8 @@ QWaylandDataDeviceManager::~QWaylandDataDeviceManager() struct wl_data_device *QWaylandDataDeviceManager::getDataDevice(QWaylandInputDevice *inputDevice) { - struct wl_data_device *transfer_device = wl_data_device_manager_get_data_device(m_data_device_manager,inputDevice->wl_input_device()); + struct wl_data_device *transfer_device = wl_data_device_manager_get_data_device(m_data_device_manager, + inputDevice->wl_seat()); wl_data_device_add_listener(transfer_device,&transfer_device_listener,this); return transfer_device; diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index d0ae002..4d0d680 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -286,9 +286,8 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id, mShm = static_cast(wl_display_bind(mDisplay, id, &wl_shm_interface)); } else if (interface == "wl_shell"){ mShell = new QWaylandShell(this,id,version); - } else if (interface == "wl_input_device") { - QWaylandInputDevice *inputDevice = - new QWaylandInputDevice(this, id); + } else if (interface == "wl_seat") { + QWaylandInputDevice *inputDevice = new QWaylandInputDevice(this, id); mInputDevices.append(inputDevice); } else if (interface == "wl_data_device_manager") { mDndSelectionHandler = new QWaylandDataDeviceManager(this, id); diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 6f2d7b7..56496ff 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -61,27 +61,24 @@ #include #endif -QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, - uint32_t id) +QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) : mQDisplay(display) , mDisplay(display->wl_display()) + , mCaps(0) , mTransferDevice(0) , mPointerFocus(0) , mKeyboardFocus(0) , mTouchFocus(0) , mButtons(0) -#ifndef QT_NO_WAYLAND_XKB + #ifndef QT_NO_WAYLAND_XKB , mXkbContext(0) , mXkbMap(0) , mXkbState(0) -#endif + #endif { - mInputDevice = static_cast - (wl_display_bind(mDisplay,id,&wl_input_device_interface)); - wl_input_device_add_listener(mInputDevice, - &inputDeviceListener, - this); - wl_input_device_set_user_data(mInputDevice, this); + mSeat = static_cast(wl_display_bind(mDisplay, id, &wl_seat_interface)); + wl_seat_add_listener(mSeat, &seatListener, this); + wl_seat_set_user_data(mSeat, this); #ifndef QT_NO_WAYLAND_XKB xkb_rule_names names; @@ -125,6 +122,53 @@ QWaylandInputDevice::~QWaylandInputDevice() #endif } +const struct wl_seat_listener QWaylandInputDevice::seatListener = { + QWaylandInputDevice::seat_capabilities +}; + +const struct wl_pointer_listener QWaylandInputDevice::pointerListener = { + QWaylandInputDevice::pointer_enter, + QWaylandInputDevice::pointer_leave, + QWaylandInputDevice::pointer_motion, + QWaylandInputDevice::pointer_button, + QWaylandInputDevice::pointer_axis +}; + +const struct wl_keyboard_listener QWaylandInputDevice::keyboardListener = { + QWaylandInputDevice::keyboard_enter, + QWaylandInputDevice::keyboard_leave, + QWaylandInputDevice::keyboard_key +}; + +const struct wl_touch_listener QWaylandInputDevice::touchListener = { + QWaylandInputDevice::touch_down, + QWaylandInputDevice::touch_up, + QWaylandInputDevice::touch_motion, + QWaylandInputDevice::touch_frame, + QWaylandInputDevice::touch_cancel +}; + +void QWaylandInputDevice::seat_capabilities(void *data, struct wl_seat *seat, uint32_t caps) +{ + QWaylandInputDevice *self = static_cast(data); + self->mCaps = caps; + + if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { + self->mDeviceInterfaces.keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(self->mDeviceInterfaces.keyboard, &keyboardListener, self); + } + + if (caps & WL_SEAT_CAPABILITY_POINTER) { + self->mDeviceInterfaces.pointer = wl_seat_get_pointer(seat); + wl_pointer_add_listener(self->mDeviceInterfaces.pointer, &pointerListener, self); + } + + if (caps & WL_SEAT_CAPABILITY_TOUCH) { + self->mDeviceInterfaces.touch = wl_seat_get_touch(seat); + wl_touch_add_listener(self->mDeviceInterfaces.touch, &touchListener, self); + } +} + void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) { if (window == mPointerFocus) @@ -135,7 +179,7 @@ void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) void QWaylandInputDevice::setTransferDevice(struct wl_data_device *device) { - mTransferDevice = device; + mTransferDevice = device; } struct wl_data_device *QWaylandInputDevice::transferDevice() const @@ -144,31 +188,72 @@ struct wl_data_device *QWaylandInputDevice::transferDevice() const return mTransferDevice; } -struct wl_input_device *QWaylandInputDevice::handle() const +void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) { - return mInputDevice; + mButtons = mButtons & !button; } -void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) +void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y) { - mButtons = mButtons & !button; + if (mCaps & WL_SEAT_CAPABILITY_POINTER) + wl_pointer_attach(mDeviceInterfaces.pointer, mTime, buffer->buffer(), x, y); } -void QWaylandInputDevice::inputHandleMotion(void *data, - struct wl_input_device *input_device, - uint32_t time, - wl_fixed_t surface_x, wl_fixed_t surface_y) +void QWaylandInputDevice::pointer_enter(void *data, + struct wl_pointer *pointer, + uint32_t time, struct wl_surface *surface, + wl_fixed_t sx, wl_fixed_t sy) { - Q_UNUSED(input_device); + Q_UNUSED(pointer); + Q_UNUSED(sx); + Q_UNUSED(sy); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + + if (!surface) + return; + + QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); + window->handleMouseEnter(); + inputDevice->mPointerFocus = window; + + inputDevice->mTime = time; +} + +void QWaylandInputDevice::pointer_leave(void *data, + struct wl_pointer *pointer, + uint32_t time, struct wl_surface *surface) +{ + Q_UNUSED(pointer); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + + // The event may arrive after destroying the window, indicated by + // a null surface. + if (!surface) + return; + + QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); + window->handleMouseLeave(); + inputDevice->mPointerFocus = 0; + inputDevice->mButtons = Qt::NoButton; + + inputDevice->mTime = time; +} + +void QWaylandInputDevice::pointer_motion(void *data, + struct wl_pointer *pointer, + uint32_t time, + wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + Q_UNUSED(pointer); Q_UNUSED(surface_x); Q_UNUSED(surface_y); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mPointerFocus; if (window == NULL) { - /* We destroyed the pointer focus surface, but the server - * didn't get the message yet. */ - return; + // We destroyed the pointer focus surface, but the server + // didn't get the message yet. + return; } QPointF pos(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); @@ -188,12 +273,12 @@ void QWaylandInputDevice::inputHandleMotion(void *data, Qt::NoModifier); } -void QWaylandInputDevice::inputHandleButton(void *data, - struct wl_input_device *input_device, - uint32_t serial, uint32_t time, - uint32_t button, uint32_t state) +void QWaylandInputDevice::pointer_button(void *data, + struct wl_pointer *pointer, + uint32_t serial, uint32_t time, + uint32_t button, uint32_t state) { - Q_UNUSED(input_device); + Q_UNUSED(pointer); Q_UNUSED(serial); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mPointerFocus; @@ -203,29 +288,29 @@ void QWaylandInputDevice::inputHandleButton(void *data, // translate from kernel (input.h) 'button' to corresponding Qt:MouseButton. // The range of mouse values is 0x110 <= mouse_button < 0x120, the first Joystick button. switch (button) { - case 0x110: qt_button = Qt::LeftButton; break; // kernel BTN_LEFT - case 0x111: qt_button = Qt::RightButton; break; - case 0x112: qt_button = Qt::MiddleButton; break; - case 0x113: qt_button = Qt::ExtraButton1; break; // AKA Qt::BackButton - case 0x114: qt_button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton - case 0x115: qt_button = Qt::ExtraButton3; break; // AKA Qt::TaskButton - case 0x116: qt_button = Qt::ExtraButton4; break; - case 0x117: qt_button = Qt::ExtraButton5; break; - case 0x118: qt_button = Qt::ExtraButton6; break; - case 0x119: qt_button = Qt::ExtraButton7; break; - case 0x11a: qt_button = Qt::ExtraButton8; break; - case 0x11b: qt_button = Qt::ExtraButton9; break; - case 0x11c: qt_button = Qt::ExtraButton10; break; - case 0x11d: qt_button = Qt::ExtraButton11; break; - case 0x11e: qt_button = Qt::ExtraButton12; break; - case 0x11f: qt_button = Qt::ExtraButton13; break; - default: return; // invalid button number (as far as Qt is concerned) + case 0x110: qt_button = Qt::LeftButton; break; // kernel BTN_LEFT + case 0x111: qt_button = Qt::RightButton; break; + case 0x112: qt_button = Qt::MiddleButton; break; + case 0x113: qt_button = Qt::ExtraButton1; break; // AKA Qt::BackButton + case 0x114: qt_button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton + case 0x115: qt_button = Qt::ExtraButton3; break; // AKA Qt::TaskButton + case 0x116: qt_button = Qt::ExtraButton4; break; + case 0x117: qt_button = Qt::ExtraButton5; break; + case 0x118: qt_button = Qt::ExtraButton6; break; + case 0x119: qt_button = Qt::ExtraButton7; break; + case 0x11a: qt_button = Qt::ExtraButton8; break; + case 0x11b: qt_button = Qt::ExtraButton9; break; + case 0x11c: qt_button = Qt::ExtraButton10; break; + case 0x11d: qt_button = Qt::ExtraButton11; break; + case 0x11e: qt_button = Qt::ExtraButton12; break; + case 0x11f: qt_button = Qt::ExtraButton13; break; + default: return; // invalid button number (as far as Qt is concerned) } if (state) - inputDevice->mButtons |= qt_button; + inputDevice->mButtons |= qt_button; else - inputDevice->mButtons &= ~qt_button; + inputDevice->mButtons &= ~qt_button; inputDevice->mTime = time; @@ -239,17 +324,17 @@ void QWaylandInputDevice::inputHandleButton(void *data, } } -void QWaylandInputDevice::inputHandleAxis(void *data, - struct wl_input_device *wl_input_device, - uint32_t time, - uint32_t axis, - int32_t value) +void QWaylandInputDevice::pointer_axis(void *data, + struct wl_pointer *pointer, + uint32_t time, + uint32_t axis, + int32_t value) { - Q_UNUSED(wl_input_device); + Q_UNUSED(pointer); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mPointerFocus; - Qt::Orientation orientation = axis == WL_INPUT_DEVICE_AXIS_HORIZONTAL_SCROLL ? Qt::Horizontal - : Qt::Vertical; + Qt::Orientation orientation = axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL ? Qt::Horizontal + : Qt::Vertical; QWindowSystemInterface::handleWheelEvent(window->window(), time, inputDevice->mSurfacePos, inputDevice->mGlobalPos, @@ -319,19 +404,62 @@ static uint32_t translateKey(uint32_t sym, char *string, size_t size) case XK_Menu: return Qt::Key_Menu; default: - string[0] = sym; - string[1] = '\0'; - return toupper(sym); + string[0] = sym; + string[1] = '\0'; + return toupper(sym); } } #endif -void QWaylandInputDevice::inputHandleKey(void *data, - struct wl_input_device *input_device, - uint32_t serial, uint32_t time, - uint32_t key, uint32_t state) +void QWaylandInputDevice::keyboard_enter(void *data, + struct wl_keyboard *keyboard, + uint32_t time, + struct wl_surface *surface, + struct wl_array *keys) { - Q_UNUSED(input_device); + Q_UNUSED(keyboard); + Q_UNUSED(time); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + QWaylandWindow *window; + + inputDevice->mModifiers = 0; + + Q_UNUSED(keys); +#ifndef QT_NO_WAYLAND_XKB + inputDevice->mModifiers |= translateModifiers(inputDevice->mXkbState); +#endif + + if (!surface) + return; + + window = (QWaylandWindow *) wl_surface_get_user_data(surface); + inputDevice->mKeyboardFocus = window; + inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(inputDevice); + QWindowSystemInterface::handleWindowActivated(window->window()); +} + +void QWaylandInputDevice::keyboard_leave(void *data, + struct wl_keyboard *keyboard, + uint32_t time, + struct wl_surface *surface) +{ + Q_UNUSED(keyboard); + Q_UNUSED(time); + Q_UNUSED(surface); + + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + + inputDevice->mKeyboardFocus = NULL; + inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(0); + QWindowSystemInterface::handleWindowActivated(0); +} + +void QWaylandInputDevice::keyboard_key(void *data, + struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, + uint32_t key, uint32_t state) +{ + Q_UNUSED(keyboard); Q_UNUSED(serial); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mKeyboardFocus; @@ -389,99 +517,16 @@ void QWaylandInputDevice::inputHandleKey(void *data, #endif } -void QWaylandInputDevice::inputHandlePointerEnter(void *data, - struct wl_input_device *input_device, - uint32_t time, struct wl_surface *surface, - wl_fixed_t sx, wl_fixed_t sy) +void QWaylandInputDevice::touch_down(void *data, + struct wl_touch *touch, + uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) { - Q_UNUSED(input_device); - Q_UNUSED(sx); - Q_UNUSED(sy); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - - if (!surface) - return; - - QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); - window->handleMouseEnter(); - inputDevice->mPointerFocus = window; - - inputDevice->mTime = time; -} - -void QWaylandInputDevice::inputHandlePointerLeave(void *data, - struct wl_input_device *input_device, - uint32_t time, struct wl_surface *surface) -{ - Q_UNUSED(input_device); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - - // The event may arrive after destroying the window, indicated by - // a null surface. - if (!surface) - return; - - QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); - window->handleMouseLeave(); - inputDevice->mPointerFocus = 0; - inputDevice->mButtons = Qt::NoButton; - - inputDevice->mTime = time; -} - -void QWaylandInputDevice::inputHandleKeyboardEnter(void *data, - struct wl_input_device *input_device, - uint32_t time, - struct wl_surface *surface, - struct wl_array *keys) -{ - Q_UNUSED(input_device); - Q_UNUSED(time); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window; - - inputDevice->mModifiers = 0; - - Q_UNUSED(keys); -#ifndef QT_NO_WAYLAND_XKB - inputDevice->mModifiers |= translateModifiers(inputDevice->mXkbState); -#endif - - if (!surface) - return; - - window = (QWaylandWindow *) wl_surface_get_user_data(surface); - inputDevice->mKeyboardFocus = window; - inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(inputDevice); - QWindowSystemInterface::handleWindowActivated(window->window()); -} - -void QWaylandInputDevice::inputHandleKeyboardLeave(void *data, - struct wl_input_device *input_device, - uint32_t time, - struct wl_surface *surface) -{ - Q_UNUSED(input_device); - Q_UNUSED(time); - Q_UNUSED(surface); - - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - - inputDevice->mKeyboardFocus = NULL; - inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(0); - QWindowSystemInterface::handleWindowActivated(0); -} - -void QWaylandInputDevice::inputHandleTouchDown(void *data, - struct wl_input_device *wl_input_device, - uint32_t serial, - uint32_t time, - struct wl_surface *surface, - int32_t id, - wl_fixed_t x, - wl_fixed_t y) -{ - Q_UNUSED(wl_input_device); + Q_UNUSED(touch); Q_UNUSED(serial); Q_UNUSED(time); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; @@ -489,13 +534,13 @@ void QWaylandInputDevice::inputHandleTouchDown(void *data, inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); } -void QWaylandInputDevice::inputHandleTouchUp(void *data, - struct wl_input_device *wl_input_device, - uint32_t serial, - uint32_t time, - int32_t id) +void QWaylandInputDevice::touch_up(void *data, + struct wl_touch *touch, + uint32_t serial, + uint32_t time, + int32_t id) { - Q_UNUSED(wl_input_device); + Q_UNUSED(touch); Q_UNUSED(serial); Q_UNUSED(time); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; @@ -503,19 +548,41 @@ void QWaylandInputDevice::inputHandleTouchUp(void *data, inputDevice->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); } -void QWaylandInputDevice::inputHandleTouchMotion(void *data, - struct wl_input_device *wl_input_device, - uint32_t time, - int32_t id, - wl_fixed_t x, - wl_fixed_t y) +void QWaylandInputDevice::touch_motion(void *data, + struct wl_touch *touch, + uint32_t time, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) { - Q_UNUSED(wl_input_device); + Q_UNUSED(touch); Q_UNUSED(time); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved); } +void QWaylandInputDevice::touch_frame(void *data, struct wl_touch *touch) +{ + Q_UNUSED(touch); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + inputDevice->handleTouchFrame(); +} + +void QWaylandInputDevice::touch_cancel(void *data, struct wl_touch *touch) +{ + Q_UNUSED(touch); + QWaylandInputDevice *self = static_cast(data); + + self->mPrevTouchPoints.clear(); + self->mTouchPoints.clear(); + + QWaylandTouchExtension *touchExt = self->mQDisplay->touchExtension(); + if (touchExt) + touchExt->touchCanceled(); + + QWindowSystemInterface::handleTouchCancelEvent(0, self->mTouchDevice); +} + void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state) { QWindowSystemInterface::TouchPoint tp; @@ -554,13 +621,6 @@ void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::Touch mTouchPoints.append(tp); } -void QWaylandInputDevice::inputHandleTouchFrame(void *data, struct wl_input_device *wl_input_device) -{ - Q_UNUSED(wl_input_device); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->handleTouchFrame(); -} - void QWaylandInputDevice::handleTouchFrame() { // Copy all points, that are in the previous but not in the current list, as stationary. @@ -603,39 +663,3 @@ void QWaylandInputDevice::handleTouchFrame() mPrevTouchPoints.clear(); } } - -void QWaylandInputDevice::inputHandleTouchCancel(void *data, struct wl_input_device *wl_input_device) -{ - Q_UNUSED(wl_input_device); - QWaylandInputDevice *self = static_cast(data); - - self->mPrevTouchPoints.clear(); - self->mTouchPoints.clear(); - - QWaylandTouchExtension *touchExt = self->mQDisplay->touchExtension(); - if (touchExt) - touchExt->touchCanceled(); - - QWindowSystemInterface::handleTouchCancelEvent(0, self->mTouchDevice); -} - -const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = { - QWaylandInputDevice::inputHandleMotion, - QWaylandInputDevice::inputHandleButton, - QWaylandInputDevice::inputHandleAxis, - QWaylandInputDevice::inputHandleKey, - QWaylandInputDevice::inputHandlePointerEnter, - QWaylandInputDevice::inputHandlePointerLeave, - QWaylandInputDevice::inputHandleKeyboardEnter, - QWaylandInputDevice::inputHandleKeyboardLeave, - QWaylandInputDevice::inputHandleTouchDown, - QWaylandInputDevice::inputHandleTouchUp, - QWaylandInputDevice::inputHandleTouchMotion, - QWaylandInputDevice::inputHandleTouchFrame, - QWaylandInputDevice::inputHandleTouchCancel -}; - -void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y) -{ - wl_input_device_attach(mInputDevice, mTime, buffer->buffer(), x, y); -} diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h index 0146af9..f6eb66c 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h @@ -67,87 +67,113 @@ class QWaylandInputDevice { public: QWaylandInputDevice(QWaylandDisplay *display, uint32_t id); ~QWaylandInputDevice(); + + uint32_t capabilities() const { return mCaps; } + + struct wl_seat *wl_seat() const { return mSeat; } + void attach(QWaylandBuffer *buffer, int x, int y); void handleWindowDestroyed(QWaylandWindow *window); - struct wl_input_device *wl_input_device() const { return mInputDevice; } void setTransferDevice(struct wl_data_device *device); struct wl_data_device *transferDevice() const; - struct wl_input_device *handle() const; - void removeMouseButtonFromState(Qt::MouseButton button); + private: QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; - struct wl_input_device *mInputDevice; + + struct wl_seat *mSeat; + uint32_t mCaps; + + struct { + struct wl_pointer *pointer; + struct wl_keyboard *keyboard; + struct wl_touch *touch; + } mDeviceInterfaces; + struct wl_data_device *mTransferDevice; QWaylandWindow *mPointerFocus; QWaylandWindow *mKeyboardFocus; QWaylandWindow *mTouchFocus; - static const struct wl_input_device_listener inputDeviceListener; + Qt::MouseButtons mButtons; QPointF mSurfacePos; QPointF mGlobalPos; Qt::KeyboardModifiers mModifiers; uint32_t mTime; - static void inputHandleMotion(void *data, - struct wl_input_device *input_device, - uint32_t time, - wl_fixed_t sx, wl_fixed_t sy); - static void inputHandleButton(void *data, - struct wl_input_device *input_device, - uint32_t serial, uint32_t time, - uint32_t button, uint32_t state); - static void inputHandleAxis(void *data, - struct wl_input_device *wl_input_device, - uint32_t time, - uint32_t axis, - int32_t value); - static void inputHandleKey(void *data, - struct wl_input_device *input_device, + static const struct wl_seat_listener seatListener; + + static void seat_capabilities(void *data, + struct wl_seat *seat, + uint32_t caps); + + static const struct wl_pointer_listener pointerListener; + + static void pointer_enter(void *data, + struct wl_pointer *pointer, + uint32_t time, struct wl_surface *surface, + wl_fixed_t sx, wl_fixed_t sy); + static void pointer_leave(void *data, + struct wl_pointer *pointer, + uint32_t time, struct wl_surface *surface); + static void pointer_motion(void *data, + struct wl_pointer *pointer, + uint32_t time, + wl_fixed_t sx, wl_fixed_t sy); + static void pointer_button(void *data, + struct wl_pointer *pointer, uint32_t serial, uint32_t time, - uint32_t key, uint32_t state); - static void inputHandlePointerEnter(void *data, - struct wl_input_device *input_device, - uint32_t time, struct wl_surface *surface, - wl_fixed_t sx, wl_fixed_t sy); - static void inputHandlePointerLeave(void *data, - struct wl_input_device *input_device, - uint32_t time, struct wl_surface *surface); - static void inputHandleKeyboardEnter(void *data, - struct wl_input_device *input_device, - uint32_t time, - struct wl_surface *surface, - struct wl_array *keys); - static void inputHandleKeyboardLeave(void *data, - struct wl_input_device *input_device, - uint32_t time, - struct wl_surface *surface); - static void inputHandleTouchDown(void *data, - struct wl_input_device *wl_input_device, - uint32_t serial, - uint32_t time, - struct wl_surface *surface, - int32_t id, - wl_fixed_t x, - wl_fixed_t y); - static void inputHandleTouchUp(void *data, - struct wl_input_device *wl_input_device, - uint32_t serial, - uint32_t time, - int32_t id); - static void inputHandleTouchMotion(void *data, - struct wl_input_device *wl_input_device, - uint32_t time, - int32_t id, - wl_fixed_t x, - wl_fixed_t y); - static void inputHandleTouchFrame(void *data, - struct wl_input_device *wl_input_device); - static void inputHandleTouchCancel(void *data, - struct wl_input_device *wl_input_device); + uint32_t button, uint32_t state); + static void pointer_axis(void *data, + struct wl_pointer *pointer, + uint32_t time, + uint32_t axis, + int32_t value); + + static const struct wl_keyboard_listener keyboardListener; + + static void keyboard_enter(void *data, + struct wl_keyboard *keyboard, + uint32_t time, + struct wl_surface *surface, + struct wl_array *keys); + static void keyboard_leave(void *data, + struct wl_keyboard *keyboard, + uint32_t time, + struct wl_surface *surface); + static void keyboard_key(void *data, + struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, + uint32_t key, uint32_t state); + + static const struct wl_touch_listener touchListener; + + static void touch_down(void *data, + struct wl_touch *touch, + uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y); + static void touch_up(void *data, + struct wl_touch *touch, + uint32_t serial, + uint32_t time, + int32_t id); + static void touch_motion(void *data, + struct wl_touch *touch, + uint32_t time, + int32_t id, + wl_fixed_t x, + wl_fixed_t y); + static void touch_frame(void *data, + struct wl_touch *touch); + static void touch_cancel(void *data, + struct wl_touch *touch); void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); void handleTouchFrame(); diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp index fd8170f..8d7498a 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp @@ -57,12 +57,16 @@ QWaylandShellSurface::QWaylandShellSurface(struct wl_shell_surface *shell_surfac void QWaylandShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) { - wl_shell_surface_resize(m_shell_surface,inputDevice->wl_input_device(),QWaylandDisplay::currentTimeMillisec(),edges); + wl_shell_surface_resize(m_shell_surface,inputDevice->wl_seat(), + QWaylandDisplay::currentTimeMillisec(), + edges); } void QWaylandShellSurface::move(QWaylandInputDevice *inputDevice) { - wl_shell_surface_move(m_shell_surface,inputDevice->wl_input_device(),QWaylandDisplay::currentTimeMillisec()); + wl_shell_surface_move(m_shell_surface, + inputDevice->wl_seat(), + QWaylandDisplay::currentTimeMillisec()); } void QWaylandShellSurface::setTopLevel() diff --git a/tests/auto/client/mockcompositor.cpp b/tests/auto/client/mockcompositor.cpp index 6c7c66f..4e5537e 100644 --- a/tests/auto/client/mockcompositor.cpp +++ b/tests/auto/client/mockcompositor.cpp @@ -197,10 +197,14 @@ Compositor::Compositor() wl_display_add_socket(m_display, 0); - wl_input_device_init(&m_input); + wl_seat_init(&m_seat); + wl_pointer_init(&m_pointer); + wl_seat_set_pointer(&m_seat, &m_pointer); + wl_keyboard_init(&m_keyboard); + wl_seat_set_keyboard(&m_seat, &m_keyboard); wl_display_add_global(m_display, &wl_compositor_interface, this, bindCompositor); - wl_display_add_global(m_display, &wl_input_device_interface, this, bindInput); + wl_display_add_global(m_display, &wl_seat_interface, this, bindSeat); wl_display_add_global(m_display, &wl_output_interface, this, bindOutput); wl_display_add_global(m_display, &wl_shell_interface, this, bindShell); @@ -212,6 +216,8 @@ Compositor::Compositor() Compositor::~Compositor() { + wl_pointer_release(&m_pointer); + wl_keyboard_release(&m_keyboard); wl_display_destroy(m_display); } diff --git a/tests/auto/client/mockcompositor.h b/tests/auto/client/mockcompositor.h index c47f5f2..8805d7b 100644 --- a/tests/auto/client/mockcompositor.h +++ b/tests/auto/client/mockcompositor.h @@ -87,10 +87,14 @@ public: private: static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id); - static void bindInput(wl_client *client, void *data, uint32_t version, uint32_t id); + static void bindSeat(wl_client *client, void *data, uint32_t version, uint32_t id); static void bindOutput(wl_client *client, void *data, uint32_t version, uint32_t id); static void bindShell(wl_client *client, void *data, uint32_t version, uint32_t id); + static void get_pointer(wl_client *client, wl_resource *resource, uint32_t id); + static void get_keyboard(wl_client *client, wl_resource *resource, uint32_t id); + static void get_touch(wl_client *client, wl_resource *resource, uint32_t id); + static void destroyInputResource(wl_resource *resource); void initShm(); @@ -108,7 +112,9 @@ private: wl_list m_outputResources; uint32_t m_time; - wl_input_device m_input; + wl_seat m_seat; + wl_pointer m_pointer; + wl_keyboard m_keyboard; QVector m_surfaces; }; diff --git a/tests/auto/client/mockinput.cpp b/tests/auto/client/mockinput.cpp index f2a7640..8e67fc0 100644 --- a/tests/auto/client/mockinput.cpp +++ b/tests/auto/client/mockinput.cpp @@ -47,22 +47,29 @@ namespace Impl { void Compositor::destroyInputResource(wl_resource *resource) { Compositor *compositor = static_cast(resource->data); - wl_input_device *input = &compositor->m_input; + wl_keyboard *keyboard = &compositor->m_keyboard; + wl_pointer *pointer = &compositor->m_pointer; - if (input->keyboard_focus_resource == resource) - input->keyboard_focus_resource = 0; - if (input->pointer_focus_resource == resource) - input->pointer_focus_resource = 0; + if (keyboard->focus_resource == resource) + keyboard->focus_resource = 0; + if (pointer->focus_resource == resource) + pointer->focus_resource = 0; wl_list_remove(&resource->link); free(resource); } -void input_device_attach(wl_client *client, - wl_resource *device_resource, - uint32_t time, - wl_resource *buffer_resource, int32_t x, int32_t y) +static void destroyInputDevice(wl_resource *resource) +{ + wl_list_remove(&resource->link); + free(resource); +} + +void pointer_attach(wl_client *client, + wl_resource *device_resource, + uint32_t time, + wl_resource *buffer_resource, int32_t x, int32_t y) { Q_UNUSED(client); Q_UNUSED(device_resource); @@ -71,18 +78,64 @@ void input_device_attach(wl_client *client, Q_UNUSED(QPoint(x, y)); } -void Compositor::bindInput(wl_client *client, void *compositorData, uint32_t version, uint32_t id) +void Compositor::get_pointer(wl_client *client, + wl_resource *resource, + uint32_t id) { - static const struct wl_input_device_interface inputDeviceInterface = { - input_device_attach, + static const struct wl_pointer_interface pointer_interface = { + pointer_attach + }; + Compositor *compositor = static_cast(resource->data); + wl_pointer *pointer = &compositor->m_pointer; + wl_resource *clientResource = wl_client_add_object(client, + &wl_pointer_interface, + &pointer_interface, + id, + pointer); + wl_list_insert(&pointer->resource_list, &clientResource->link); + clientResource->destroy = destroyInputDevice; +} + +void Compositor::get_keyboard(wl_client *client, + wl_resource *resource, + uint32_t id) +{ + Compositor *compositor = static_cast(resource->data); + wl_keyboard *keyboard = &compositor->m_keyboard; + wl_resource *clientResource = wl_client_add_object(client, + &wl_keyboard_interface, + 0, + id, + keyboard); + wl_list_insert(&keyboard->resource_list, &clientResource->link); + clientResource->destroy = destroyInputDevice; +} + +void Compositor::get_touch(wl_client *client, + wl_resource *resource, + uint32_t id) +{ + Q_UNUSED(client); + Q_UNUSED(resource); + Q_UNUSED(id); +} + +void Compositor::bindSeat(wl_client *client, void *compositorData, uint32_t version, uint32_t id) +{ + static const struct wl_seat_interface seatInterface = { + get_pointer, + get_keyboard, + get_touch }; Q_UNUSED(version); - wl_resource *resource = wl_client_add_object(client, &wl_input_device_interface, &inputDeviceInterface, id, compositorData); + wl_resource *resource = wl_client_add_object(client, &wl_seat_interface, &seatInterface, id, compositorData); resource->destroy = destroyInputResource; Compositor *compositor = static_cast(compositorData); - wl_list_insert(&compositor->m_input.resource_list, &resource->link); + wl_list_insert(&compositor->m_seat.base_resource_list, &resource->link); + + wl_seat_send_capabilities(resource, WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD); } static wl_surface *resolveSurface(const QVariant &v) @@ -95,7 +148,7 @@ static wl_surface *resolveSurface(const QVariant &v) void Compositor::setKeyboardFocus(void *data, const QList ¶meters) { Compositor *compositor = static_cast(data); - wl_input_device_set_keyboard_focus(&compositor->m_input, resolveSurface(parameters.first())); + wl_keyboard_set_focus(&compositor->m_keyboard, resolveSurface(parameters.first())); } void Compositor::sendMousePress(void *data, const QList ¶meters) @@ -106,12 +159,12 @@ void Compositor::sendMousePress(void *data, const QList ¶meters) return; QPoint pos = parameters.last().toPoint(); - wl_input_device_set_pointer_focus(&compositor->m_input, surface, - wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); - wl_input_device_send_motion(compositor->m_input.pointer_focus_resource, compositor->time(), - wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); - wl_input_device_send_button(compositor->m_input.pointer_focus_resource, - compositor->nextSerial(), compositor->time(), 0x110, 1); + wl_pointer_set_focus(&compositor->m_pointer, surface, + wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); + wl_pointer_send_motion(compositor->m_pointer.focus_resource, compositor->time(), + wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); + wl_pointer_send_button(compositor->m_pointer.focus_resource, + compositor->nextSerial(), compositor->time(), 0x110, 1); } void Compositor::sendMouseRelease(void *data, const QList ¶meters) @@ -121,8 +174,8 @@ void Compositor::sendMouseRelease(void *data, const QList ¶meters) if (!surface) return; - wl_input_device_send_button(compositor->m_input.pointer_focus_resource, - compositor->nextSerial(), compositor->time(), 0x110, 0); + wl_pointer_send_button(compositor->m_pointer.focus_resource, + compositor->nextSerial(), compositor->time(), 0x110, 0); } void Compositor::sendKeyPress(void *data, const QList ¶meters) @@ -132,9 +185,8 @@ void Compositor::sendKeyPress(void *data, const QList ¶meters) if (!surface) return; - QPoint pos = parameters.last().toPoint(); - wl_input_device_send_key(compositor->m_input.keyboard_focus_resource, - compositor->nextSerial(), compositor->time(), parameters.last().toUInt() - 8, 1); + wl_keyboard_send_key(compositor->m_keyboard.focus_resource, + compositor->nextSerial(), compositor->time(), parameters.last().toUInt() - 8, 1); } void Compositor::sendKeyRelease(void *data, const QList ¶meters) @@ -144,9 +196,8 @@ void Compositor::sendKeyRelease(void *data, const QList ¶meters) if (!surface) return; - wl_input_device_send_key(compositor->m_input.keyboard_focus_resource, - compositor->nextSerial(), compositor->time(), parameters.last().toUInt() - 8, 0); + wl_keyboard_send_key(compositor->m_keyboard.focus_resource, + compositor->nextSerial(), compositor->time(), parameters.last().toUInt() - 8, 0); } } - diff --git a/wayland_sha1.txt b/wayland_sha1.txt index 05da057..124705e 100644 --- a/wayland_sha1.txt +++ b/wayland_sha1.txt @@ -1,3 +1,3 @@ This version of Qt-Compositor is checked against the following sha1 from the Wayland repository: -6b8816bab46172abc975674dcefadcea4edcef08 +94bb47020ae71336be5088824fee38bf3c8d51cc -- 2.7.4