File indexing completed on 2024-05-12 17:07:27

0001 /*
0002     SPDX-FileCopyrightText: 2022 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "tabletevents.h"
0008 #include "qwayland-tablet-unstable-v2.h"
0009 #include <QQuickWindow>
0010 #include <QWaylandClientExtensionTemplate>
0011 #include <qguiapplication.h>
0012 #include <qpa/qplatformnativeinterface.h>
0013 #include <qtwaylandclientversion.h>
0014 
0015 class TabletPad : public QObject, public QtWayland::zwp_tablet_pad_v2
0016 {
0017 public:
0018     TabletPad(TabletEvents *events, ::zwp_tablet_pad_v2 *t)
0019         : QObject(events)
0020         , QtWayland::zwp_tablet_pad_v2(t)
0021         , m_events(events)
0022     {
0023     }
0024 
0025     ~TabletPad()
0026     {
0027         destroy();
0028     }
0029 
0030     void zwp_tablet_pad_v2_path(const QString &path) override
0031     {
0032         m_path = path;
0033     }
0034 
0035     void zwp_tablet_pad_v2_buttons(uint32_t buttons) override
0036     {
0037         m_buttons = buttons;
0038     }
0039 
0040     void zwp_tablet_pad_v2_done() override
0041     {
0042         m_events->padButtonsChanged(m_path, m_buttons);
0043     }
0044 
0045     void zwp_tablet_pad_v2_button(uint32_t /*time*/, uint32_t button, uint32_t state) override
0046     {
0047         Q_EMIT m_events->padButtonReceived(m_path, button, state);
0048     }
0049 
0050     TabletEvents *const m_events;
0051     QString m_path;
0052     uint m_buttons = 0;
0053 };
0054 
0055 class Tool : public QObject, public QtWayland::zwp_tablet_tool_v2
0056 {
0057 public:
0058     Tool(TabletEvents *const events, ::zwp_tablet_tool_v2 *t)
0059         : QObject(events)
0060         , QtWayland::zwp_tablet_tool_v2(t)
0061         , m_events(events)
0062     {
0063     }
0064 
0065     ~Tool()
0066     {
0067         destroy();
0068     }
0069 
0070     void zwp_tablet_tool_v2_hardware_serial(uint32_t hardware_serial_hi, uint32_t hardware_serial_lo) override
0071     {
0072         m_hardware_serial_hi = hardware_serial_hi;
0073         m_hardware_serial_lo = hardware_serial_lo;
0074     }
0075 
0076     void zwp_tablet_tool_v2_button(uint32_t /*serial*/, uint32_t button, uint32_t state) override
0077     {
0078         Q_EMIT m_events->toolButtonReceived(m_hardware_serial_hi, m_hardware_serial_lo, button, state);
0079     }
0080 
0081     uint32_t m_hardware_serial_hi = 0;
0082     uint32_t m_hardware_serial_lo = 0;
0083     TabletEvents *const m_events;
0084 };
0085 
0086 class TabletManager : public QWaylandClientExtensionTemplate<TabletManager>, public QtWayland::zwp_tablet_manager_v2
0087 {
0088 public:
0089     TabletManager(TabletEvents *q)
0090         : QWaylandClientExtensionTemplate<TabletManager>(ZWP_TABLET_MANAGER_V2_GET_TABLET_SEAT_SINCE_VERSION)
0091         , q(q)
0092     {
0093         setParent(q);
0094 #if QTWAYLANDCLIENT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
0095         initialize();
0096 #else
0097         // QWaylandClientExtensionTemplate invokes this with a QueuedConnection but we want it called immediately
0098         QMetaObject::invokeMethod(this, "addRegistryListener", Qt::DirectConnection);
0099 #endif
0100         Q_ASSERT(isInitialized());
0101     }
0102 
0103     ~TabletManager()
0104     {
0105         destroy();
0106     }
0107 
0108     TabletEvents *const q;
0109 };
0110 
0111 class TabletSeat : public QObject, public QtWayland::zwp_tablet_seat_v2
0112 {
0113 public:
0114     TabletSeat(TabletEvents *events, ::zwp_tablet_seat_v2 *seat)
0115         : QObject(events)
0116         , QtWayland::zwp_tablet_seat_v2(seat)
0117         , m_events(events)
0118     {
0119     }
0120 
0121     ~TabletSeat()
0122     {
0123         destroy();
0124     }
0125 
0126     void zwp_tablet_seat_v2_tool_added(struct ::zwp_tablet_tool_v2 *id) override
0127     {
0128         new Tool(m_events, id);
0129     }
0130 
0131     void zwp_tablet_seat_v2_pad_added(struct ::zwp_tablet_pad_v2 *id) override
0132     {
0133         new TabletPad(m_events, id);
0134     }
0135 
0136     TabletEvents *const m_events;
0137 };
0138 
0139 TabletEvents::TabletEvents(QQuickItem *parent)
0140     : QQuickItem(parent)
0141 {
0142     auto seat = static_cast<wl_seat *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_seat"));
0143 
0144     auto tabletClient = new TabletManager(this);
0145     auto _seat = tabletClient->get_tablet_seat(seat);
0146     new TabletSeat(this, _seat);
0147 }