bool COSXScreen::onDisplayChange() { // screen resolution may have changed. save old shape. SInt32 xOld = m_x, yOld = m_y, wOld = m_w, hOld = m_h; // update shape updateScreenShape(); // do nothing if resolution hasn't changed if (xOld != m_x || yOld != m_y || wOld != m_w || hOld != m_h) { if (m_isPrimary) { // warp mouse to center if off screen if (!m_isOnScreen) { warpCursor(m_xCenter, m_yCenter); } } // send new screen info sendEvent(m_events->forIPrimaryScreen().shapeChanged()); } return true; }
COSXScreen::COSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCursor) : CPlatformScreen(events), m_events(events), MouseButtonEventMap(NumButtonIDs), m_isPrimary(isPrimary), m_isOnScreen(m_isPrimary), m_cursorPosValid(false), m_cursorHidden(false), m_dragNumButtonsDown(0), m_dragTimer(NULL), m_keyState(NULL), m_sequenceNumber(0), m_screensaver(NULL), m_screensaverNotify(false), m_ownClipboard(false), m_clipboardTimer(NULL), m_hiddenWindow(NULL), m_userInputWindow(NULL), m_switchEventHandlerRef(0), m_pmMutex(new CMutex), m_pmWatchThread(NULL), m_pmThreadReady(new CCondVar<bool>(m_pmMutex, false)), m_activeModifierHotKey(0), m_activeModifierHotKeyMask(0), m_lastSingleClick(0), m_lastDoubleClick(0), m_lastSingleClickXCursor(0), m_lastSingleClickYCursor(0), m_autoShowHideCursor(autoShowHideCursor), m_eventTapRLSR(nullptr), m_eventTapPort(nullptr), m_pmRootPort(0) { try { m_displayID = CGMainDisplayID(); updateScreenShape(m_displayID, 0); m_screensaver = new COSXScreenSaver(m_events, getEventTarget()); m_keyState = new COSXKeyState(m_events); // TODO: http://stackoverflow.com/questions/2950124/enable-access-for-assistive-device-programmatically if (m_isPrimary && !AXAPIEnabled()) throw XArch("system setting not enabled: \"Enable access for assistive devices\""); // install display manager notification handler #if defined(MAC_OS_X_VERSION_10_5) CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, this); #else m_displayManagerNotificationUPP = NewDMExtendedNotificationUPP(displayManagerCallback); OSStatus err = GetCurrentProcess(&m_PSN); err = DMRegisterExtendedNotifyProc(m_displayManagerNotificationUPP, this, 0, &m_PSN); #endif // install fast user switching event handler EventTypeSpec switchEventTypes[2]; switchEventTypes[0].eventClass = kEventClassSystem; switchEventTypes[0].eventKind = kEventSystemUserSessionDeactivated; switchEventTypes[1].eventClass = kEventClassSystem; switchEventTypes[1].eventKind = kEventSystemUserSessionActivated; EventHandlerUPP switchEventHandler = NewEventHandlerUPP(userSwitchCallback); InstallApplicationEventHandler(switchEventHandler, 2, switchEventTypes, this, &m_switchEventHandlerRef); DisposeEventHandlerUPP(switchEventHandler); constructMouseButtonEventMap(); // watch for requests to sleep m_events->adoptHandler(m_events->forCOSXScreen().confirmSleep(), getEventTarget(), new TMethodEventJob<COSXScreen>(this, &COSXScreen::handleConfirmSleep)); // create thread for monitoring system power state. *m_pmThreadReady = false; LOG((CLOG_DEBUG "starting watchSystemPowerThread")); m_pmWatchThread = new CThread(new TMethodJob<COSXScreen> (this, &COSXScreen::watchSystemPowerThread)); } catch (...) { m_events->removeHandler(m_events->forCOSXScreen().confirmSleep(), getEventTarget()); if (m_switchEventHandlerRef != 0) { RemoveEventHandler(m_switchEventHandlerRef); } #if defined(MAC_OS_X_VERSION_10_5) CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this); #else if (m_displayManagerNotificationUPP != NULL) { DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP, NULL, &m_PSN, 0); } if (m_hiddenWindow) { ReleaseWindow(m_hiddenWindow); m_hiddenWindow = NULL; } if (m_userInputWindow) { ReleaseWindow(m_userInputWindow); m_userInputWindow = NULL; } #endif delete m_keyState; delete m_screensaver; throw; } // install event handlers m_events->adoptHandler(CEvent::kSystem, m_events->getSystemTarget(), new TMethodEventJob<COSXScreen>(this, &COSXScreen::handleSystemEvent)); // install the platform event queue m_events->adoptBuffer(new COSXEventQueueBuffer(m_events)); }
void COSXScreen::updateScreenShape(const CGDirectDisplayID, const CGDisplayChangeSummaryFlags flags) { updateScreenShape(); }
COSXScreen::COSXScreen(bool isPrimary) : m_isPrimary(isPrimary), m_isOnScreen(m_isPrimary), m_cursorPosValid(false), m_cursorHidden(false), m_dragNumButtonsDown(0), m_dragTimer(NULL), m_keyState(NULL), m_sequenceNumber(0), m_screensaver(NULL), m_screensaverNotify(false), m_ownClipboard(false), m_clipboardTimer(NULL), m_hiddenWindow(NULL), m_userInputWindow(NULL), m_switchEventHandlerRef(0), m_pmMutex(new CMutex), m_pmWatchThread(NULL), m_pmThreadReady(new CCondVar<bool>(m_pmMutex, false)), m_activeModifierHotKey(0), m_activeModifierHotKeyMask(0) { try { m_displayID = CGMainDisplayID(); updateScreenShape(m_displayID, 0); m_screensaver = new COSXScreenSaver(getEventTarget()); m_keyState = new COSXKeyState(); if (m_isPrimary) { if (!AXAPIEnabled()) { LOG((CLOG_ERR "Synergy server requires accessibility API enabled. Please check the option for \"Enable access for assistive devices\" in the Universal Access System Preferences panel. Unintentional key-replication will occur until this is fixed.")); } } // install display manager notification handler #if defined(MAC_OS_X_VERSION_10_5) CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, this); #else m_displayManagerNotificationUPP = NewDMExtendedNotificationUPP(displayManagerCallback); OSStatus err = GetCurrentProcess(&m_PSN); err = DMRegisterExtendedNotifyProc(m_displayManagerNotificationUPP, this, 0, &m_PSN); #endif // install fast user switching event handler EventTypeSpec switchEventTypes[2]; switchEventTypes[0].eventClass = kEventClassSystem; switchEventTypes[0].eventKind = kEventSystemUserSessionDeactivated; switchEventTypes[1].eventClass = kEventClassSystem; switchEventTypes[1].eventKind = kEventSystemUserSessionActivated; EventHandlerUPP switchEventHandler = NewEventHandlerUPP(userSwitchCallback); InstallApplicationEventHandler(switchEventHandler, 2, switchEventTypes, this, &m_switchEventHandlerRef); DisposeEventHandlerUPP(switchEventHandler); // watch for requests to sleep EVENTQUEUE->adoptHandler(COSXScreen::getConfirmSleepEvent(), getEventTarget(), new TMethodEventJob<COSXScreen>(this, &COSXScreen::handleConfirmSleep)); // create thread for monitoring system power state. LOG((CLOG_DEBUG "starting watchSystemPowerThread")); m_pmWatchThread = new CThread(new TMethodJob<COSXScreen> (this, &COSXScreen::watchSystemPowerThread)); } catch (...) { EVENTQUEUE->removeHandler(COSXScreen::getConfirmSleepEvent(), getEventTarget()); if (m_switchEventHandlerRef != 0) { RemoveEventHandler(m_switchEventHandlerRef); } #if defined(MAC_OS_X_VERSION_10_5) CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this); #else if (m_displayManagerNotificationUPP != NULL) { DMRemoveExtendedNotifyProc(m_displayManagerNotificationUPP, NULL, &m_PSN, 0); } if (m_hiddenWindow) { ReleaseWindow(m_hiddenWindow); m_hiddenWindow = NULL; } if (m_userInputWindow) { ReleaseWindow(m_userInputWindow); m_userInputWindow = NULL; } #endif delete m_keyState; delete m_screensaver; throw; } // install event handlers EVENTQUEUE->adoptHandler(CEvent::kSystem, IEventQueue::getSystemTarget(), new TMethodEventJob<COSXScreen>(this, &COSXScreen::handleSystemEvent)); // install the platform event queue EVENTQUEUE->adoptBuffer(new COSXEventQueueBuffer); }
COSXScreen::COSXScreen(bool isPrimary) : m_isPrimary(isPrimary), m_isOnScreen(m_isPrimary), m_cursorPosValid(false), m_cursorHidden(false), m_dragNumButtonsDown(0), m_dragTimer(NULL), m_keyState(NULL), m_sequenceNumber(0), m_screensaver(NULL), m_screensaverNotify(false), m_clipboardTimer(NULL), m_hiddenWindow(NULL), m_userInputWindow(NULL), m_switchEventHandlerRef(0), m_pmMutex(new CMutex), m_pmWatchThread(NULL), m_pmThreadReady(new CCondVar<bool>(m_pmMutex, false)), m_activeModifierHotKey(0), m_activeModifierHotKeyMask(0) { try { m_displayID = CGMainDisplayID(); updateScreenShape(m_displayID, 0); m_screensaver = new COSXScreenSaver(getEventTarget()); m_keyState = new COSXKeyState(); if (m_isPrimary) { // 1x1 window (to minimze the back buffer allocated for this // window. Rect bounds = { 100, 100, 101, 101 }; // m_hiddenWindow is a window meant to let us get mouse moves // when the focus is on another computer. If you get your event // from the application event target you'll get every mouse // moves. On the other hand the Window event target will only // get events when the mouse moves over the window. // The ignoreClicks attributes makes it impossible for the // user to click on our invisible window. CreateNewWindow(kUtilityWindowClass, kWindowNoShadowAttribute | kWindowIgnoreClicksAttribute | kWindowNoActivatesAttribute, &bounds, &m_hiddenWindow); // Make it invisible SetWindowAlpha(m_hiddenWindow, 0); ShowWindow(m_hiddenWindow); // m_userInputWindow is a window meant to let us get mouse moves // when the focus is on this computer. Rect inputBounds = { 100, 100, 200, 200 }; CreateNewWindow(kUtilityWindowClass, kWindowNoShadowAttribute | kWindowOpaqueForEventsAttribute | kWindowStandardHandlerAttribute, &inputBounds, &m_userInputWindow); SetWindowAlpha(m_userInputWindow, 0); } // install display manager notification handler CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, this); // install fast user switching event handler EventTypeSpec switchEventTypes[2]; switchEventTypes[0].eventClass = kEventClassSystem; switchEventTypes[0].eventKind = kEventSystemUserSessionDeactivated; switchEventTypes[1].eventClass = kEventClassSystem; switchEventTypes[1].eventKind = kEventSystemUserSessionActivated; EventHandlerUPP switchEventHandler = NewEventHandlerUPP(userSwitchCallback); InstallApplicationEventHandler(switchEventHandler, 2, switchEventTypes, this, &m_switchEventHandlerRef); DisposeEventHandlerUPP(switchEventHandler); // watch for requests to sleep EVENTQUEUE->adoptHandler(COSXScreen::getConfirmSleepEvent(), getEventTarget(), new TMethodEventJob<COSXScreen>(this, &COSXScreen::handleConfirmSleep)); // create thread for monitoring system power state. LOG((CLOG_DEBUG "starting watchSystemPowerThread")); m_pmWatchThread = new CThread(new TMethodJob<COSXScreen> (this, &COSXScreen::watchSystemPowerThread)); } catch (...) { EVENTQUEUE->removeHandler(COSXScreen::getConfirmSleepEvent(), getEventTarget()); if (m_switchEventHandlerRef != 0) { RemoveEventHandler(m_switchEventHandlerRef); } CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this); if (m_hiddenWindow) { CFRelease(m_hiddenWindow); m_hiddenWindow = NULL; } if (m_userInputWindow) { CFRelease(m_userInputWindow); m_userInputWindow = NULL; } delete m_keyState; delete m_screensaver; throw; } // install event handlers EVENTQUEUE->adoptHandler(CEvent::kSystem, IEventQueue::getSystemTarget(), new TMethodEventJob<COSXScreen>(this, &COSXScreen::handleSystemEvent)); // install the platform event queue EVENTQUEUE->adoptBuffer(new COSXEventQueueBuffer); }