Deskflow 1.27.0.8
Keyboard and mouse sharing utility
Loading...
Searching...
No Matches
EiComputer.h
Go to the documentation of this file.
1/*
2 * Deskflow -- mouse and keyboard sharing utility
3 * SPDX-FileCopyrightText: (C) 2024, 2026 Synergy App Ltd
4 * SPDX-FileCopyrightText: (C) 2022, 2026 Red Hat, Inc.
5 * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
6 */
7
8#pragma once
9
10#include "deskflow/IComputer.h"
12#ifdef HAVE_LIBPORTAL_SHORTCUTS
14#endif
16
17#include <bitset>
18#include <climits>
19#include <libei.h>
20#include <map>
21#include <mutex>
22#include <vector>
23
24struct ei;
25struct ei_event;
26struct ei_seat;
27struct ei_device;
28
29class EventQueueTimer;
30
31namespace deskflow {
32
33class EiKeyState;
37class EiClipboard;
38
40
43{
44public:
45 EiComputer(bool isPrimary, IEventQueue *events, bool usePortal);
46 ~EiComputer() override;
47
48 // IComputer overrides
49 void *getEventTarget() const final;
50 bool getClipboard(ClipboardID id, IClipboard *) const override;
51 void getShape(std::int32_t &x, std::int32_t &y, std::int32_t &width, std::int32_t &height) const override;
52 void getCursorPos(std::int32_t &x, std::int32_t &y) const override;
53
54 // IPrimaryComputer overrides
55 void reconfigure(std::uint32_t activeSides) override;
56 std::uint32_t activeSides() override;
57 void warpCursor(std::int32_t x, std::int32_t y) override;
58 std::uint32_t registerHotKey(KeyID key, KeyModifierMask mask) override;
59 void unregisterHotKey(std::uint32_t id) override;
60 void fakeInputBegin() override;
61 void fakeInputEnd() override;
62 std::int32_t getJumpZoneSize() const override;
63 bool isAnyMouseButtonDown(std::uint32_t &buttonID) const override;
64 void getCursorCenter(std::int32_t &x, std::int32_t &y) const override;
65
66 // ISecondaryComputer overrides
67 void fakeMouseButton(ButtonID id, bool press) override;
68 void fakeMouseMove(std::int32_t x, std::int32_t y) override;
69 void fakeMouseRelativeMove(std::int32_t dx, std::int32_t dy) const override;
70 void fakeMouseWheel(ScrollDelta delta) const override;
71 void fakeKey(std::uint32_t keycode, bool isDown) const;
72
73 // IPlatformComputer overrides
74 void enable() override;
75 void disable() override;
76 void enter() override;
77 bool canLeave() override;
78 void leave() override;
79 bool setClipboard(ClipboardID, const IClipboard *) override;
80 void checkClipboards() override;
81 void openScreensaver(bool notify) override;
82 void closeScreensaver() override;
83 void screensaver(bool activate) override;
84 void resetOptions() override;
85 void setOptions(const OptionsList &options) override;
86 void setSequenceNumber(std::uint32_t) override;
87 bool isPrimary() const override;
88
89 // Send clipboard event (needed by PortalInputCapture)
91
92 // Local clipboard cache (used by PortalRemoteDesktop to land selection reads)
94 {
95 return m_clipboard;
96 }
97
98 // Maximum clipboard size in KB, configured by the server
99 size_t maximumClipboardSize() const
100 {
101 return m_maximumClipboardSize;
102 }
103
104protected:
105 // IPlatformComputer overrides
106 void handleSystemEvent(const Event &event) override;
107 void updateButtons() override;
108 IKeyState *getKeyState() const override;
109 std::string getSecureInputApp() const override;
110
111 void updateShape();
112 void addDevice(ei_device *device);
113 void removeDevice(ei_device *device);
114
115private:
116 void initEi();
117 void cleanupEi();
118 void sendEvent(EventTypes type, void *data);
119 ButtonID mapButtonFromEvdev(ei_event *event) const;
120 void onKeyEvent(ei_event *event);
121 void onButtonEvent(ei_event *event);
122 void sendWheelEvents(ei_device *device, const int threshold, double dx, double dy, bool is_discrete);
123 void onPointerScrollEvent(ei_event *event);
124 void onPointerScrollDiscreteEvent(ei_event *event);
125 void onMotionEvent(ei_event *event);
126 void onAbsMotionEvent(const ei_event *) const;
127 bool onHotkey(KeyID key, bool isPressed, KeyModifierMask mask);
128 void eiLogEvent(ei_log_priority priority, const char *message) const;
129
130 void handleConnectedToEisEvent(const Event &event);
131 void handlePortalSessionClosed();
132 void ensureEmulating() const;
133 void stopEmulating() const;
134 void cancelIdleEmulationTimer() const;
135 void updatePortalGlobalShortcuts();
136
137 static void handleEiLogEvent(ei *ei, const ei_log_priority priority, const char *message, ei_log_context *)
138 {
139 auto computer = static_cast<EiComputer *>(ei_get_user_data(ei));
140 computer->eiLogEvent(priority, message);
141 }
142
143private:
144 // true if computer is being used as a primary computer, false otherwise
145 bool m_isPrimary = false;
146 IEventQueue *m_events = nullptr;
147
148 // keyboard stuff
149 EiKeyState *m_keyState = nullptr;
150
151 KeyID m_lastPressed = kKeyNone;
152
153 // mouse buttons currently held, indexed by ButtonID
154 std::bitset<NumButtonIDs> m_buttons;
155
156 // clipboard stuff
157 EiClipboard *m_clipboard = nullptr;
158 size_t m_maximumClipboardSize = INT_MAX;
159
160 std::vector<ei_device *> m_eiDevices;
161
162 ei *m_ei = nullptr;
163 ei_seat *m_eiSeat = nullptr;
164 ei_device *m_eiPointer = nullptr;
165 ei_device *m_eiKeyboard = nullptr;
166 ei_device *m_eiAbs = nullptr;
167
168 mutable std::uint32_t m_sequenceNumber = 0;
169
170 // Lazily-started EIS emulation: only grab while relayed input is actually
171 // flowing, and release after a short idle so the compositor can DPMS-sleep
172 // this computer even while the deskflow cursor logically sits on it.
173 mutable bool m_isEmulating = false;
174 mutable EventQueueTimer *m_idleEmulationTimer = nullptr;
175 // Chosen empirically on one machine in 2026-06; not derived from any protocol constant.
176 static constexpr double s_idleEmulationTimeout = 4.0;
177
178 std::uint32_t m_activeSides = 0;
179 std::uint32_t m_x = 0;
180 std::uint32_t m_y = 0;
181 std::uint32_t m_w = 0;
182 std::uint32_t m_h = 0;
183 bool m_isShapeInitialized = false;
184
185 // true if mouse has entered the computer
186 bool m_isOnComputer;
187
188 // server: last pointer position
189 // client: position sent before enter()
190 std::int32_t m_cursorX = 0;
191 std::int32_t m_cursorY = 0;
192
193 double m_bufferDX = 0;
194 double m_bufferDY = 0;
195
196 mutable std::mutex m_mutex;
197
198 PortalRemoteDesktop *m_portalRemoteDesktop = nullptr;
199 PortalInputCapture *m_portalInputCapture = nullptr;
200 PortalGlobalShortcuts *m_portalGlobalShortcuts = nullptr;
201
202 bool m_activated = false;
203
204 struct HotKeyItem
205 {
206 public:
207 HotKeyItem(std::uint32_t mask, std::uint32_t id);
208 auto operator<=>(const HotKeyItem &other) const
209 {
210 return mask <=> other.mask;
211 }
212
213 public:
214 std::uint32_t mask = 0;
215 std::uint32_t id = 0; // for registering the hotkey
216 };
217
218 class HotKeySet
219 {
220 public:
221 explicit HotKeySet(KeyID keyid);
222 KeyID keyid() const
223 {
224 return m_id;
225 }
226 bool removeById(std::uint32_t id);
227 void addItem(HotKeyItem item);
228 std::uint32_t findByMask(std::uint32_t mask) const;
229 bool empty() const
230 {
231 return m_set.empty();
232 }
233#ifdef HAVE_LIBPORTAL_SHORTCUTS
234 const std::vector<PortalGlobalShortcuts::HotKey> getPortalHotKeys() const;
235#endif
236
237 private:
238 KeyID m_id = 0;
239 std::vector<HotKeyItem> m_set;
240 };
241
242 using HotKeyMap = std::map<KeyID, HotKeySet>;
243
244 HotKeyMap m_hotkeys;
245 [[no_unique_address]] XDGPowerManager m_powerManager;
246};
247
248} // namespace deskflow
static int void FAR * data
Definition ArchNetworkWinsock.cpp:36
static int type
Definition ArchNetworkWinsock.cpp:46
uint8_t ClipboardID
Clipboard ID.
Definition ClipboardTypes.h:16
Coordinate ScrollDelta
Definition Coordinate.h:21
uint32_t KeyID
Key ID.
Definition KeyTypes.h:22
uint32_t KeyModifierMask
Modifier key mask.
Definition KeyTypes.h:45
uint8_t ButtonID
Mouse button ID.
Definition MouseTypes.h:16
std::vector< uint32_t > OptionsList
Definition OptionTypes.h:27
Definition EventQueueTimer.h:12
Event.
Definition Event.h:43
Clipboard interface.
Definition IClipboard.h:19
Event queue interface.
Definition IEventQueue.h:29
Key state interface.
Definition IKeyState.h:23
PlatformComputer(IEventQueue *events)
Definition PlatformComputer.cpp:13
EI/Portal clipboard implementation.
Definition EiClipboard.h:21
Implementation of IPlatformComputer for X11.
Definition EiComputer.h:43
void enter() override
Enter computer.
Definition EiComputer.cpp:452
void fakeMouseWheel(ScrollDelta delta) const override
Synthesize a mouse wheel event of amount This Implmentation for this method should call applyScrollMo...
Definition EiComputer.cpp:368
void fakeMouseMove(std::int32_t x, std::int32_t y) override
Definition EiComputer.cpp:341
void closeScreensaver() override
Close screen saver.
Definition EiComputer.cpp:523
std::uint32_t activeSides() override
activeSides
Definition EiComputer.cpp:218
void disable() override
Disable computer.
Definition EiComputer.cpp:400
void removeDevice(ei_device *device)
Definition EiComputer.cpp:651
void resetOptions() override
Notify of options changes.
Definition EiComputer.cpp:533
void openScreensaver(bool notify) override
Open screen saver.
Definition EiComputer.cpp:518
bool isAnyMouseButtonDown(std::uint32_t &buttonID) const override
Definition EiComputer.cpp:299
size_t maximumClipboardSize() const
Definition EiComputer.h:99
void leave() override
Leave computer.
Definition EiComputer.cpp:473
EiClipboard * getClipboardCache() const
Definition EiComputer.h:93
bool isPrimary() const override
Test if is primary computer.
Definition EiComputer.cpp:552
void reconfigure(std::uint32_t activeSides) override
Definition EiComputer.cpp:211
void getShape(std::int32_t &x, std::int32_t &y, std::int32_t &width, std::int32_t &height) const override
Definition EiComputer.cpp:197
void sendClipboardEvent(EventTypes type, ClipboardID id) const
Definition EiComputer.cpp:696
EiComputer(bool isPrimary, IEventQueue *events, bool usePortal)
Definition EiComputer.cpp:42
void fakeInputEnd() override
Done synthesizing input on primary computer.
Definition EiComputer.cpp:289
void updateShape()
Definition EiComputer.cpp:557
void fakeInputBegin() override
Prepare to synthesize input on primary computer.
Definition EiComputer.cpp:284
void setOptions(const OptionsList &options) override
Notify of options changes.
Definition EiComputer.cpp:539
void getCursorCenter(std::int32_t &x, std::int32_t &y) const override
Definition EiComputer.cpp:308
std::uint32_t registerHotKey(KeyID key, KeyModifierMask mask) override
Register a system hotkey.
Definition EiComputer.cpp:229
void updateButtons() override
Update mouse buttons.
Definition EiComputer.cpp:1075
bool canLeave() override
Leave computer.
Definition EiComputer.cpp:468
bool setClipboard(ClipboardID, const IClipboard *) override
Set clipboard.
Definition EiComputer.cpp:482
void getCursorPos(std::int32_t &x, std::int32_t &y) const override
Definition EiComputer.cpp:205
void handleSystemEvent(const Event &event) override
Handle system event.
Definition EiComputer.cpp:950
void addDevice(ei_device *device)
Definition EiComputer.cpp:604
void screensaver(bool activate) override
Activate/deactivate screen saver.
Definition EiComputer.cpp:528
void * getEventTarget() const final
Get event target.
Definition EiComputer.cpp:173
void enable() override
Enable computer.
Definition EiComputer.cpp:394
std::string getSecureInputApp() const override
Determine the name of the app causing a secure input state.
Definition EiComputer.cpp:1088
void fakeKey(std::uint32_t keycode, bool isDown) const
Definition EiComputer.cpp:382
void setSequenceNumber(std::uint32_t) override
Definition EiComputer.cpp:710
std::int32_t getJumpZoneSize() const override
Get jump zone size.
Definition EiComputer.cpp:294
bool getClipboard(ClipboardID id, IClipboard *) const override
Get clipboard.
Definition EiComputer.cpp:178
void fakeMouseButton(ButtonID id, bool press) override
Fake mouse press/release.
Definition EiComputer.cpp:314
IKeyState * getKeyState() const override
Get the key state.
Definition EiComputer.cpp:1083
void checkClipboards() override
Check clipboard owner.
Definition EiComputer.cpp:511
void warpCursor(std::int32_t x, std::int32_t y) override
Definition EiComputer.cpp:223
void unregisterHotKey(std::uint32_t id) override
Definition EiComputer.cpp:248
void fakeMouseRelativeMove(std::int32_t dx, std::int32_t dy) const override
Definition EiComputer.cpp:358
A key state for Ei.
Definition EiKeyState.h:23
Definition PortalGlobalShortcuts.h:29
Definition PortalInputCapture.h:30
Definition PortalRemoteDesktop.h:21
Definition DaemonApp.h:18
EventTypes
Definition EventTypes.h:13
IComputer::ClipboardInfo ClipboardInfo
Definition EiComputer.h:39
Definition IComputer.h:24