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 }