Deskflow 1.27.0.8
Keyboard and mouse sharing utility
Loading...
Searching...
No Matches
OSXComputer.h
Go to the documentation of this file.
1/*
2 * Deskflow -- mouse and keyboard sharing utility
3 * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
4 * SPDX-FileCopyrightText: (C) 2012 - 2016 Synergy App Ltd
5 * SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman
6 * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
7 */
8
9#pragma once
10
14
15#include <Carbon/Carbon.h>
16#include <IOKit/IOMessage.h>
17#include <IOKit/pwr_mgt/IOPMLib.h>
18#include <mach/mach_init.h>
19#include <mach/mach_interface.h>
20#include <mach/mach_port.h>
21
22#include <bitset>
23#include <map>
24#include <memory>
25#include <thread>
26#include <vector>
27
28extern "C"
29{
30 using CGSConnectionID = int;
31 CGError CGSSetConnectionProperty(CGSConnectionID cid, CGSConnectionID targetCID, CFStringRef key, CFTypeRef value);
33}
34
35template <class T> class CondVar;
36class EventQueueTimer;
37class Mutex;
38class Thread;
39class OSXKeyState;
40class OSXScreenSaver;
41class IEventQueue;
42class Mutex;
43
46{
47public:
48 OSXComputer(IEventQueue *events, bool isPrimary, bool enableLangSync = false);
49
50 virtual ~OSXComputer();
51
53 {
54 return m_events;
55 }
56
57 // IComputer overrides
58 void *getEventTarget() const override;
59 bool getClipboard(ClipboardID id, IClipboard *) const override;
60 void getShape(int32_t &x, int32_t &y, int32_t &width, int32_t &height) const override;
61 void getCursorPos(int32_t &x, int32_t &y) const override;
62
63 // IPrimaryComputer overrides
64 void reconfigure(uint32_t activeSides) override;
65 uint32_t activeSides() override;
66 void warpCursor(int32_t x, int32_t y) override;
67 uint32_t registerHotKey(KeyID key, KeyModifierMask mask) override;
68 void unregisterHotKey(uint32_t id) override;
69 void fakeInputBegin() override;
70 void fakeInputEnd() override;
71 int32_t getJumpZoneSize() const override;
72 bool isAnyMouseButtonDown(uint32_t &buttonID) const override;
73 void getCursorCenter(int32_t &x, int32_t &y) const override;
74
75 // ISecondaryComputer overrides
76 void fakeMouseButton(ButtonID id, bool press) override;
77 void fakeMouseMove(int32_t x, int32_t y) override;
78 void fakeMouseRelativeMove(int32_t dx, int32_t dy) const override;
79 void fakeMouseWheel(ScrollDelta delta) const override;
80
81 // IPlatformComputer overrides
82 void enable() override;
83 void disable() override;
84 void enter() override;
85 bool canLeave() override;
86 void leave() override;
87 bool setClipboard(ClipboardID, const IClipboard *) override;
88 void checkClipboards() override;
89 void openScreensaver(bool notify) override;
90 void closeScreensaver() override;
91 void screensaver(bool activate) override;
92 void resetOptions() override;
93 void setOptions(const OptionsList &options) override;
94 void setSequenceNumber(uint32_t) override;
95 bool isPrimary() const override;
96 std::string getSecureInputApp() const override;
97
98 void waitForCarbonLoop() const;
99
100protected:
101 // IPlatformComputer overrides
102 void handleSystemEvent(const Event &e) override;
103 void updateButtons() override;
104 IKeyState *getKeyState() const override;
105
106private:
107 bool updateComputerShape();
108 bool updateComputerShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags);
109 void postMouseEvent(CGPoint &) const;
110
111 // convenience function to send events
112 void sendEvent(EventTypes type, void * = nullptr) const;
113 void sendClipboardEvent(EventTypes type, ClipboardID id) const;
114
115 // message handlers
116 bool onMouseMove(CGEventRef event);
117 // mouse button handler. pressed is true if this is a mousedown
118 // event, false if it is a mouseup event. macButton is the index
119 // of the button pressed using the mac button mapping.
120 bool onMouseButton(bool pressed, uint16_t macButton);
121 bool onMouseWheel(int32_t xDelta, int32_t yDelta) const;
122
123 void constructMouseButtonEventMap();
124
125 bool onKey(CGEventRef event);
126
127 void onMediaKey(CGEventRef event);
128
129 bool onHotKey(EventRef event) const;
130
131 // Added here to allow the carbon cursor hack to be called.
132 void showCursor();
133 void hideCursor();
134
135 // map deskflow mouse button to mac buttons
136 ButtonID mapDeskflowButtonToMac(uint16_t) const;
137
138 // map mac mouse button to deskflow buttons
139 ButtonID mapMacButtonToDeskflow(uint16_t) const;
140
141 // map mac scroll wheel value to a deskflow scroll wheel value
142 int32_t mapScrollWheelToDeskflow(int32_t) const;
143
144 // get the current scroll wheel speed
145 double getScrollSpeed() const;
146
147 // Resolution switch callback
148 static void displayReconfigurationCallback(CGDirectDisplayID, CGDisplayChangeSummaryFlags, void *);
149
150 // fast user switch callback
151 static pascal OSStatus userSwitchCallback(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData);
152
153 // sleep / wakeup support
154 void watchSystemPowerThread(const void *);
155 static void testCanceled(CFRunLoopTimerRef timer, void *info);
156 static void powerChangeCallback(void *refcon, io_service_t service, natural_t messageType, void *messageArgument);
157 void handlePowerChangeRequest(natural_t messageType, void *messageArgument);
158
159 void handleConfirmSleep(const Event &event);
160
161 bool checkAXPermissions();
162
163 // global hotkey operating mode
164 static bool isGlobalHotKeyOperatingModeAvailable();
165 static void setGlobalHotKeysEnabled(bool enabled);
166 static bool getGlobalHotKeysEnabled();
167
168 // Quartz event tap support
169 static CGEventRef handleCGInputEvent(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon);
170 static CGEventRef
171 handleCGInputEventSecondary(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon);
172
173 // convert CFString to char*
174 static char *CFStringRefToUTF8String(CFStringRef aString);
175
176private:
177 struct HotKeyItem
178 {
179 public:
180 HotKeyItem(uint32_t, uint32_t);
181 HotKeyItem(EventHotKeyRef, uint32_t, uint32_t);
182
183 EventHotKeyRef getRef() const;
184
185 bool operator<(const HotKeyItem &) const;
186
187 private:
188 EventHotKeyRef m_ref;
189 uint32_t m_keycode;
190 uint32_t m_mask;
191 };
192
193 enum EMouseButtonState
194 {
195 kMouseButtonUp = 0,
196 kMouseButtonDragged,
197 kMouseButtonDown,
198 kMouseButtonStateMax
199 };
200
201 class MouseButtonState
202 {
203 public:
204 void set(uint32_t button, EMouseButtonState state);
205 bool any();
206 void reset();
207 void overwrite(uint32_t buttons);
208
209 bool test(uint32_t button) const;
210 int8_t getFirstButtonDown() const;
211
212 private:
213 std::bitset<NumButtonIDs> m_buttons;
214 };
215
216 using HotKeyMap = std::map<uint32_t, HotKeyItem>;
217 using HotKeyIDList = std::vector<uint32_t>;
218 using ModifierHotKeyMap = std::map<KeyModifierMask, uint32_t>;
219 using HotKeyToIDMap = std::map<HotKeyItem, uint32_t>;
220
221 // true if screen is being used as a primary screen, false otherwise
222 bool m_isPrimary;
223
224 // true if mouse has entered the screen
225 bool m_isOnComputer;
226
227 // the display
228 CGDirectDisplayID m_displayID;
229
230 uint32_t m_activeSides = 0;
231 // screen shape stuff
232 int32_t m_x, m_y;
233 int32_t m_w, m_h;
234 int32_t m_xCenter, m_yCenter;
235
236 // mouse state
237 mutable int32_t m_xCursor, m_yCursor;
238 mutable bool m_cursorPosValid;
239
240 // mouse event number (needed for macOS 27)
241 uint32_t m_mouseEventNumber = 0;
242
243 /* FIXME: this data structure is explicitly marked mutable due
244 to a need to track the state of buttons since the remote
245 side only lets us know of change events, and because the
246 fakeMouseButton button method is marked 'const'. This is
247 Evil, and this should be moved to a place where it need not
248 be mutable as soon as possible. */
249 mutable MouseButtonState m_buttonState;
250 using MouseButtonEventMapType = std::map<uint16_t, CGEventType>;
251 std::vector<MouseButtonEventMapType> MouseButtonEventMap;
252
253 bool m_cursorHidden;
254
255 // keyboard stuff
256 OSXKeyState *m_keyState;
257
258 // clipboards
259 OSXClipboard m_pasteboard;
260 uint32_t m_sequenceNumber;
261
262 // screen saver stuff
263 OSXScreenSaver *m_screensaver;
264 bool m_screensaverNotify;
265
266 // clipboard stuff
267 bool m_ownClipboard;
268 EventQueueTimer *m_clipboardTimer;
269
270 EventQueueTimer *m_axTimer;
271
272 // window object that gets user input events when the server
273 // has focus.
274 WindowRef m_hiddenWindow;
275 // window object that gets user input events when the server
276 // does not have focus.
277 WindowRef m_userInputWindow;
278
279 // fast user switching
280 EventHandlerRef m_switchEventHandlerRef;
281
282 // sleep / wakeup
283 Mutex *m_pmMutex;
284 Thread *m_pmWatchThread;
285 CondVar<bool> *m_pmThreadReady;
286 CFRunLoopRef m_pmRunloop;
287 io_connect_t m_pmRootPort;
288 IOPMAssertionID m_userActivityAssertionID = kIOPMNullAssertionID;
289
290 // hot key stuff
291 HotKeyMap m_hotKeys;
292 HotKeyIDList m_oldHotKeyIDs;
293 ModifierHotKeyMap m_modifierHotKeys;
294 uint32_t m_activeModifierHotKey;
295 KeyModifierMask m_activeModifierHotKeyMask;
296 HotKeyToIDMap m_hotKeyToIDMap;
297
298 // global hotkey operating mode
299 static bool s_testedForGHOM;
300 static bool s_hasGHOM;
301
302 // Quartz input event support
303 CFMachPortRef m_eventTapPort;
304 CFRunLoopSourceRef m_eventTapRLSR;
305 std::thread m_eventTapThread;
306 CFRunLoopRef m_eventTapRunLoop = nullptr;
307
308 // for double click coalescing.
309 double m_lastClickTime;
310 int m_clickState;
311 int32_t m_lastSingleClickXCursor;
312 int32_t m_lastSingleClickYCursor;
313
314 IEventQueue *m_events;
315
316 std::unique_ptr<Thread> m_getDropTargetThread;
317 std::string m_dropTarget;
318
319 Mutex *m_carbonLoopMutex;
320 CondVar<bool> *m_carbonLoopReady;
321
322 OSXPowerManager m_powerManager;
323
324 class OSXComputerImpl *m_impl;
325};
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
CGError CGSSetConnectionProperty(CGSConnectionID cid, CGSConnectionID targetCID, CFStringRef key, CFTypeRef value)
int CGSConnectionID
Definition OSXComputer.h:30
int _CGSDefaultConnection()
std::vector< uint32_t > OptionsList
Definition OptionTypes.h:27
Condition variable.
Definition CondVar.h:121
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
Mutual exclusion.
Definition Mutex.h:22
void fakeMouseMove(int32_t x, int32_t y) override
Fake mouse move.
Definition OSXComputer.mm:587
void screensaver(bool activate) override
Activate/deactivate screen saver.
Definition OSXComputer.mm:870
int32_t getJumpZoneSize() const override
Get jump zone size.
Definition OSXComputer.mm:301
bool isAnyMouseButtonDown(uint32_t &buttonID) const override
Test if mouse is pressed.
Definition OSXComputer.mm:306
void disable() override
Disable computer.
Definition OSXComputer.mm:749
void setSequenceNumber(uint32_t) override
Set clipboard sequence number.
Definition OSXComputer.mm:889
IEventQueue * getEvents() const
Definition OSXComputer.h:52
void enter() override
Enter computer.
Definition OSXComputer.mm:790
void checkClipboards() override
Check clipboard owner.
Definition OSXComputer.mm:845
bool isPrimary() const override
Test if is primary computer.
Definition OSXComputer.mm:894
IKeyState * getKeyState() const override
Get the key state.
Definition OSXComputer.mm:1301
void unregisterHotKey(uint32_t id) override
Unregister a system hotkey.
Definition OSXComputer.mm:375
void updateButtons() override
Update mouse buttons.
Definition OSXComputer.mm:1294
void setOptions(const OptionsList &options) override
Notify of options changes.
Definition OSXComputer.mm:884
uint32_t registerHotKey(KeyID key, KeyModifierMask mask) override
Register a system hotkey.
Definition OSXComputer.mm:322
OSXComputer(IEventQueue *events, bool isPrimary, bool enableLangSync=false)
Definition OSXComputer.mm:86
void fakeInputBegin() override
Prepare to synthesize input on primary computer.
Definition OSXComputer.mm:291
uint32_t activeSides() override
activeSides
Definition OSXComputer.mm:264
void handleSystemEvent(const Event &e) override
Handle system event.
Definition OSXComputer.mm:912
bool setClipboard(ClipboardID, const IClipboard *) override
Set clipboard.
Definition OSXComputer.mm:836
void fakeInputEnd() override
Done synthesizing input on primary computer.
Definition OSXComputer.mm:296
void leave() override
Leave computer.
Definition OSXComputer.mm:819
void openScreensaver(bool notify) override
Open screen saver.
Definition OSXComputer.mm:855
void enable() override
Enable computer.
Definition OSXComputer.mm:690
void fakeMouseRelativeMove(int32_t dx, int32_t dy) const override
Fake mouse move.
Definition OSXComputer.mm:601
void closeScreensaver() override
Close screen saver.
Definition OSXComputer.mm:863
void reconfigure(uint32_t activeSides) override
Update configuration.
Definition OSXComputer.mm:257
void getCursorPos(int32_t &x, int32_t &y) const override
Get cursor position.
Definition OSXComputer.mm:245
bool getClipboard(ClipboardID id, IClipboard *) const override
Get clipboard.
Definition OSXComputer.mm:231
void resetOptions() override
Notify of options changes.
Definition OSXComputer.mm:879
bool canLeave() override
Leave computer.
Definition OSXComputer.mm:814
void getCursorCenter(int32_t &x, int32_t &y) const override
Get cursor center position.
Definition OSXComputer.mm:316
void waitForCarbonLoop() const
Definition OSXComputer.mm:1801
void getShape(int32_t &x, int32_t &y, int32_t &width, int32_t &height) const override
Get computer shape.
Definition OSXComputer.mm:237
void warpCursor(int32_t x, int32_t y) override
Warp cursor.
Definition OSXComputer.mm:269
void fakeMouseWheel(ScrollDelta delta) const override
Synthesize a mouse wheel event of amount This Implmentation for this method should call applyScrollMo...
Definition OSXComputer.mm:625
void fakeMouseButton(ButtonID id, bool press) override
Fake mouse press/release.
Definition OSXComputer.mm:504
void * getEventTarget() const override
Get event target.
Definition OSXComputer.mm:226
std::string getSecureInputApp() const override
Determine the name of the app causing a secure input state.
Definition OSXComputer.mm:1823
OS X key state.
Definition OSXKeyState.h:25
OSX screen saver implementation.
Definition OSXScreenSaver.h:18
PlatformComputer(IEventQueue *events)
Definition PlatformComputer.cpp:13
Thread handle.
Definition Thread.h:33
EventTypes
Definition EventTypes.h:13