Deskflow 1.24.0.365
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, bool invertScrolling = 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(int32_t xDelta, int32_t yDelta) 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 // map deskflow scroll wheel value to a mac scroll wheel value
143 int32_t mapScrollWheelFromDeskflow(int32_t) const;
144
145 // get the current scroll wheel speed
146 double getScrollSpeed() const;
147
148 // Resolution switch callback
149 static void displayReconfigurationCallback(CGDirectDisplayID, CGDisplayChangeSummaryFlags, void *);
150
151 // fast user switch callback
152 static pascal OSStatus userSwitchCallback(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData);
153
154 // sleep / wakeup support
155 void watchSystemPowerThread(const void *);
156 static void testCanceled(CFRunLoopTimerRef timer, void *info);
157 static void powerChangeCallback(void *refcon, io_service_t service, natural_t messageType, void *messageArgument);
158 void handlePowerChangeRequest(natural_t messageType, void *messageArgument);
159
160 void handleConfirmSleep(const Event &event);
161
162 // global hotkey operating mode
163 static bool isGlobalHotKeyOperatingModeAvailable();
164 static void setGlobalHotKeysEnabled(bool enabled);
165 static bool getGlobalHotKeysEnabled();
166
167 // Quartz event tap support
168 static CGEventRef handleCGInputEvent(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon);
169 static CGEventRef
170 handleCGInputEventSecondary(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon);
171
172 // convert CFString to char*
173 static char *CFStringRefToUTF8String(CFStringRef aString);
174
175private:
176 struct HotKeyItem
177 {
178 public:
179 HotKeyItem(uint32_t, uint32_t);
180 HotKeyItem(EventHotKeyRef, uint32_t, uint32_t);
181
182 EventHotKeyRef getRef() const;
183
184 bool operator<(const HotKeyItem &) const;
185
186 private:
187 EventHotKeyRef m_ref;
188 uint32_t m_keycode;
189 uint32_t m_mask;
190 };
191
192 enum EMouseButtonState
193 {
194 kMouseButtonUp = 0,
195 kMouseButtonDragged,
196 kMouseButtonDown,
197 kMouseButtonStateMax
198 };
199
200 class MouseButtonState
201 {
202 public:
203 void set(uint32_t button, EMouseButtonState state);
204 bool any();
205 void reset();
206 void overwrite(uint32_t buttons);
207
208 bool test(uint32_t button) const;
209 int8_t getFirstButtonDown() const;
210
211 private:
212 std::bitset<NumButtonIDs> m_buttons;
213 };
214
215 using HotKeyMap = std::map<uint32_t, HotKeyItem>;
216 using HotKeyIDList = std::vector<uint32_t>;
217 using ModifierHotKeyMap = std::map<KeyModifierMask, uint32_t>;
218 using HotKeyToIDMap = std::map<HotKeyItem, uint32_t>;
219
220 // true if screen is being used as a primary screen, false otherwise
221 bool m_isPrimary;
222
223 // true if mouse has entered the screen
224 bool m_isOnScreen;
225
226 // the display
227 CGDirectDisplayID m_displayID;
228
229 uint32_t m_activeSides = 0;
230 // screen shape stuff
231 int32_t m_x, m_y;
232 int32_t m_w, m_h;
233 int32_t m_xCenter, m_yCenter;
234
235 // mouse state
236 mutable int32_t m_xCursor, m_yCursor;
237 mutable bool m_cursorPosValid;
238
239 /* FIXME: this data structure is explicitly marked mutable due
240 to a need to track the state of buttons since the remote
241 side only lets us know of change events, and because the
242 fakeMouseButton button method is marked 'const'. This is
243 Evil, and this should be moved to a place where it need not
244 be mutable as soon as possible. */
245 mutable MouseButtonState m_buttonState;
246 using MouseButtonEventMapType = std::map<uint16_t, CGEventType>;
247 std::vector<MouseButtonEventMapType> MouseButtonEventMap;
248
249 bool m_cursorHidden;
250
251 // keyboard stuff
252 OSXKeyState *m_keyState;
253
254 // clipboards
255 OSXClipboard m_pasteboard;
256 uint32_t m_sequenceNumber;
257
258 // screen saver stuff
259 OSXScreenSaver *m_screensaver;
260 bool m_screensaverNotify;
261
262 // clipboard stuff
263 bool m_ownClipboard;
264 EventQueueTimer *m_clipboardTimer;
265
266 // window object that gets user input events when the server
267 // has focus.
268 WindowRef m_hiddenWindow;
269 // window object that gets user input events when the server
270 // does not have focus.
271 WindowRef m_userInputWindow;
272
273 // fast user switching
274 EventHandlerRef m_switchEventHandlerRef;
275
276 // sleep / wakeup
277 Mutex *m_pmMutex;
278 Thread *m_pmWatchThread;
279 CondVar<bool> *m_pmThreadReady;
280 CFRunLoopRef m_pmRunloop;
281 io_connect_t m_pmRootPort;
282
283 // hot key stuff
284 HotKeyMap m_hotKeys;
285 HotKeyIDList m_oldHotKeyIDs;
286 ModifierHotKeyMap m_modifierHotKeys;
287 uint32_t m_activeModifierHotKey;
288 KeyModifierMask m_activeModifierHotKeyMask;
289 HotKeyToIDMap m_hotKeyToIDMap;
290
291 // global hotkey operating mode
292 static bool s_testedForGHOM;
293 static bool s_hasGHOM;
294
295 // Quartz input event support
296 CFMachPortRef m_eventTapPort;
297 CFRunLoopSourceRef m_eventTapRLSR;
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
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:549
std::string getSecureInputApp() const override
Determine the name of the app causing a secure input state.
Definition OSXScreen.mm:1772
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:747
void handleSystemEvent(const Event &e) override
Handle system event.
Definition OSXScreen.mm:840
void enter() override
Enter screen.
Definition OSXScreen.mm:723
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:651
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:694
void fakeMouseRelativeMove(int32_t dx, int32_t dy) const override
Fake mouse move.
Definition OSXScreen.mm:563
void screensaver(bool activate) override
Activate/deactivate screen saver.
Definition OSXScreen.mm:798
void setSequenceNumber(uint32_t) override
Set clipboard sequence number.
Definition OSXScreen.mm:817
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:481
void fakeMouseWheel(int32_t xDelta, int32_t yDelta) const override
Fake mouse wheel.
Definition OSXScreen.mm:587
void leave() override
Leave screen.
Definition OSXScreen.mm:752
void openScreensaver(bool notify) override
Open screen saver.
Definition OSXScreen.mm:783
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:773
int32_t getJumpZoneSize() const override
Get jump zone size.
Definition OSXScreen.mm:283
bool setClipboard(ClipboardID, const IClipboard *) override
Set clipboard.
Definition OSXScreen.mm:764
bool isPrimary() const override
Test if is primary screen.
Definition OSXScreen.mm:822
IEventQueue * getEvents() const
Definition OSXScreen.h:50
void closeScreensaver() override
Close screen saver.
Definition OSXScreen.mm:791
bool getClipboard(ClipboardID id, IClipboard *) const override
Get clipboard.
Definition OSXScreen.mm:221
OSXScreen(IEventQueue *events, bool isPrimary, bool enableLangSync=false, bool invertScrolling=false)
Definition OSXScreen.mm:77
void setOptions(const OptionsList &options) override
Notify of options changes.
Definition OSXScreen.mm:812
void waitForCarbonLoop() const
Definition OSXScreen.mm:1750
IKeyState * getKeyState() const override
Get the key state.
Definition OSXScreen.mm:1255
void fakeInputBegin() override
Prepare to synthesize input on primary screen.
Definition OSXScreen.mm:273
void resetOptions() override
Notify of options changes.
Definition OSXScreen.mm:807
void updateButtons() override
Update mouse buttons.
Definition OSXScreen.mm:1248
PlatformScreen(IEventQueue *events, bool invertScrollDirection)
Definition PlatformScreen.cpp:12
Thread handle.
Definition Thread.h:33
EventTypes
Definition EventTypes.h:13