diff options
Diffstat (limited to 'src/lib/platform/OSXScreen.h')
| -rw-r--r-- | src/lib/platform/OSXScreen.h | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h new file mode 100644 index 0000000..27cb7df --- /dev/null +++ b/src/lib/platform/OSXScreen.h @@ -0,0 +1,349 @@ +/* + * barrier -- mouse and keyboard sharing utility + * Copyright (C) 2012-2016 Symless Ltd. + * Copyright (C) 2004 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "platform/OSXClipboard.h" +#include "barrier/PlatformScreen.h" +#include "barrier/DragInformation.h" +#include "base/EventTypes.h" +#include "common/stdmap.h" +#include "common/stdvector.h" + +#include <bitset> +#include <Carbon/Carbon.h> +#include <mach/mach_port.h> +#include <mach/mach_interface.h> +#include <mach/mach_init.h> +#include <IOKit/pwr_mgt/IOPMLib.h> +#include <IOKit/IOMessage.h> + +extern "C" { + typedef int CGSConnectionID; + CGError CGSSetConnectionProperty(CGSConnectionID cid, CGSConnectionID targetCID, CFStringRef key, CFTypeRef value); + int _CGSDefaultConnection(); +} + + +template <class T> +class CondVar; +class EventQueueTimer; +class Mutex; +class Thread; +class OSXKeyState; +class OSXScreenSaver; +class IEventQueue; +class Mutex; + +//! Implementation of IPlatformScreen for OS X +class OSXScreen : public PlatformScreen { +public: + OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCursor=true); + virtual ~OSXScreen(); + + IEventQueue* getEvents() const { return m_events; } + + // IScreen overrides + virtual void* getEventTarget() const; + virtual bool getClipboard(ClipboardID id, IClipboard*) const; + virtual void getShape(SInt32& x, SInt32& y, + SInt32& width, SInt32& height) const; + virtual void getCursorPos(SInt32& x, SInt32& y) const; + + // IPrimaryScreen overrides + virtual void reconfigure(UInt32 activeSides); + virtual void warpCursor(SInt32 x, SInt32 y); + virtual UInt32 registerHotKey(KeyID key, KeyModifierMask mask); + virtual void unregisterHotKey(UInt32 id); + virtual void fakeInputBegin(); + virtual void fakeInputEnd(); + virtual SInt32 getJumpZoneSize() const; + virtual bool isAnyMouseButtonDown(UInt32& buttonID) const; + virtual void getCursorCenter(SInt32& x, SInt32& y) const; + + // ISecondaryScreen overrides + virtual void fakeMouseButton(ButtonID id, bool press); + virtual void fakeMouseMove(SInt32 x, SInt32 y); + virtual void fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const; + virtual void fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const; + + // IPlatformScreen overrides + virtual void enable(); + virtual void disable(); + virtual void enter(); + virtual bool leave(); + virtual bool setClipboard(ClipboardID, const IClipboard*); + virtual void checkClipboards(); + virtual void openScreensaver(bool notify); + virtual void closeScreensaver(); + virtual void screensaver(bool activate); + virtual void resetOptions(); + virtual void setOptions(const OptionsList& options); + virtual void setSequenceNumber(UInt32); + virtual bool isPrimary() const; + virtual void fakeDraggingFiles(DragFileList fileList); + virtual String& getDraggingFilename(); + + const String& getDropTarget() const { return m_dropTarget; } + void waitForCarbonLoop() const; + +protected: + // IPlatformScreen overrides + virtual void handleSystemEvent(const Event&, void*); + virtual void updateButtons(); + virtual IKeyState* getKeyState() const; + +private: + void updateScreenShape(); + void updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags); + void postMouseEvent(CGPoint&) const; + + // convenience function to send events + void sendEvent(Event::Type type, void* = NULL) const; + void sendClipboardEvent(Event::Type type, ClipboardID id) const; + + // message handlers + bool onMouseMove(SInt32 mx, SInt32 my); + // mouse button handler. pressed is true if this is a mousedown + // event, false if it is a mouseup event. macButton is the index + // of the button pressed using the mac button mapping. + bool onMouseButton(bool pressed, UInt16 macButton); + bool onMouseWheel(SInt32 xDelta, SInt32 yDelta) const; + + void constructMouseButtonEventMap(); + + bool onKey(CGEventRef event); + + void onMediaKey(CGEventRef event); + + bool onHotKey(EventRef event) const; + + // Added here to allow the carbon cursor hack to be called. + void showCursor(); + void hideCursor(); + + // map barrier mouse button to mac buttons + ButtonID mapBarrierButtonToMac(UInt16) const; + + // map mac mouse button to barrier buttons + ButtonID mapMacButtonToBarrier(UInt16) const; + + // map mac scroll wheel value to a barrier scroll wheel value + SInt32 mapScrollWheelToBarrier(SInt32) const; + + // map barrier scroll wheel value to a mac scroll wheel value + SInt32 mapScrollWheelFromBarrier(SInt32) const; + + // get the current scroll wheel speed + double getScrollSpeed() const; + + // get the current scroll wheel speed + double getScrollSpeedFactor() const; + + // enable/disable drag handling for buttons 3 and up + void enableDragTimer(bool enable); + + // drag timer handler + void handleDrag(const Event&, void*); + + // clipboard check timer handler + void handleClipboardCheck(const Event&, void*); + + // Resolution switch callback + static void displayReconfigurationCallback(CGDirectDisplayID, + CGDisplayChangeSummaryFlags, void*); + + // fast user switch callback + static pascal OSStatus + userSwitchCallback(EventHandlerCallRef nextHandler, + EventRef theEvent, void* inUserData); + + // sleep / wakeup support + void watchSystemPowerThread(void*); + static void testCanceled(CFRunLoopTimerRef timer, void*info); + static void powerChangeCallback(void* refcon, io_service_t service, + natural_t messageType, void* messageArgument); + void handlePowerChangeRequest(natural_t messageType, + void* messageArgument); + + void handleConfirmSleep(const Event& event, void*); + + // global hotkey operating mode + static bool isGlobalHotKeyOperatingModeAvailable(); + static void setGlobalHotKeysEnabled(bool enabled); + static bool getGlobalHotKeysEnabled(); + + // Quartz event tap support + static CGEventRef handleCGInputEvent(CGEventTapProxy proxy, + CGEventType type, + CGEventRef event, + void* refcon); + static CGEventRef handleCGInputEventSecondary(CGEventTapProxy proxy, + CGEventType type, + CGEventRef event, + void* refcon); + + // convert CFString to char* + static char* CFStringRefToUTF8String(CFStringRef aString); + + void getDropTargetThread(void*); + +private: + struct HotKeyItem { + public: + HotKeyItem(UInt32, UInt32); + HotKeyItem(EventHotKeyRef, UInt32, UInt32); + + EventHotKeyRef getRef() const; + + bool operator<(const HotKeyItem&) const; + + private: + EventHotKeyRef m_ref; + UInt32 m_keycode; + UInt32 m_mask; + }; + + enum EMouseButtonState { + kMouseButtonUp = 0, + kMouseButtonDragged, + kMouseButtonDown, + kMouseButtonStateMax + }; + + + class MouseButtonState { + public: + void set(UInt32 button, EMouseButtonState state); + bool any(); + void reset(); + void overwrite(UInt32 buttons); + + bool test(UInt32 button) const; + SInt8 getFirstButtonDown() const; + private: + std::bitset<NumButtonIDs> m_buttons; + }; + + typedef std::map<UInt32, HotKeyItem> HotKeyMap; + typedef std::vector<UInt32> HotKeyIDList; + typedef std::map<KeyModifierMask, UInt32> ModifierHotKeyMap; + typedef std::map<HotKeyItem, UInt32> HotKeyToIDMap; + + // true if screen is being used as a primary screen, false otherwise + bool m_isPrimary; + + // true if mouse has entered the screen + bool m_isOnScreen; + + // the display + CGDirectDisplayID m_displayID; + + // screen shape stuff + SInt32 m_x, m_y; + SInt32 m_w, m_h; + SInt32 m_xCenter, m_yCenter; + + // mouse state + mutable SInt32 m_xCursor, m_yCursor; + mutable bool m_cursorPosValid; + + /* FIXME: this data structure is explicitly marked mutable due + to a need to track the state of buttons since the remote + side only lets us know of change events, and because the + fakeMouseButton button method is marked 'const'. This is + Evil, and this should be moved to a place where it need not + be mutable as soon as possible. */ + mutable MouseButtonState m_buttonState; + typedef std::map<UInt16, CGEventType> MouseButtonEventMapType; + std::vector<MouseButtonEventMapType> MouseButtonEventMap; + + bool m_cursorHidden; + SInt32 m_dragNumButtonsDown; + Point m_dragLastPoint; + EventQueueTimer* m_dragTimer; + + // keyboard stuff + OSXKeyState* m_keyState; + + // clipboards + OSXClipboard m_pasteboard; + UInt32 m_sequenceNumber; + + // screen saver stuff + OSXScreenSaver* m_screensaver; + bool m_screensaverNotify; + + // clipboard stuff + bool m_ownClipboard; + EventQueueTimer* m_clipboardTimer; + + // window object that gets user input events when the server + // has focus. + WindowRef m_hiddenWindow; + // window object that gets user input events when the server + // does not have focus. + WindowRef m_userInputWindow; + + // fast user switching + EventHandlerRef m_switchEventHandlerRef; + + // sleep / wakeup + Mutex* m_pmMutex; + Thread* m_pmWatchThread; + CondVar<bool>* m_pmThreadReady; + CFRunLoopRef m_pmRunloop; + io_connect_t m_pmRootPort; + + // hot key stuff + HotKeyMap m_hotKeys; + HotKeyIDList m_oldHotKeyIDs; + ModifierHotKeyMap m_modifierHotKeys; + UInt32 m_activeModifierHotKey; + KeyModifierMask m_activeModifierHotKeyMask; + HotKeyToIDMap m_hotKeyToIDMap; + + // global hotkey operating mode + static bool s_testedForGHOM; + static bool s_hasGHOM; + + // Quartz input event support + CFMachPortRef m_eventTapPort; + CFRunLoopSourceRef m_eventTapRLSR; + + // for double click coalescing. + double m_lastClickTime; + int m_clickState; + SInt32 m_lastSingleClickXCursor; + SInt32 m_lastSingleClickYCursor; + + // cursor will hide and show on enable and disable if true. + bool m_autoShowHideCursor; + + IEventQueue* m_events; + + Thread* m_getDropTargetThread; + String m_dropTarget; + +#if defined(MAC_OS_X_VERSION_10_7) + Mutex* m_carbonLoopMutex; + CondVar<bool>* m_carbonLoopReady; +#endif + + class OSXScreenImpl* m_impl; +}; |
