Deskflow 1.22.0.197
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
11#include "base/EventTypes.h"
15
16#include <Carbon/Carbon.h>
17#include <IOKit/IOMessage.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 <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:
48 IEventQueue *events, bool isPrimary, bool enableLangSync = false,
50 );
51
52 virtual ~OSXScreen();
53
55 {
56 return m_events;
57 }
58
59 // IScreen overrides
60 void *getEventTarget() const override;
61 bool getClipboard(ClipboardID id, IClipboard *) const override;
62 void getShape(int32_t &x, int32_t &y, int32_t &width, int32_t &height) const override;
63 void getCursorPos(int32_t &x, int32_t &y) const override;
64
65 // IPrimaryScreen overrides
66 void reconfigure(uint32_t activeSides) override;
67 uint32_t activeSides() override;
68 void warpCursor(int32_t x, int32_t y) override;
69 uint32_t registerHotKey(KeyID key, KeyModifierMask mask) override;
70 void unregisterHotKey(uint32_t id) override;
71 void fakeInputBegin() override;
72 void fakeInputEnd() override;
73 int32_t getJumpZoneSize() const override;
74 bool isAnyMouseButtonDown(uint32_t &buttonID) const override;
75 void getCursorCenter(int32_t &x, int32_t &y) const override;
76
77 // ISecondaryScreen overrides
78 void fakeMouseButton(ButtonID id, bool press) override;
79 void fakeMouseMove(int32_t x, int32_t y) override;
80 void fakeMouseRelativeMove(int32_t dx, int32_t dy) const override;
81 void fakeMouseWheel(int32_t xDelta, int32_t yDelta) const override;
82
83 // IPlatformScreen overrides
84 void enable() override;
85 void disable() override;
86 void enter() override;
87 bool canLeave() override;
88 void leave() override;
89 bool setClipboard(ClipboardID, const IClipboard *) override;
90 void checkClipboards() override;
91 void openScreensaver(bool notify) override;
92 void closeScreensaver() override;
93 void screensaver(bool activate) override;
94 void resetOptions() override;
95 void setOptions(const OptionsList &options) override;
96 void setSequenceNumber(uint32_t) override;
97 bool isPrimary() const override;
98 std::string getSecureInputApp() const override;
99
100 void waitForCarbonLoop() const;
101
102protected:
103 // IPlatformScreen overrides
104 void handleSystemEvent(const Event &e) override;
105 void updateButtons() override;
106 IKeyState *getKeyState() const override;
107
108private:
109 bool updateScreenShape();
110 bool updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags);
111 void postMouseEvent(CGPoint &) const;
112
113 // convenience function to send events
114 void sendEvent(EventTypes type, void * = nullptr) const;
115 void sendClipboardEvent(EventTypes type, ClipboardID id) const;
116
117 // message handlers
118 bool onMouseMove(CGFloat mx, CGFloat my);
119 // mouse button handler. pressed is true if this is a mousedown
120 // event, false if it is a mouseup event. macButton is the index
121 // of the button pressed using the mac button mapping.
122 bool onMouseButton(bool pressed, uint16_t macButton);
123 bool onMouseWheel(int32_t xDelta, int32_t yDelta) const;
124
125 void constructMouseButtonEventMap();
126
127 bool onKey(CGEventRef event);
128
129 void onMediaKey(CGEventRef event);
130
131 bool onHotKey(EventRef event) const;
132
133 // Added here to allow the carbon cursor hack to be called.
134 void showCursor();
135 void hideCursor();
136
137 // map deskflow mouse button to mac buttons
138 ButtonID mapDeskflowButtonToMac(uint16_t) const;
139
140 // map mac mouse button to deskflow buttons
141 ButtonID mapMacButtonToDeskflow(uint16_t) const;
142
143 // map mac scroll wheel value to a deskflow scroll wheel value
144 int32_t mapScrollWheelToDeskflow(int32_t) const;
145
146 // map deskflow scroll wheel value to a mac scroll wheel value
147 int32_t mapScrollWheelFromDeskflow(int32_t) const;
148
149 // get the current scroll wheel speed
150 double getScrollSpeed() const;
151
152 // Resolution switch callback
153 static void displayReconfigurationCallback(CGDirectDisplayID, CGDisplayChangeSummaryFlags, void *);
154
155 // fast user switch callback
156 static pascal OSStatus userSwitchCallback(EventHandlerCallRef nextHandler, EventRef theEvent, void *inUserData);
157
158 // sleep / wakeup support
159 void watchSystemPowerThread(void *);
160 static void testCanceled(CFRunLoopTimerRef timer, void *info);
161 static void powerChangeCallback(void *refcon, io_service_t service, natural_t messageType, void *messageArgument);
162 void handlePowerChangeRequest(natural_t messageType, void *messageArgument);
163
164 void handleConfirmSleep(const Event &event);
165
166 // global hotkey operating mode
167 static bool isGlobalHotKeyOperatingModeAvailable();
168 static void setGlobalHotKeysEnabled(bool enabled);
169 static bool getGlobalHotKeysEnabled();
170
171 // Quartz event tap support
172 static CGEventRef handleCGInputEvent(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon);
173 static CGEventRef
174 handleCGInputEventSecondary(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon);
175
176 // convert CFString to char*
177 static char *CFStringRefToUTF8String(CFStringRef aString);
178
179private:
180 struct HotKeyItem
181 {
182 public:
183 HotKeyItem(uint32_t, uint32_t);
184 HotKeyItem(EventHotKeyRef, uint32_t, uint32_t);
185
186 EventHotKeyRef getRef() const;
187
188 bool operator<(const HotKeyItem &) const;
189
190 private:
191 EventHotKeyRef m_ref;
192 uint32_t m_keycode;
193 uint32_t m_mask;
194 };
195
196 enum EMouseButtonState
197 {
198 kMouseButtonUp = 0,
199 kMouseButtonDragged,
200 kMouseButtonDown,
201 kMouseButtonStateMax
202 };
203
204 class MouseButtonState
205 {
206 public:
207 void set(uint32_t button, EMouseButtonState state);
208 bool any();
209 void reset();
210 void overwrite(uint32_t buttons);
211
212 bool test(uint32_t button) const;
213 int8_t getFirstButtonDown() const;
214
215 private:
216 std::bitset<NumButtonIDs> m_buttons;
217 };
218
219 using HotKeyMap = std::map<uint32_t, HotKeyItem>;
220 using HotKeyIDList = std::vector<uint32_t>;
221 using ModifierHotKeyMap = std::map<KeyModifierMask, uint32_t>;
222 using HotKeyToIDMap = std::map<HotKeyItem, uint32_t>;
223
224 // true if screen is being used as a primary screen, false otherwise
225 bool m_isPrimary;
226
227 // true if mouse has entered the screen
228 bool m_isOnScreen;
229
230 // the display
231 CGDirectDisplayID m_displayID;
232
233 uint32_t m_activeSides = 0;
234 // screen shape stuff
235 int32_t m_x, m_y;
236 int32_t m_w, m_h;
237 int32_t m_xCenter, m_yCenter;
238
239 // mouse state
240 mutable int32_t m_xCursor, m_yCursor;
241 mutable bool m_cursorPosValid;
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 // window object that gets user input events when the server
271 // has focus.
272 WindowRef m_hiddenWindow;
273 // window object that gets user input events when the server
274 // does not have focus.
275 WindowRef m_userInputWindow;
276
277 // fast user switching
278 EventHandlerRef m_switchEventHandlerRef;
279
280 // sleep / wakeup
281 Mutex *m_pmMutex;
282 Thread *m_pmWatchThread;
283 CondVar<bool> *m_pmThreadReady;
284 CFRunLoopRef m_pmRunloop;
285 io_connect_t m_pmRootPort;
286
287 // hot key stuff
288 HotKeyMap m_hotKeys;
289 HotKeyIDList m_oldHotKeyIDs;
290 ModifierHotKeyMap m_modifierHotKeys;
291 uint32_t m_activeModifierHotKey;
292 KeyModifierMask m_activeModifierHotKeyMask;
293 HotKeyToIDMap m_hotKeyToIDMap;
294
295 // global hotkey operating mode
296 static bool s_testedForGHOM;
297 static bool s_hasGHOM;
298
299 // Quartz input event support
300 CFMachPortRef m_eventTapPort;
301 CFRunLoopSourceRef m_eventTapRLSR;
302
303 // for double click coalescing.
304 double m_lastClickTime;
305 int m_clickState;
306 int32_t m_lastSingleClickXCursor;
307 int32_t m_lastSingleClickYCursor;
308
309 IEventQueue *m_events;
310
311 std::unique_ptr<Thread> m_getDropTargetThread;
312 std::string m_dropTarget;
313
314 Mutex *m_carbonLoopMutex;
315 CondVar<bool> *m_carbonLoopReady;
316
317 OSXPowerManager m_powerManager;
318
319 class OSXScreenImpl *m_impl;
320};
static int type
Definition ArchNetworkWinsock.cpp:44
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: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 OSXScreen.h:29
int _CGSDefaultConnection()
std::vector< uint32_t > OptionsList
Definition OptionTypes.h:27
int y
Definition ServerConfig.cpp:27
int x
Definition ServerConfig.cpp:26
Condition variable.
Definition CondVar.h:122
Definition SimpleEventQueueBuffer.cpp:13
Event.
Definition Event.h:27
Clipboard interface.
Definition IClipboard.h:20
Event queue interface.
Definition IEventQueue.h:32
Key state interface.
Definition IKeyState.h:24
Mutual exclusion.
Definition Mutex.h:22
OS X key state.
Definition OSXKeyState.h:26
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:1767
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:303
bool canLeave() override
Leave screen.
Definition OSXScreen.mm:748
void handleSystemEvent(const Event &e) override
Handle system event.
Definition OSXScreen.mm:841
void enter() override
Enter screen.
Definition OSXScreen.mm:724
virtual ~OSXScreen()
Definition OSXScreen.mm:177
uint32_t activeSides() override
activeSides
Definition OSXScreen.mm:253
void getCursorCenter(int32_t &x, int32_t &y) const override
Get cursor center position.
Definition OSXScreen.mm:297
void fakeInputEnd() override
Done synthesizing input on primary screen.
Definition OSXScreen.mm:277
void enable() override
Enable screen.
Definition OSXScreen.mm:652
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:695
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:799
void setSequenceNumber(uint32_t) override
Set clipboard sequence number.
Definition OSXScreen.mm:818
bool isAnyMouseButtonDown(uint32_t &buttonID) const override
Test if mouse is pressed.
Definition OSXScreen.mm:287
OSXScreen(IEventQueue *events, bool isPrimary, bool enableLangSync=false, deskflow::ClientScrollDirection scrollDirection=deskflow::ClientScrollDirection::Normal)
Definition OSXScreen.mm:75
void warpCursor(int32_t x, int32_t y) override
Warp cursor.
Definition OSXScreen.mm:258
void fakeMouseButton(ButtonID id, bool press) override
Fake mouse press/release.
Definition OSXScreen.mm:482
void fakeMouseWheel(int32_t xDelta, int32_t yDelta) const override
Fake mouse wheel.
Definition OSXScreen.mm:588
void leave() override
Leave screen.
Definition OSXScreen.mm:753
void openScreensaver(bool notify) override
Open screen saver.
Definition OSXScreen.mm:784
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:774
int32_t getJumpZoneSize() const override
Get jump zone size.
Definition OSXScreen.mm:282
bool setClipboard(ClipboardID, const IClipboard *) override
Set clipboard.
Definition OSXScreen.mm:765
bool isPrimary() const override
Test if is primary screen.
Definition OSXScreen.mm:823
IEventQueue * getEvents() const
Definition OSXScreen.h:54
void closeScreensaver() override
Close screen saver.
Definition OSXScreen.mm:792
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:813
void waitForCarbonLoop() const
Definition OSXScreen.mm:1745
IKeyState * getKeyState() const override
Get the key state.
Definition OSXScreen.mm:1250
void fakeInputBegin() override
Prepare to synthesize input on primary screen.
Definition OSXScreen.mm:272
void resetOptions() override
Notify of options changes.
Definition OSXScreen.mm:808
void updateButtons() override
Update mouse buttons.
Definition OSXScreen.mm:1243
PlatformScreen(IEventQueue *events, deskflow::ClientScrollDirection scrollDirection=deskflow::ClientScrollDirection::Normal)
Definition PlatformScreen.cpp:12
Thread handle.
Definition Thread.h:33
ClientScrollDirection
Definition ClientArgs.h:13
@ Normal
Same direction as the server.
Definition ClientArgs.h:14
EventTypes
Definition EventTypes.h:13