File indexing completed on 2024-05-19 16:35:19

0001 /*
0002     SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "fakeinput_interface.h"
0007 #include "display.h"
0008 
0009 #include <QPointF>
0010 #include <memory>
0011 #include <vector>
0012 
0013 #include <qwayland-server-fake-input.h>
0014 #include <wayland-server.h>
0015 
0016 namespace KWaylandServer
0017 {
0018 static const quint32 s_version = 4;
0019 
0020 class FakeInputInterfacePrivate : public QtWaylandServer::org_kde_kwin_fake_input
0021 {
0022 public:
0023     FakeInputInterfacePrivate(FakeInputInterface *_q, Display *display);
0024     std::map<wl_resource *, std::unique_ptr<FakeInputDevice>> devices;
0025 
0026 private:
0027     FakeInputDevice *device(wl_resource *r);
0028 
0029     FakeInputInterface *q;
0030     static QList<quint32> touchIds;
0031 
0032 protected:
0033     void org_kde_kwin_fake_input_bind_resource(Resource *resource) override;
0034     void org_kde_kwin_fake_input_destroy_resource(Resource *resource) override;
0035     void org_kde_kwin_fake_input_authenticate(Resource *resource, const QString &application, const QString &reason) override;
0036     void org_kde_kwin_fake_input_pointer_motion(Resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y) override;
0037     void org_kde_kwin_fake_input_button(Resource *resource, uint32_t button, uint32_t state) override;
0038     void org_kde_kwin_fake_input_axis(Resource *resource, uint32_t axis, wl_fixed_t value) override;
0039     void org_kde_kwin_fake_input_touch_down(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) override;
0040     void org_kde_kwin_fake_input_touch_motion(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) override;
0041     void org_kde_kwin_fake_input_touch_up(Resource *resource, uint32_t id) override;
0042     void org_kde_kwin_fake_input_touch_cancel(Resource *resource) override;
0043     void org_kde_kwin_fake_input_touch_frame(Resource *resource) override;
0044     void org_kde_kwin_fake_input_pointer_motion_absolute(Resource *resource, wl_fixed_t x, wl_fixed_t y) override;
0045     void org_kde_kwin_fake_input_keyboard_key(Resource *resource, uint32_t button, uint32_t state) override;
0046 };
0047 
0048 QList<quint32> FakeInputInterfacePrivate::touchIds = QList<quint32>();
0049 
0050 FakeInputInterfacePrivate::FakeInputInterfacePrivate(FakeInputInterface *_q, Display *display)
0051     : QtWaylandServer::org_kde_kwin_fake_input(*display, s_version)
0052     , q(_q)
0053 {
0054 }
0055 
0056 FakeInputInterface::FakeInputInterface(Display *display)
0057     : d(std::make_unique<FakeInputInterfacePrivate>(this, display))
0058 {
0059 }
0060 
0061 FakeInputInterface::~FakeInputInterface() = default;
0062 
0063 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_bind_resource(Resource *resource)
0064 {
0065     auto device = new FakeInputDevice(q, resource->handle);
0066     devices[resource->handle] = std::unique_ptr<FakeInputDevice>(device);
0067     Q_EMIT q->deviceCreated(device);
0068 }
0069 
0070 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_destroy_resource(Resource *resource)
0071 {
0072     auto it = devices.find(resource->handle);
0073     if (it != devices.end()) {
0074         const auto [resource, device] = std::move(*it);
0075         devices.erase(it);
0076         Q_EMIT q->deviceDestroyed(device.get());
0077     }
0078 }
0079 
0080 FakeInputDevice *FakeInputInterfacePrivate::device(wl_resource *r)
0081 {
0082     return devices[r].get();
0083 }
0084 
0085 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_authenticate(Resource *resource, const QString &application, const QString &reason)
0086 {
0087     FakeInputDevice *d = device(resource->handle);
0088     if (!d) {
0089         return;
0090     }
0091     Q_EMIT d->authenticationRequested(application, reason);
0092 }
0093 
0094 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_pointer_motion(Resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y)
0095 {
0096     FakeInputDevice *d = device(resource->handle);
0097     if (!d || !d->isAuthenticated()) {
0098         return;
0099     }
0100     Q_EMIT d->pointerMotionRequested(QPointF(wl_fixed_to_double(delta_x), wl_fixed_to_double(delta_y)));
0101 }
0102 
0103 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_button(Resource *resource, uint32_t button, uint32_t state)
0104 {
0105     FakeInputDevice *d = device(resource->handle);
0106     if (!d || !d->isAuthenticated()) {
0107         return;
0108     }
0109     switch (state) {
0110     case WL_POINTER_BUTTON_STATE_PRESSED:
0111         Q_EMIT d->pointerButtonPressRequested(button);
0112         break;
0113     case WL_POINTER_BUTTON_STATE_RELEASED:
0114         Q_EMIT d->pointerButtonReleaseRequested(button);
0115         break;
0116     default:
0117         // nothing
0118         break;
0119     }
0120 }
0121 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_axis(Resource *resource, uint32_t axis, wl_fixed_t value)
0122 {
0123     FakeInputDevice *d = device(resource->handle);
0124     if (!d || !d->isAuthenticated()) {
0125         return;
0126     }
0127     Qt::Orientation orientation;
0128     switch (axis) {
0129     case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
0130         orientation = Qt::Horizontal;
0131         break;
0132     case WL_POINTER_AXIS_VERTICAL_SCROLL:
0133         orientation = Qt::Vertical;
0134         break;
0135     default:
0136         // invalid
0137         return;
0138     }
0139     Q_EMIT d->pointerAxisRequested(orientation, wl_fixed_to_double(value));
0140 }
0141 
0142 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_touch_down(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y)
0143 {
0144     FakeInputDevice *d = device(resource->handle);
0145     if (!d || !d->isAuthenticated()) {
0146         return;
0147     }
0148     if (touchIds.contains(id)) {
0149         return;
0150     }
0151     touchIds << id;
0152     Q_EMIT d->touchDownRequested(id, QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)));
0153 }
0154 
0155 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_touch_motion(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y)
0156 {
0157     FakeInputDevice *d = device(resource->handle);
0158     if (!d || !d->isAuthenticated()) {
0159         return;
0160     }
0161     if (!touchIds.contains(id)) {
0162         return;
0163     }
0164     Q_EMIT d->touchMotionRequested(id, QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)));
0165 }
0166 
0167 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_touch_up(Resource *resource, uint32_t id)
0168 {
0169     FakeInputDevice *d = device(resource->handle);
0170     if (!d || !d->isAuthenticated()) {
0171         return;
0172     }
0173     if (!touchIds.contains(id)) {
0174         return;
0175     }
0176     touchIds.removeOne(id);
0177     Q_EMIT d->touchUpRequested(id);
0178 }
0179 
0180 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_touch_cancel(Resource *resource)
0181 {
0182     FakeInputDevice *d = device(resource->handle);
0183     if (!d || !d->isAuthenticated()) {
0184         return;
0185     }
0186     touchIds.clear();
0187     Q_EMIT d->touchCancelRequested();
0188 }
0189 
0190 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_touch_frame(Resource *resource)
0191 {
0192     FakeInputDevice *d = device(resource->handle);
0193     if (!d || !d->isAuthenticated()) {
0194         return;
0195     }
0196     Q_EMIT d->touchFrameRequested();
0197 }
0198 
0199 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_pointer_motion_absolute(Resource *resource, wl_fixed_t x, wl_fixed_t y)
0200 {
0201     FakeInputDevice *d = device(resource->handle);
0202     if (!d || !d->isAuthenticated()) {
0203         return;
0204     }
0205     Q_EMIT d->pointerMotionAbsoluteRequested(QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)));
0206 }
0207 
0208 void FakeInputInterfacePrivate::org_kde_kwin_fake_input_keyboard_key(Resource *resource, uint32_t button, uint32_t state)
0209 {
0210     FakeInputDevice *d = device(resource->handle);
0211     if (!d || !d->isAuthenticated()) {
0212         return;
0213     }
0214     switch (state) {
0215     case WL_KEYBOARD_KEY_STATE_PRESSED:
0216         Q_EMIT d->keyboardKeyPressRequested(button);
0217         break;
0218     case WL_KEYBOARD_KEY_STATE_RELEASED:
0219         Q_EMIT d->keyboardKeyReleaseRequested(button);
0220         break;
0221     default:
0222         // nothing
0223         break;
0224     }
0225 }
0226 
0227 class FakeInputDevicePrivate
0228 {
0229 public:
0230     FakeInputDevicePrivate(FakeInputInterface *interface, wl_resource *resource);
0231     wl_resource *resource;
0232     FakeInputInterface *interface;
0233     bool authenticated = false;
0234 };
0235 
0236 FakeInputDevicePrivate::FakeInputDevicePrivate(FakeInputInterface *interface, wl_resource *resource)
0237     : resource(resource)
0238     , interface(interface)
0239 {
0240 }
0241 
0242 FakeInputDevice::FakeInputDevice(FakeInputInterface *parent, wl_resource *resource)
0243     : d(std::make_unique<FakeInputDevicePrivate>(parent, resource))
0244 {
0245 }
0246 
0247 FakeInputDevice::~FakeInputDevice() = default;
0248 
0249 void FakeInputDevice::setAuthentication(bool authenticated)
0250 {
0251     d->authenticated = authenticated;
0252 }
0253 
0254 wl_resource *FakeInputDevice::resource()
0255 {
0256     return d->resource;
0257 }
0258 
0259 bool FakeInputDevice::isAuthenticated() const
0260 {
0261     return d->authenticated;
0262 }
0263 
0264 }