File indexing completed on 2024-11-10 04:56:31
0001 /* 0002 SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "fakeinputbackend.h" 0008 #include "fakeinputdevice.h" 0009 #include "wayland/display.h" 0010 0011 #include "wayland/qwayland-server-fake-input.h" 0012 0013 namespace KWin 0014 { 0015 0016 static const quint32 s_version = 5; 0017 0018 class FakeInputBackendPrivate : public QtWaylandServer::org_kde_kwin_fake_input 0019 { 0020 public: 0021 FakeInputBackendPrivate(FakeInputBackend *q, Display *display); 0022 0023 FakeInputDevice *findDevice(Resource *resource); 0024 std::chrono::microseconds currentTime() const; 0025 0026 FakeInputBackend *q; 0027 Display *display; 0028 std::map<Resource *, std::unique_ptr<FakeInputDevice>> devices; 0029 static QList<quint32> touchIds; 0030 0031 protected: 0032 void org_kde_kwin_fake_input_bind_resource(Resource *resource) override; 0033 void org_kde_kwin_fake_input_destroy_resource(Resource *resource) override; 0034 void org_kde_kwin_fake_input_authenticate(Resource *resource, const QString &application, const QString &reason) override; 0035 void org_kde_kwin_fake_input_pointer_motion(Resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y) override; 0036 void org_kde_kwin_fake_input_button(Resource *resource, uint32_t button, uint32_t state) override; 0037 void org_kde_kwin_fake_input_axis(Resource *resource, uint32_t axis, wl_fixed_t value) override; 0038 void org_kde_kwin_fake_input_touch_down(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) override; 0039 void org_kde_kwin_fake_input_touch_motion(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) override; 0040 void org_kde_kwin_fake_input_touch_up(Resource *resource, uint32_t id) override; 0041 void org_kde_kwin_fake_input_touch_cancel(Resource *resource) override; 0042 void org_kde_kwin_fake_input_touch_frame(Resource *resource) override; 0043 void org_kde_kwin_fake_input_pointer_motion_absolute(Resource *resource, wl_fixed_t x, wl_fixed_t y) override; 0044 void org_kde_kwin_fake_input_keyboard_key(Resource *resource, uint32_t button, uint32_t state) override; 0045 void org_kde_kwin_fake_input_destroy(Resource *resource) override; 0046 }; 0047 0048 QList<quint32> FakeInputBackendPrivate::touchIds = QList<quint32>(); 0049 0050 FakeInputBackendPrivate::FakeInputBackendPrivate(FakeInputBackend *q, Display *display) 0051 : q(q) 0052 , display(display) 0053 { 0054 } 0055 0056 void FakeInputBackendPrivate::org_kde_kwin_fake_input_bind_resource(Resource *resource) 0057 { 0058 auto device = new FakeInputDevice(q); 0059 devices[resource] = std::unique_ptr<FakeInputDevice>(device); 0060 Q_EMIT q->deviceAdded(device); 0061 } 0062 0063 void FakeInputBackendPrivate::org_kde_kwin_fake_input_destroy(Resource *resource) 0064 { 0065 wl_resource_destroy(resource->handle); 0066 } 0067 0068 void FakeInputBackendPrivate::org_kde_kwin_fake_input_destroy_resource(Resource *resource) 0069 { 0070 auto it = devices.find(resource); 0071 if (it != devices.end()) { 0072 const auto [resource, device] = std::move(*it); 0073 devices.erase(it); 0074 Q_EMIT q->deviceRemoved(device.get()); 0075 } 0076 } 0077 0078 FakeInputDevice *FakeInputBackendPrivate::findDevice(Resource *resource) 0079 { 0080 return devices[resource].get(); 0081 } 0082 0083 std::chrono::microseconds FakeInputBackendPrivate::currentTime() const 0084 { 0085 return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()); 0086 } 0087 0088 void FakeInputBackendPrivate::org_kde_kwin_fake_input_authenticate(Resource *resource, const QString &application, const QString &reason) 0089 { 0090 FakeInputDevice *device = findDevice(resource); 0091 if (device) { 0092 // TODO: make secure 0093 device->setAuthenticated(true); 0094 } 0095 } 0096 0097 void FakeInputBackendPrivate::org_kde_kwin_fake_input_pointer_motion(Resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y) 0098 { 0099 FakeInputDevice *device = findDevice(resource); 0100 if (!device->isAuthenticated()) { 0101 return; 0102 } 0103 const QPointF delta(wl_fixed_to_double(delta_x), wl_fixed_to_double(delta_y)); 0104 0105 Q_EMIT device->pointerMotion(delta, delta, currentTime(), device); 0106 Q_EMIT device->pointerFrame(device); 0107 } 0108 0109 void FakeInputBackendPrivate::org_kde_kwin_fake_input_button(Resource *resource, uint32_t button, uint32_t state) 0110 { 0111 FakeInputDevice *device = findDevice(resource); 0112 if (!device->isAuthenticated()) { 0113 return; 0114 } 0115 0116 InputRedirection::PointerButtonState nativeState; 0117 switch (state) { 0118 case WL_POINTER_BUTTON_STATE_PRESSED: 0119 nativeState = InputRedirection::PointerButtonPressed; 0120 break; 0121 case WL_POINTER_BUTTON_STATE_RELEASED: 0122 nativeState = InputRedirection::PointerButtonReleased; 0123 break; 0124 default: 0125 return; 0126 } 0127 0128 Q_EMIT device->pointerButtonChanged(button, nativeState, currentTime(), device); 0129 Q_EMIT device->pointerFrame(device); 0130 } 0131 0132 void FakeInputBackendPrivate::org_kde_kwin_fake_input_axis(Resource *resource, uint32_t axis, wl_fixed_t value) 0133 { 0134 FakeInputDevice *device = findDevice(resource); 0135 if (!device->isAuthenticated()) { 0136 return; 0137 } 0138 0139 InputRedirection::PointerAxis nativeAxis; 0140 switch (axis) { 0141 case WL_POINTER_AXIS_HORIZONTAL_SCROLL: 0142 nativeAxis = InputRedirection::PointerAxisHorizontal; 0143 break; 0144 0145 case WL_POINTER_AXIS_VERTICAL_SCROLL: 0146 nativeAxis = InputRedirection::PointerAxisVertical; 0147 break; 0148 0149 default: 0150 return; 0151 } 0152 0153 Q_EMIT device->pointerAxisChanged(nativeAxis, wl_fixed_to_double(value), 0, InputRedirection::PointerAxisSourceUnknown, currentTime(), device); 0154 Q_EMIT device->pointerFrame(device); 0155 } 0156 0157 void FakeInputBackendPrivate::org_kde_kwin_fake_input_touch_down(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) 0158 { 0159 FakeInputDevice *device = findDevice(resource); 0160 if (!device->isAuthenticated()) { 0161 return; 0162 } 0163 if (touchIds.contains(id)) { 0164 return; 0165 } 0166 touchIds << id; 0167 Q_EMIT device->touchDown(id, QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), currentTime(), device); 0168 } 0169 0170 void FakeInputBackendPrivate::org_kde_kwin_fake_input_touch_motion(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) 0171 { 0172 FakeInputDevice *device = findDevice(resource); 0173 if (!device->isAuthenticated()) { 0174 return; 0175 } 0176 if (!touchIds.contains(id)) { 0177 return; 0178 } 0179 Q_EMIT device->touchMotion(id, QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), currentTime(), device); 0180 } 0181 0182 void FakeInputBackendPrivate::org_kde_kwin_fake_input_touch_up(Resource *resource, uint32_t id) 0183 { 0184 FakeInputDevice *device = findDevice(resource); 0185 if (!device->isAuthenticated()) { 0186 return; 0187 } 0188 if (!touchIds.contains(id)) { 0189 return; 0190 } 0191 touchIds.removeOne(id); 0192 Q_EMIT device->touchUp(id, currentTime(), device); 0193 } 0194 0195 void FakeInputBackendPrivate::org_kde_kwin_fake_input_touch_cancel(Resource *resource) 0196 { 0197 FakeInputDevice *device = findDevice(resource); 0198 if (!device->isAuthenticated()) { 0199 return; 0200 } 0201 touchIds.clear(); 0202 Q_EMIT device->touchCanceled(device); 0203 } 0204 0205 void FakeInputBackendPrivate::org_kde_kwin_fake_input_touch_frame(Resource *resource) 0206 { 0207 FakeInputDevice *device = findDevice(resource); 0208 if (!device->isAuthenticated()) { 0209 return; 0210 } 0211 Q_EMIT device->touchFrame(device); 0212 } 0213 0214 void FakeInputBackendPrivate::org_kde_kwin_fake_input_pointer_motion_absolute(Resource *resource, wl_fixed_t x, wl_fixed_t y) 0215 { 0216 FakeInputDevice *device = findDevice(resource); 0217 if (!device->isAuthenticated()) { 0218 return; 0219 } 0220 0221 Q_EMIT device->pointerMotionAbsolute(QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), currentTime(), device); 0222 Q_EMIT device->pointerFrame(device); 0223 } 0224 0225 void FakeInputBackendPrivate::org_kde_kwin_fake_input_keyboard_key(Resource *resource, uint32_t button, uint32_t state) 0226 { 0227 FakeInputDevice *device = findDevice(resource); 0228 if (!device->isAuthenticated()) { 0229 return; 0230 } 0231 0232 InputRedirection::KeyboardKeyState nativeState; 0233 switch (state) { 0234 case WL_KEYBOARD_KEY_STATE_PRESSED: 0235 nativeState = InputRedirection::KeyboardKeyPressed; 0236 break; 0237 0238 case WL_KEYBOARD_KEY_STATE_RELEASED: 0239 nativeState = InputRedirection::KeyboardKeyReleased; 0240 break; 0241 0242 default: 0243 return; 0244 } 0245 0246 Q_EMIT device->keyChanged(button, nativeState, currentTime(), device); 0247 } 0248 0249 FakeInputBackend::FakeInputBackend(Display *display) 0250 : d(std::make_unique<FakeInputBackendPrivate>(this, display)) 0251 { 0252 } 0253 0254 FakeInputBackend::~FakeInputBackend() = default; 0255 0256 void FakeInputBackend::initialize() 0257 { 0258 d->init(*d->display, s_version); 0259 } 0260 0261 } // namespace KWin 0262 0263 #include "moc_fakeinputbackend.cpp"