From e6b91f5628c5b4be408e175a935e6c011e2d08bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 25 Nov 2014 13:52:40 +0100 Subject: [PATCH] [server] Move PointerInterface into own .h and .cpp --- src/wayland/CMakeLists.txt | 2 + .../autotests/client/test_datadevice.cpp | 1 + .../autotests/client/test_wayland_seat.cpp | 1 + src/wayland/autotests/server/test_seat.cpp | 1 + src/wayland/datadevice_interface.cpp | 1 + src/wayland/pointer_interface.cpp | 378 ++++++++++++++++++ src/wayland/pointer_interface.h | 80 ++++ src/wayland/seat_interface.cpp | 347 +--------------- src/wayland/seat_interface.h | 37 -- src/wayland/tests/renderingservertest.cpp | 1 + 10 files changed, 466 insertions(+), 383 deletions(-) create mode 100644 src/wayland/pointer_interface.cpp create mode 100644 src/wayland/pointer_interface.h diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 7ae805aaec..1fe83b7594 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -10,6 +10,7 @@ set(SERVER_LIB_SRCS global.cpp keyboard_interface.cpp output_interface.cpp + pointer_interface.cpp region_interface.cpp resource.cpp seat_interface.cpp @@ -62,6 +63,7 @@ set_target_properties(KF5WaylandServer PROPERTIES VERSION ${KWAYLAND_VERSION_S # global.h # keyboard_interface.h # output_interface.h +# pointer_interface.h # region_interface.h # resource.h # seat_interface.h diff --git a/src/wayland/autotests/client/test_datadevice.cpp b/src/wayland/autotests/client/test_datadevice.cpp index fc9398d54b..c6bd56d07c 100644 --- a/src/wayland/autotests/client/test_datadevice.cpp +++ b/src/wayland/autotests/client/test_datadevice.cpp @@ -34,6 +34,7 @@ License along with this library. If not, see . #include "../../src/server/datadevicemanager_interface.h" #include "../../src/server/datasource_interface.h" #include "../../src/server/compositor_interface.h" +#include "../../src/server/pointer_interface.h" #include "../../src/server/seat_interface.h" #include "../../src/server/surface_interface.h" // Wayland diff --git a/src/wayland/autotests/client/test_wayland_seat.cpp b/src/wayland/autotests/client/test_wayland_seat.cpp index 3bcb892be4..7db5653121 100644 --- a/src/wayland/autotests/client/test_wayland_seat.cpp +++ b/src/wayland/autotests/client/test_wayland_seat.cpp @@ -33,6 +33,7 @@ License along with this library. If not, see . #include "../../src/server/compositor_interface.h" #include "../../src/server/display.h" #include "../../src/server/keyboard_interface.h" +#include "../../src/server/pointer_interface.h" #include "../../src/server/seat_interface.h" #include "../../src/server/surface_interface.h" // Wayland diff --git a/src/wayland/autotests/server/test_seat.cpp b/src/wayland/autotests/server/test_seat.cpp index 10e702a4b3..8698d9d3cc 100644 --- a/src/wayland/autotests/server/test_seat.cpp +++ b/src/wayland/autotests/server/test_seat.cpp @@ -21,6 +21,7 @@ License along with this library. If not, see . #include // WaylandServer #include "../../src/server/display.h" +#include "../../src/server/pointer_interface.h" #include "../../src/server/seat_interface.h" using namespace KWayland::Server; diff --git a/src/wayland/datadevice_interface.cpp b/src/wayland/datadevice_interface.cpp index 79559ff6b0..4caa337f4c 100644 --- a/src/wayland/datadevice_interface.cpp +++ b/src/wayland/datadevice_interface.cpp @@ -23,6 +23,7 @@ License along with this library. If not, see . #include "datasource_interface.h" #include "display.h" #include "resource_p.h" +#include "pointer_interface.h" #include "seat_interface.h" #include "surface_interface.h" // Wayland diff --git a/src/wayland/pointer_interface.cpp b/src/wayland/pointer_interface.cpp new file mode 100644 index 0000000000..2d4faefc46 --- /dev/null +++ b/src/wayland/pointer_interface.cpp @@ -0,0 +1,378 @@ +/******************************************************************** +Copyright 2014 Martin Gräßlin + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ +#include "pointer_interface.h" +#include "seat_interface.h" +#include "display.h" +#include "surface_interface.h" +// Qt +#include +// Wayland +#include +// linux +#include + +namespace KWayland +{ + +namespace Server +{ + +class PointerInterface::Private +{ +public: + Private(Display *display, SeatInterface *parent); + void createInterface(wl_client *client, wl_resource *parentResource, uint32_t id); + wl_resource *pointerForSurface(SurfaceInterface *surface) const; + void surfaceDeleted(); + void updateButtonSerial(quint32 button, quint32 serial); + enum class ButtonState { + Released, + Pressed + }; + void updateButtonState(quint32 button, ButtonState state); + + Display *display; + SeatInterface *seat; + struct ResourceData { + wl_client *client = nullptr; + wl_resource *pointer = nullptr; + }; + QList resources; + quint32 eventTime = 0; + QPoint globalPos; + struct FocusedSurface { + SurfaceInterface *surface = nullptr; + QPoint offset = QPoint(); + wl_resource *pointer = nullptr; + quint32 serial = 0; + }; + FocusedSurface focusedSurface; + QHash buttonSerials; + QHash buttonStates; + QMetaObject::Connection destroyConnection; + +private: + static PointerInterface::Private *cast(wl_resource *resource) { + return reinterpret_cast(wl_resource_get_user_data(resource)); + } + + static void unbind(wl_resource *resource); + // interface + static void setCursorCallback(wl_client *client, wl_resource *resource, uint32_t serial, + wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y); + // since version 3 + static void releaseCallback(wl_client *client, wl_resource *resource); + + static const struct wl_pointer_interface s_interface; +}; + +PointerInterface::Private::Private(Display *display, SeatInterface *parent) + : display(display) + , seat(parent) +{ +} + + +const struct wl_pointer_interface PointerInterface::Private::s_interface = { + setCursorCallback, + releaseCallback +}; + +PointerInterface::PointerInterface(Display *display, SeatInterface *parent) + : QObject(parent) + , d(new Private(display, parent)) +{ +} + +PointerInterface::~PointerInterface() +{ + while (!d->resources.isEmpty()) { + auto data = d->resources.takeLast(); + wl_resource_destroy(data.pointer); + } +} + +void PointerInterface::createInterface(wl_client *client, wl_resource *parentResource, uint32_t id) +{ + d->createInterface(client, parentResource, id); +} + +void PointerInterface::Private::createInterface(wl_client* client, wl_resource* parentResource, uint32_t id) +{ + wl_resource *p = wl_resource_create(client, &wl_pointer_interface, wl_resource_get_version(parentResource), id); + if (!p) { + wl_resource_post_no_memory(parentResource); + return; + } + ResourceData data; + data.client = client; + data.pointer = p; + resources << data; + + wl_resource_set_implementation(p, &s_interface, this, unbind); +} + +wl_resource *PointerInterface::Private::pointerForSurface(SurfaceInterface *surface) const +{ + if (!surface) { + return nullptr; + } + for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) { + if ((*it).client == *surface->client()) { + return (*it).pointer; + } + } + return nullptr; +} + +void PointerInterface::setFocusedSurface(SurfaceInterface *surface, const QPoint &surfacePosition) +{ + const quint32 serial = d->display->nextSerial(); + if (d->focusedSurface.surface && d->focusedSurface.pointer) { + wl_pointer_send_leave(d->focusedSurface.pointer, serial, d->focusedSurface.surface->resource()); + disconnect(d->destroyConnection); + } + d->focusedSurface.pointer = d->pointerForSurface(surface); + if (!d->focusedSurface.pointer) { + d->focusedSurface = Private::FocusedSurface(); + return; + } + d->focusedSurface.surface = surface; + d->focusedSurface.offset = surfacePosition; + d->focusedSurface.serial = serial; + d->destroyConnection = connect(d->focusedSurface.surface, &QObject::destroyed, this, [this] { d->surfaceDeleted(); }); + + const QPoint pos = d->globalPos - surfacePosition; + wl_pointer_send_enter(d->focusedSurface.pointer, d->focusedSurface.serial, + d->focusedSurface.surface->resource(), + wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); +} + +void PointerInterface::Private::surfaceDeleted() +{ + focusedSurface = FocusedSurface(); +} + +void PointerInterface::setFocusedSurfacePosition(const QPoint &surfacePosition) +{ + if (!d->focusedSurface.surface) { + return; + } + d->focusedSurface.offset = surfacePosition; +} + +void PointerInterface::setGlobalPos(const QPoint &pos) +{ + if (d->globalPos == pos) { + return; + } + d->globalPos = pos; + if (d->focusedSurface.surface && d->focusedSurface.pointer) { + const QPoint pos = d->globalPos - d->focusedSurface.offset; + wl_pointer_send_motion(d->focusedSurface.pointer, d->eventTime, + wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); + } + emit globalPosChanged(d->globalPos); +} + +void PointerInterface::updateTimestamp(quint32 time) +{ + d->eventTime = time; +} + +static quint32 qtToWaylandButton(Qt::MouseButton button) +{ + static const QHash s_buttons({ + {Qt::LeftButton, BTN_LEFT}, + {Qt::RightButton, BTN_RIGHT}, + {Qt::MiddleButton, BTN_MIDDLE}, + {Qt::ExtraButton1, BTN_BACK}, // note: QtWayland maps BTN_SIDE + {Qt::ExtraButton2, BTN_FORWARD}, // note: QtWayland maps BTN_EXTRA + {Qt::ExtraButton3, BTN_TASK}, // note: QtWayland maps BTN_FORWARD + {Qt::ExtraButton4, BTN_EXTRA}, // note: QtWayland maps BTN_BACK + {Qt::ExtraButton5, BTN_SIDE}, // note: QtWayland maps BTN_TASK + {Qt::ExtraButton6, BTN_TASK + 1}, + {Qt::ExtraButton7, BTN_TASK + 2}, + {Qt::ExtraButton8, BTN_TASK + 3}, + {Qt::ExtraButton9, BTN_TASK + 4}, + {Qt::ExtraButton10, BTN_TASK + 5}, + {Qt::ExtraButton11, BTN_TASK + 6}, + {Qt::ExtraButton12, BTN_TASK + 7}, + {Qt::ExtraButton13, BTN_TASK + 8} + // further mapping not possible, 0x120 is BTN_JOYSTICK + }); + return s_buttons.value(button, 0); +}; + +void PointerInterface::buttonPressed(quint32 button) +{ + const quint32 serial = d->display->nextSerial(); + d->updateButtonSerial(button, serial); + d->updateButtonState(button, Private::ButtonState::Pressed); + if (!d->focusedSurface.surface || !d->focusedSurface.pointer) { + return; + } + wl_pointer_send_button(d->focusedSurface.pointer, serial, d->eventTime, button, WL_POINTER_BUTTON_STATE_PRESSED); +} + +void PointerInterface::buttonPressed(Qt::MouseButton button) +{ + const quint32 nativeButton = qtToWaylandButton(button); + if (nativeButton == 0) { + return; + } + buttonPressed(nativeButton); +} + +void PointerInterface::buttonReleased(quint32 button) +{ + const quint32 serial = d->display->nextSerial(); + d->updateButtonSerial(button, serial); + d->updateButtonState(button, Private::ButtonState::Released); + if (!d->focusedSurface.surface || !d->focusedSurface.pointer) { + return; + } + wl_pointer_send_button(d->focusedSurface.pointer, serial, d->eventTime, button, WL_POINTER_BUTTON_STATE_RELEASED); +} + +void PointerInterface::buttonReleased(Qt::MouseButton button) +{ + const quint32 nativeButton = qtToWaylandButton(button); + if (nativeButton == 0) { + return; + } + buttonReleased(nativeButton); +} + +void PointerInterface::Private::updateButtonSerial(quint32 button, quint32 serial) +{ + auto it = buttonSerials.find(button); + if (it == buttonSerials.end()) { + buttonSerials.insert(button, serial); + return; + } + it.value() = serial; +} + +quint32 PointerInterface::buttonSerial(quint32 button) const +{ + auto it = d->buttonSerials.constFind(button); + if (it == d->buttonSerials.constEnd()) { + return 0; + } + return it.value(); +} + +quint32 PointerInterface::buttonSerial(Qt::MouseButton button) const +{ + return buttonSerial(qtToWaylandButton(button)); +} + +void PointerInterface::Private::updateButtonState(quint32 button, ButtonState state) +{ + auto it = buttonStates.find(button); + if (it == buttonStates.end()) { + buttonStates.insert(button, state); + return; + } + it.value() = state; +} + +bool PointerInterface::isButtonPressed(quint32 button) const +{ + auto it = d->buttonStates.constFind(button); + if (it == d->buttonStates.constEnd()) { + return false; + } + return it.value() == Private::ButtonState::Pressed ? true : false; +} + +bool PointerInterface::isButtonPressed(Qt::MouseButton button) const +{ + const quint32 nativeButton = qtToWaylandButton(button); + if (nativeButton == 0) { + return false; + } + return isButtonPressed(nativeButton); +} + +void PointerInterface::axis(Qt::Orientation orientation, quint32 delta) +{ + if (!d->focusedSurface.surface || !d->focusedSurface.pointer) { + return; + } + wl_pointer_send_axis(d->focusedSurface.pointer, d->eventTime, + (orientation == Qt::Vertical) ? WL_POINTER_AXIS_VERTICAL_SCROLL : WL_POINTER_AXIS_HORIZONTAL_SCROLL, + wl_fixed_from_int(delta)); +} + +void PointerInterface::Private::unbind(wl_resource *resource) +{ + auto p = cast(resource); + auto it = std::find_if(p->resources.begin(), p->resources.end(), + [resource](const ResourceData &data) { + return data.pointer == resource; + } + ); + if (it == p->resources.end()) { + return; + } + if ((*it).pointer == p->focusedSurface.pointer) { + QObject::disconnect(p->destroyConnection); + p->focusedSurface = FocusedSurface(); + } + p->resources.erase(it); +} + +void PointerInterface::Private::setCursorCallback(wl_client *client, wl_resource *resource, uint32_t serial, + wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) +{ + Q_UNUSED(client) + Q_UNUSED(resource) + Q_UNUSED(serial) + Q_UNUSED(surface) + Q_UNUSED(hotspot_x) + Q_UNUSED(hotspot_y) + // TODO: implement +} + +void PointerInterface::Private::releaseCallback(wl_client *client, wl_resource *resource) +{ + Q_UNUSED(client) + unbind(resource); +} + +QPoint PointerInterface::globalPos() const +{ + return d->globalPos; +} + +SurfaceInterface *PointerInterface::focusedSurface() const +{ + return d->focusedSurface.surface; +} + +QPoint PointerInterface::focusedSurfacePosition() const +{ + return d->focusedSurface.offset; +} + +} +} diff --git a/src/wayland/pointer_interface.h b/src/wayland/pointer_interface.h new file mode 100644 index 0000000000..ea3d4c0797 --- /dev/null +++ b/src/wayland/pointer_interface.h @@ -0,0 +1,80 @@ +/******************************************************************** +Copyright 2014 Martin Gräßlin + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ +#ifndef WAYLAND_SERVER_POINTER_INTERFACE_H +#define WAYLAND_SERVER_POINTER_INTERFACE_H + +#include +#include + +#include + +struct wl_client; +struct wl_resource; + +namespace KWayland +{ +namespace Server +{ + +class Display; +class SeatInterface; +class SurfaceInterface; + +class KWAYLANDSERVER_EXPORT PointerInterface : public QObject +{ + Q_OBJECT + Q_PROPERTY(QPoint globalPos READ globalPos WRITE setGlobalPos NOTIFY globalPosChanged) +public: + virtual ~PointerInterface(); + + void createInterface(wl_client *client, wl_resource *parentResource, uint32_t id); + + void updateTimestamp(quint32 time); + void setGlobalPos(const QPoint &pos); + QPoint globalPos() const; + void buttonPressed(quint32 button); + void buttonPressed(Qt::MouseButton button); + void buttonReleased(quint32 button); + void buttonReleased(Qt::MouseButton button); + bool isButtonPressed(quint32 button) const; + bool isButtonPressed(Qt::MouseButton button) const; + quint32 buttonSerial(quint32 button) const; + quint32 buttonSerial(Qt::MouseButton button) const; + void axis(Qt::Orientation orientation, quint32 delta); + + void setFocusedSurface(SurfaceInterface *surface, const QPoint &surfacePosition = QPoint()); + void setFocusedSurfacePosition(const QPoint &surfacePosition); + SurfaceInterface *focusedSurface() const; + QPoint focusedSurfacePosition() const; + +Q_SIGNALS: + void globalPosChanged(const QPoint &pos); + +private: + friend class SeatInterface; + explicit PointerInterface(Display *display, SeatInterface *parent); + class Private; + QScopedPointer d; +}; + +} +} + +#endif diff --git a/src/wayland/seat_interface.cpp b/src/wayland/seat_interface.cpp index 2cad806d47..acd410e93c 100644 --- a/src/wayland/seat_interface.cpp +++ b/src/wayland/seat_interface.cpp @@ -21,6 +21,7 @@ License along with this library. If not, see . #include "global_p.h" #include "display.h" #include "keyboard_interface.h" +#include "pointer_interface.h" #include "surface_interface.h" // Qt #include @@ -29,8 +30,6 @@ License along with this library. If not, see . #ifndef WL_SEAT_NAME_SINCE_VERSION #define WL_SEAT_NAME_SINCE_VERSION 2 #endif -// linux -#include namespace KWayland { @@ -268,349 +267,5 @@ SeatInterface::Private *SeatInterface::d_func() const return reinterpret_cast(d.data()); } -/**************************************** - * PointerInterface - ***************************************/ - -class PointerInterface::Private -{ -public: - Private(Display *display, SeatInterface *parent); - void createInterface(wl_client *client, wl_resource *parentResource, uint32_t id); - wl_resource *pointerForSurface(SurfaceInterface *surface) const; - void surfaceDeleted(); - void updateButtonSerial(quint32 button, quint32 serial); - enum class ButtonState { - Released, - Pressed - }; - void updateButtonState(quint32 button, ButtonState state); - - Display *display; - SeatInterface *seat; - struct ResourceData { - wl_client *client = nullptr; - wl_resource *pointer = nullptr; - }; - QList resources; - quint32 eventTime = 0; - QPoint globalPos; - struct FocusedSurface { - SurfaceInterface *surface = nullptr; - QPoint offset = QPoint(); - wl_resource *pointer = nullptr; - quint32 serial = 0; - }; - FocusedSurface focusedSurface; - QHash buttonSerials; - QHash buttonStates; - QMetaObject::Connection destroyConnection; - -private: - static PointerInterface::Private *cast(wl_resource *resource) { - return reinterpret_cast(wl_resource_get_user_data(resource)); - } - - static void unbind(wl_resource *resource); - // interface - static void setCursorCallback(wl_client *client, wl_resource *resource, uint32_t serial, - wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y); - // since version 3 - static void releaseCallback(wl_client *client, wl_resource *resource); - - static const struct wl_pointer_interface s_interface; -}; - -PointerInterface::Private::Private(Display *display, SeatInterface *parent) - : display(display) - , seat(parent) -{ -} - - -const struct wl_pointer_interface PointerInterface::Private::s_interface = { - setCursorCallback, - releaseCallback -}; - -PointerInterface::PointerInterface(Display *display, SeatInterface *parent) - : QObject(parent) - , d(new Private(display, parent)) -{ -} - -PointerInterface::~PointerInterface() -{ - while (!d->resources.isEmpty()) { - auto data = d->resources.takeLast(); - wl_resource_destroy(data.pointer); - } -} - -void PointerInterface::createInterface(wl_client *client, wl_resource *parentResource, uint32_t id) -{ - d->createInterface(client, parentResource, id); -} - -void PointerInterface::Private::createInterface(wl_client* client, wl_resource* parentResource, uint32_t id) -{ - wl_resource *p = wl_resource_create(client, &wl_pointer_interface, wl_resource_get_version(parentResource), id); - if (!p) { - wl_resource_post_no_memory(parentResource); - return; - } - ResourceData data; - data.client = client; - data.pointer = p; - resources << data; - - wl_resource_set_implementation(p, &s_interface, this, unbind); -} - -wl_resource *PointerInterface::Private::pointerForSurface(SurfaceInterface *surface) const -{ - if (!surface) { - return nullptr; - } - for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) { - if ((*it).client == *surface->client()) { - return (*it).pointer; - } - } - return nullptr; -} - -void PointerInterface::setFocusedSurface(SurfaceInterface *surface, const QPoint &surfacePosition) -{ - const quint32 serial = d->display->nextSerial(); - if (d->focusedSurface.surface && d->focusedSurface.pointer) { - wl_pointer_send_leave(d->focusedSurface.pointer, serial, d->focusedSurface.surface->resource()); - disconnect(d->destroyConnection); - } - d->focusedSurface.pointer = d->pointerForSurface(surface); - if (!d->focusedSurface.pointer) { - d->focusedSurface = Private::FocusedSurface(); - return; - } - d->focusedSurface.surface = surface; - d->focusedSurface.offset = surfacePosition; - d->focusedSurface.serial = serial; - d->destroyConnection = connect(d->focusedSurface.surface, &QObject::destroyed, this, [this] { d->surfaceDeleted(); }); - - const QPoint pos = d->globalPos - surfacePosition; - wl_pointer_send_enter(d->focusedSurface.pointer, d->focusedSurface.serial, - d->focusedSurface.surface->resource(), - wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); -} - -void PointerInterface::Private::surfaceDeleted() -{ - focusedSurface = FocusedSurface(); -} - -void PointerInterface::setFocusedSurfacePosition(const QPoint &surfacePosition) -{ - if (!d->focusedSurface.surface) { - return; - } - d->focusedSurface.offset = surfacePosition; -} - -void PointerInterface::setGlobalPos(const QPoint &pos) -{ - if (d->globalPos == pos) { - return; - } - d->globalPos = pos; - if (d->focusedSurface.surface && d->focusedSurface.pointer) { - const QPoint pos = d->globalPos - d->focusedSurface.offset; - wl_pointer_send_motion(d->focusedSurface.pointer, d->eventTime, - wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); - } - emit globalPosChanged(d->globalPos); -} - -void PointerInterface::updateTimestamp(quint32 time) -{ - d->eventTime = time; -} - -static quint32 qtToWaylandButton(Qt::MouseButton button) -{ - static const QHash s_buttons({ - {Qt::LeftButton, BTN_LEFT}, - {Qt::RightButton, BTN_RIGHT}, - {Qt::MiddleButton, BTN_MIDDLE}, - {Qt::ExtraButton1, BTN_BACK}, // note: QtWayland maps BTN_SIDE - {Qt::ExtraButton2, BTN_FORWARD}, // note: QtWayland maps BTN_EXTRA - {Qt::ExtraButton3, BTN_TASK}, // note: QtWayland maps BTN_FORWARD - {Qt::ExtraButton4, BTN_EXTRA}, // note: QtWayland maps BTN_BACK - {Qt::ExtraButton5, BTN_SIDE}, // note: QtWayland maps BTN_TASK - {Qt::ExtraButton6, BTN_TASK + 1}, - {Qt::ExtraButton7, BTN_TASK + 2}, - {Qt::ExtraButton8, BTN_TASK + 3}, - {Qt::ExtraButton9, BTN_TASK + 4}, - {Qt::ExtraButton10, BTN_TASK + 5}, - {Qt::ExtraButton11, BTN_TASK + 6}, - {Qt::ExtraButton12, BTN_TASK + 7}, - {Qt::ExtraButton13, BTN_TASK + 8} - // further mapping not possible, 0x120 is BTN_JOYSTICK - }); - return s_buttons.value(button, 0); -}; - -void PointerInterface::buttonPressed(quint32 button) -{ - const quint32 serial = d->display->nextSerial(); - d->updateButtonSerial(button, serial); - d->updateButtonState(button, Private::ButtonState::Pressed); - if (!d->focusedSurface.surface || !d->focusedSurface.pointer) { - return; - } - wl_pointer_send_button(d->focusedSurface.pointer, serial, d->eventTime, button, WL_POINTER_BUTTON_STATE_PRESSED); -} - -void PointerInterface::buttonPressed(Qt::MouseButton button) -{ - const quint32 nativeButton = qtToWaylandButton(button); - if (nativeButton == 0) { - return; - } - buttonPressed(nativeButton); -} - -void PointerInterface::buttonReleased(quint32 button) -{ - const quint32 serial = d->display->nextSerial(); - d->updateButtonSerial(button, serial); - d->updateButtonState(button, Private::ButtonState::Released); - if (!d->focusedSurface.surface || !d->focusedSurface.pointer) { - return; - } - wl_pointer_send_button(d->focusedSurface.pointer, serial, d->eventTime, button, WL_POINTER_BUTTON_STATE_RELEASED); -} - -void PointerInterface::buttonReleased(Qt::MouseButton button) -{ - const quint32 nativeButton = qtToWaylandButton(button); - if (nativeButton == 0) { - return; - } - buttonReleased(nativeButton); -} - -void PointerInterface::Private::updateButtonSerial(quint32 button, quint32 serial) -{ - auto it = buttonSerials.find(button); - if (it == buttonSerials.end()) { - buttonSerials.insert(button, serial); - return; - } - it.value() = serial; -} - -quint32 PointerInterface::buttonSerial(quint32 button) const -{ - auto it = d->buttonSerials.constFind(button); - if (it == d->buttonSerials.constEnd()) { - return 0; - } - return it.value(); -} - -quint32 PointerInterface::buttonSerial(Qt::MouseButton button) const -{ - return buttonSerial(qtToWaylandButton(button)); -} - -void PointerInterface::Private::updateButtonState(quint32 button, ButtonState state) -{ - auto it = buttonStates.find(button); - if (it == buttonStates.end()) { - buttonStates.insert(button, state); - return; - } - it.value() = state; -} - -bool PointerInterface::isButtonPressed(quint32 button) const -{ - auto it = d->buttonStates.constFind(button); - if (it == d->buttonStates.constEnd()) { - return false; - } - return it.value() == Private::ButtonState::Pressed ? true : false; -} - -bool PointerInterface::isButtonPressed(Qt::MouseButton button) const -{ - const quint32 nativeButton = qtToWaylandButton(button); - if (nativeButton == 0) { - return false; - } - return isButtonPressed(nativeButton); -} - -void PointerInterface::axis(Qt::Orientation orientation, quint32 delta) -{ - if (!d->focusedSurface.surface || !d->focusedSurface.pointer) { - return; - } - wl_pointer_send_axis(d->focusedSurface.pointer, d->eventTime, - (orientation == Qt::Vertical) ? WL_POINTER_AXIS_VERTICAL_SCROLL : WL_POINTER_AXIS_HORIZONTAL_SCROLL, - wl_fixed_from_int(delta)); -} - -void PointerInterface::Private::unbind(wl_resource *resource) -{ - auto p = cast(resource); - auto it = std::find_if(p->resources.begin(), p->resources.end(), - [resource](const ResourceData &data) { - return data.pointer == resource; - } - ); - if (it == p->resources.end()) { - return; - } - if ((*it).pointer == p->focusedSurface.pointer) { - QObject::disconnect(p->destroyConnection); - p->focusedSurface = FocusedSurface(); - } - p->resources.erase(it); -} - -void PointerInterface::Private::setCursorCallback(wl_client *client, wl_resource *resource, uint32_t serial, - wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) -{ - Q_UNUSED(client) - Q_UNUSED(resource) - Q_UNUSED(serial) - Q_UNUSED(surface) - Q_UNUSED(hotspot_x) - Q_UNUSED(hotspot_y) - // TODO: implement -} - -void PointerInterface::Private::releaseCallback(wl_client *client, wl_resource *resource) -{ - Q_UNUSED(client) - unbind(resource); -} - -QPoint PointerInterface::globalPos() const -{ - return d->globalPos; -} - -SurfaceInterface *PointerInterface::focusedSurface() const -{ - return d->focusedSurface.surface; -} - -QPoint PointerInterface::focusedSurfacePosition() const -{ - return d->focusedSurface.offset; -} - } } diff --git a/src/wayland/seat_interface.h b/src/wayland/seat_interface.h index 98a5f23824..deada594f3 100644 --- a/src/wayland/seat_interface.h +++ b/src/wayland/seat_interface.h @@ -77,43 +77,6 @@ private: Private *d_func() const; }; -class KWAYLANDSERVER_EXPORT PointerInterface : public QObject -{ - Q_OBJECT - Q_PROPERTY(QPoint globalPos READ globalPos WRITE setGlobalPos NOTIFY globalPosChanged) -public: - virtual ~PointerInterface(); - - void createInterface(wl_client *client, wl_resource *parentResource, uint32_t id); - - void updateTimestamp(quint32 time); - void setGlobalPos(const QPoint &pos); - QPoint globalPos() const; - void buttonPressed(quint32 button); - void buttonPressed(Qt::MouseButton button); - void buttonReleased(quint32 button); - void buttonReleased(Qt::MouseButton button); - bool isButtonPressed(quint32 button) const; - bool isButtonPressed(Qt::MouseButton button) const; - quint32 buttonSerial(quint32 button) const; - quint32 buttonSerial(Qt::MouseButton button) const; - void axis(Qt::Orientation orientation, quint32 delta); - - void setFocusedSurface(SurfaceInterface *surface, const QPoint &surfacePosition = QPoint()); - void setFocusedSurfacePosition(const QPoint &surfacePosition); - SurfaceInterface *focusedSurface() const; - QPoint focusedSurfacePosition() const; - -Q_SIGNALS: - void globalPosChanged(const QPoint &pos); - -private: - friend class SeatInterface; - explicit PointerInterface(Display *display, SeatInterface *parent); - class Private; - QScopedPointer d; -}; - } } diff --git a/src/wayland/tests/renderingservertest.cpp b/src/wayland/tests/renderingservertest.cpp index 94213d48c2..f6af3ed9ef 100644 --- a/src/wayland/tests/renderingservertest.cpp +++ b/src/wayland/tests/renderingservertest.cpp @@ -22,6 +22,7 @@ License along with this library. If not, see . #include "../src/server/display.h" #include "../src/server/keyboard_interface.h" #include "../src/server/output_interface.h" +#include "../src/server/pointer_interface.h" #include "../src/server/seat_interface.h" #include "../src/server/shell_interface.h"