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