Changeset View
Changeset View
Standalone View
Standalone View
krfb/events.cpp
Show All 17 Lines | 1 | /* | |||
---|---|---|---|---|---|
18 | 18 | | |||
19 | You should have received a copy of the GNU General Public License | 19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; see the file COPYING. If not, write to | 20 | along with this program; see the file COPYING. If not, write to | ||
21 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 21 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
22 | Boston, MA 02110-1301, USA. | 22 | Boston, MA 02110-1301, USA. | ||
23 | */ | 23 | */ | ||
24 | 24 | | |||
25 | #include "events.h" | 25 | #include "events.h" | ||
26 | #include "krfbconfig.h" | ||||
27 | #include "rfbservermanager.h" | ||||
28 | | ||||
29 | #include "dbus/xdp_dbus_remotedesktop_interface.h" | ||||
30 | | ||||
31 | #include <linux/input.h> | ||||
26 | 32 | | |||
27 | #include <QApplication> | 33 | #include <QApplication> | ||
28 | #include <QX11Info> | 34 | #include <QX11Info> | ||
29 | #include <QDesktopWidget> | 35 | #include <QDesktopWidget> | ||
30 | #include <QGlobalStatic> | 36 | #include <QGlobalStatic> | ||
31 | 37 | | |||
32 | #include <X11/Xutil.h> | 38 | #include <X11/Xutil.h> | ||
33 | #include <X11/keysym.h> | 39 | #include <X11/keysym.h> | ||
34 | #include <X11/extensions/XTest.h> | 40 | #include <X11/extensions/XTest.h> | ||
35 | 41 | | |||
42 | #include <QX11Info> | ||||
43 | | ||||
36 | enum { | 44 | enum { | ||
37 | LEFTSHIFT = 1, | 45 | LEFTSHIFT = 1, | ||
38 | RIGHTSHIFT = 2, | 46 | RIGHTSHIFT = 2, | ||
39 | ALTGR = 4 | 47 | ALTGR = 4 | ||
40 | }; | 48 | }; | ||
41 | 49 | | |||
42 | class EventData | 50 | class EventData | ||
43 | { | 51 | { | ||
44 | public: | 52 | public: | ||
45 | EventData(); | 53 | EventData(); | ||
46 | 54 | | |||
47 | //keyboard | 55 | //keyboard | ||
48 | Display *dpy; | 56 | Display *dpy; | ||
49 | signed char modifiers[0x100]; | 57 | signed char modifiers[0x100]; | ||
50 | KeyCode keycodes[0x100]; | 58 | KeyCode keycodes[0x100]; | ||
51 | KeyCode leftShiftCode; | 59 | KeyCode leftShiftCode; | ||
52 | KeyCode rightShiftCode; | 60 | KeyCode rightShiftCode; | ||
53 | KeyCode altGrCode; | 61 | KeyCode altGrCode; | ||
54 | char modifierState; | 62 | char modifierState; | ||
55 | 63 | | |||
56 | //mouse | 64 | //mouse | ||
57 | int buttonMask; | 65 | int buttonMask; | ||
66 | int x; | ||||
67 | int y; | ||||
68 | | ||||
69 | QScopedPointer<OrgFreedesktopPortalRemoteDesktopInterface> dbusXdpRemoteDesktopService; | ||||
58 | 70 | | |||
59 | private: | 71 | private: | ||
60 | void init(); | 72 | void init(); | ||
61 | }; | 73 | }; | ||
62 | 74 | | |||
63 | Q_GLOBAL_STATIC(EventData, data) | 75 | Q_GLOBAL_STATIC(EventData, data) | ||
64 | 76 | | |||
65 | EventData::EventData() | 77 | EventData::EventData() | ||
66 | { | 78 | { | ||
67 | init(); | 79 | init(); | ||
68 | } | 80 | } | ||
69 | 81 | | |||
70 | void EventData::init() | 82 | void EventData::init() | ||
71 | { | 83 | { | ||
72 | dpy = QX11Info::display(); | | |||
73 | buttonMask = 0; | 84 | buttonMask = 0; | ||
74 | 85 | | |||
86 | if (QX11Info::isPlatformX11()) { | ||||
87 | dpy = QX11Info::display(); | ||||
75 | //initialize keycodes | 88 | //initialize keycodes | ||
76 | KeySym key, *keymap; | 89 | KeySym key, *keymap; | ||
77 | int i, j, minkey, maxkey, syms_per_keycode; | 90 | int i, j, minkey, maxkey, syms_per_keycode; | ||
78 | 91 | | |||
79 | memset(modifiers, -1, sizeof(modifiers)); | 92 | memset(modifiers, -1, sizeof(modifiers)); | ||
80 | 93 | | |||
81 | XDisplayKeycodes(dpy, &minkey, &maxkey); | 94 | XDisplayKeycodes(dpy, &minkey, &maxkey); | ||
82 | Q_ASSERT(minkey >= 8); | 95 | Q_ASSERT(minkey >= 8); | ||
Show All 16 Lines | |||||
99 | 112 | | |||
100 | leftShiftCode = XKeysymToKeycode(dpy, XK_Shift_L); | 113 | leftShiftCode = XKeysymToKeycode(dpy, XK_Shift_L); | ||
101 | rightShiftCode = XKeysymToKeycode(dpy, XK_Shift_R); | 114 | rightShiftCode = XKeysymToKeycode(dpy, XK_Shift_R); | ||
102 | altGrCode = XKeysymToKeycode(dpy, XK_Mode_switch); | 115 | altGrCode = XKeysymToKeycode(dpy, XK_Mode_switch); | ||
103 | 116 | | |||
104 | XFree((char *)keymap); | 117 | XFree((char *)keymap); | ||
105 | } | 118 | } | ||
106 | 119 | | |||
120 | dbusXdpRemoteDesktopService.reset(new OrgFreedesktopPortalRemoteDesktopInterface(QLatin1String("org.freedesktop.portal.Desktop"), | ||||
121 | QLatin1String("/org/freedesktop/portal/desktop"), QDBusConnection::sessionBus())); | ||||
122 | } | ||||
123 | | ||||
107 | /* this function adjusts the modifiers according to mod (as from modifiers) and data->modifierState */ | 124 | /* this function adjusts the modifiers according to mod (as from modifiers) and data->modifierState */ | ||
108 | static void tweakModifiers(signed char mod, bool down) | 125 | static void tweakModifiers(signed char mod, bool down) | ||
109 | { | 126 | { | ||
110 | bool isShift = data->modifierState & (LEFTSHIFT | RIGHTSHIFT); | 127 | bool isShift = data->modifierState & (LEFTSHIFT | RIGHTSHIFT); | ||
111 | 128 | | |||
112 | if (mod < 0) { | 129 | if (mod < 0) { | ||
113 | return; | 130 | return; | ||
114 | } | 131 | } | ||
Show All 26 Lines | |||||
141 | } | 158 | } | ||
142 | } | 159 | } | ||
143 | 160 | | |||
144 | void EventHandler::handleKeyboard(bool down, rfbKeySym keySym) | 161 | void EventHandler::handleKeyboard(bool down, rfbKeySym keySym) | ||
145 | { | 162 | { | ||
146 | #define ADJUSTMOD(sym,state) \ | 163 | #define ADJUSTMOD(sym,state) \ | ||
147 | if(keySym==sym) { if(down) data->modifierState|=state; else data->modifierState&=~state; } | 164 | if(keySym==sym) { if(down) data->modifierState|=state; else data->modifierState&=~state; } | ||
148 | 165 | | |||
166 | if (QX11Info::isPlatformX11()) { | ||||
149 | ADJUSTMOD(XK_Shift_L, LEFTSHIFT); | 167 | ADJUSTMOD(XK_Shift_L, LEFTSHIFT); | ||
150 | ADJUSTMOD(XK_Shift_R, RIGHTSHIFT); | 168 | ADJUSTMOD(XK_Shift_R, RIGHTSHIFT); | ||
151 | ADJUSTMOD(XK_Mode_switch, ALTGR); | 169 | ADJUSTMOD(XK_Mode_switch, ALTGR); | ||
152 | 170 | | |||
153 | if (keySym >= ' ' && keySym < 0x100) { | 171 | if (keySym >= ' ' && keySym < 0x100) { | ||
154 | KeyCode k; | 172 | KeyCode k; | ||
155 | 173 | | |||
156 | if (down) { | 174 | if (down) { | ||
Show All 13 Lines | 187 | } else { | |||
170 | KeyCode k = XKeysymToKeycode(data->dpy, keySym); | 188 | KeyCode k = XKeysymToKeycode(data->dpy, keySym); | ||
171 | 189 | | |||
172 | if (k != NoSymbol) { | 190 | if (k != NoSymbol) { | ||
173 | XTestFakeKeyEvent(data->dpy, k, down, CurrentTime); | 191 | XTestFakeKeyEvent(data->dpy, k, down, CurrentTime); | ||
174 | } | 192 | } | ||
175 | } | 193 | } | ||
176 | } | 194 | } | ||
177 | 195 | | |||
196 | // Wayland platform and pipweire plugin in use | ||||
197 | if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("pw")) { | ||||
Kanedias: What's supposed to be here? | |||||
Keyboard support, once it's implemented . I should maybe remove this completely until there is keyboard support we can use. jgrulich: Keyboard support, once it's implemented . I should maybe remove this completely until there is… | |||||
198 | | ||||
199 | } | ||||
200 | } | ||||
201 | | ||||
178 | void EventHandler::handlePointer(int buttonMask, int x, int y) | 202 | void EventHandler::handlePointer(int buttonMask, int x, int y) | ||
179 | { | 203 | { | ||
204 | if (QX11Info::isPlatformX11()) { | ||||
180 | QDesktopWidget *desktopWidget = QApplication::desktop(); | 205 | QDesktopWidget *desktopWidget = QApplication::desktop(); | ||
181 | 206 | | |||
182 | int screen = desktopWidget->screenNumber(); | 207 | int screen = desktopWidget->screenNumber(); | ||
183 | 208 | | |||
184 | if (screen < 0) { | 209 | if (screen < 0) { | ||
185 | screen = 0; | 210 | screen = 0; | ||
186 | } | 211 | } | ||
187 | 212 | | |||
188 | XTestFakeMotionEvent(data->dpy, screen, x, y, CurrentTime); | 213 | XTestFakeMotionEvent(data->dpy, screen, x, y, CurrentTime); | ||
189 | 214 | | |||
190 | for (int i = 0; i < 5; i++) { | 215 | for (int i = 0; i < 5; i++) { | ||
191 | if ((data->buttonMask&(1 << i)) != (buttonMask&(1 << i))) { | 216 | if ((data->buttonMask&(1 << i)) != (buttonMask&(1 << i))) { | ||
192 | XTestFakeButtonEvent(data->dpy, | 217 | XTestFakeButtonEvent(data->dpy, | ||
193 | i + 1, | 218 | i + 1, | ||
194 | (buttonMask&(1 << i)) ? True : False, | 219 | (buttonMask&(1 << i)) ? True : False, | ||
195 | CurrentTime); | 220 | CurrentTime); | ||
196 | } | 221 | } | ||
197 | } | 222 | } | ||
198 | 223 | | |||
199 | data->buttonMask = buttonMask; | 224 | data->buttonMask = buttonMask; | ||
200 | } | 225 | } | ||
226 | | ||||
227 | // Wayland platform and pipweire plugin in use | ||||
228 | if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("pw")) { | ||||
229 | QSharedPointer<FrameBuffer> fb = RfbServerManager::instance()->framebuffer(); | ||||
230 | const uint streamNodeId = fb->customProperty(QLatin1String("stream_node_id")).toUInt(); | ||||
231 | const QDBusObjectPath sessionHandle = fb->customProperty(QLatin1String("session_handle")).value<QDBusObjectPath>(); | ||||
232 | | ||||
233 | if (x != data->x || y != data->y) { | ||||
234 | data->dbusXdpRemoteDesktopService->NotifyPointerMotionAbsolute(sessionHandle, QVariantMap(), streamNodeId, x, y); | ||||
235 | data->x = x; | ||||
236 | data->y = y; | ||||
237 | } | ||||
238 | | ||||
239 | if (buttonMask != data->buttonMask) { | ||||
240 | int i = 0; | ||||
241 | QVector<int> buttons = { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, 0, 0, 0, 0, BTN_SIDE, BTN_EXTRA }; | ||||
242 | for (auto it = buttons.constBegin(); it != buttons.constEnd(); ++it) { | ||||
243 | int prevButtonState = (data->buttonMask >> i) & 0x01; | ||||
244 | int currentButtonState = (buttonMask >> i) & 0x01; | ||||
245 | | ||||
246 | if (prevButtonState != currentButtonState) { | ||||
247 | if (*it) { | ||||
248 | data->dbusXdpRemoteDesktopService->NotifyPointerButton(sessionHandle, QVariantMap(), *it, buttonMask); | ||||
249 | } else { | ||||
250 | int axis = 0; | ||||
251 | int steps = 0; | ||||
252 | switch (i) { | ||||
253 | case 3: | ||||
254 | axis = 0; // Vertical | ||||
255 | steps = -1; | ||||
256 | break; | ||||
257 | case 4: | ||||
258 | axis = 0; // Vertical | ||||
259 | steps = 1; | ||||
260 | break; | ||||
261 | case 5: | ||||
262 | axis = 1; // Horizontal | ||||
263 | steps = -1; | ||||
264 | break; | ||||
265 | case 6: | ||||
266 | axis = 1; // Horizontal | ||||
267 | steps = 1; | ||||
268 | break; | ||||
269 | } | ||||
270 | | ||||
271 | data->dbusXdpRemoteDesktopService->NotifyPointerAxisDiscrete(sessionHandle, QVariantMap(), axis, steps); | ||||
272 | } | ||||
273 | } | ||||
274 | ++i; | ||||
275 | } | ||||
276 | data->buttonMask = buttonMask; | ||||
277 | } | ||||
278 | } | ||||
279 | } |
What's supposed to be here?