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