diff options
Diffstat (limited to 'src/lib/barrier/Screen.cpp')
| -rw-r--r-- | src/lib/barrier/Screen.cpp | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/src/lib/barrier/Screen.cpp b/src/lib/barrier/Screen.cpp new file mode 100644 index 0000000..32442f6 --- /dev/null +++ b/src/lib/barrier/Screen.cpp @@ -0,0 +1,559 @@ +/* + * barrier -- mouse and keyboard sharing utility + * Copyright (C) 2012-2016 Symless Ltd. + * Copyright (C) 2003 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/>. + */ + +#include "barrier/Screen.h" +#include "barrier/IPlatformScreen.h" +#include "barrier/protocol_types.h" +#include "base/Log.h" +#include "base/IEventQueue.h" +#include "server/ClientProxy.h" +#include "base/TMethodEventJob.h" + +namespace barrier { + +// +// Screen +// + +Screen::Screen(IPlatformScreen* platformScreen, IEventQueue* events) : + m_screen(platformScreen), + m_isPrimary(platformScreen->isPrimary()), + m_enabled(false), + m_entered(m_isPrimary), + m_screenSaverSync(true), + m_fakeInput(false), + m_events(events), + m_mock(false), + m_enableDragDrop(false) +{ + assert(m_screen != NULL); + + // reset options + resetOptions(); + + LOG((CLOG_DEBUG "opened display")); +} + +Screen::~Screen() +{ + if (m_mock) { + return; + } + + if (m_enabled) { + disable(); + } + assert(!m_enabled); + assert(m_entered == m_isPrimary); + delete m_screen; + LOG((CLOG_DEBUG "closed display")); +} + +void +Screen::enable() +{ + assert(!m_enabled); + + m_screen->updateKeyMap(); + m_screen->updateKeyState(); + m_screen->enable(); + if (m_isPrimary) { + enablePrimary(); + } + else { + enableSecondary(); + } + + // note activation + m_enabled = true; +} + +void +Screen::disable() +{ + assert(m_enabled); + + if (!m_isPrimary && m_entered) { + leave(); + } + else if (m_isPrimary && !m_entered) { + enter(0); + } + m_screen->disable(); + if (m_isPrimary) { + disablePrimary(); + } + else { + disableSecondary(); + } + + // note deactivation + m_enabled = false; +} + +void +Screen::enter(KeyModifierMask toggleMask) +{ + assert(m_entered == false); + LOG((CLOG_INFO "entering screen")); + + // now on screen + m_entered = true; + + m_screen->enter(); + if (m_isPrimary) { + enterPrimary(); + } + else { + enterSecondary(toggleMask); + } +} + +bool +Screen::leave() +{ + assert(m_entered == true); + LOG((CLOG_INFO "leaving screen")); + + if (!m_screen->leave()) { + return false; + } + if (m_isPrimary) { + leavePrimary(); + } + else { + leaveSecondary(); + } + + // make sure our idea of clipboard ownership is correct + m_screen->checkClipboards(); + + // now not on screen + m_entered = false; + + return true; +} + +void +Screen::reconfigure(UInt32 activeSides) +{ + assert(m_isPrimary); + m_screen->reconfigure(activeSides); +} + +void +Screen::warpCursor(SInt32 x, SInt32 y) +{ + assert(m_isPrimary); + m_screen->warpCursor(x, y); +} + +void +Screen::setClipboard(ClipboardID id, const IClipboard* clipboard) +{ + m_screen->setClipboard(id, clipboard); +} + +void +Screen::grabClipboard(ClipboardID id) +{ + m_screen->setClipboard(id, NULL); +} + +void +Screen::screensaver(bool activate) +{ + if (!m_isPrimary) { + // activate/deactivation screen saver iff synchronization enabled + if (m_screenSaverSync) { + m_screen->screensaver(activate); + } + } +} + +void +Screen::keyDown(KeyID id, KeyModifierMask mask, KeyButton button) +{ + // check for ctrl+alt+del emulation + if (id == kKeyDelete && + (mask & (KeyModifierControl | KeyModifierAlt)) == + (KeyModifierControl | KeyModifierAlt)) { + LOG((CLOG_DEBUG "emulating ctrl+alt+del press")); + if (m_screen->fakeCtrlAltDel()) { + return; + } + } + m_screen->fakeKeyDown(id, mask, button); +} + +void +Screen::keyRepeat(KeyID id, + KeyModifierMask mask, SInt32 count, KeyButton button) +{ + assert(!m_isPrimary); + m_screen->fakeKeyRepeat(id, mask, count, button); +} + +void +Screen::keyUp(KeyID, KeyModifierMask, KeyButton button) +{ + m_screen->fakeKeyUp(button); +} + +void +Screen::mouseDown(ButtonID button) +{ + m_screen->fakeMouseButton(button, true); +} + +void +Screen::mouseUp(ButtonID button) +{ + m_screen->fakeMouseButton(button, false); +} + +void +Screen::mouseMove(SInt32 x, SInt32 y) +{ + assert(!m_isPrimary); + m_screen->fakeMouseMove(x, y); +} + +void +Screen::mouseRelativeMove(SInt32 dx, SInt32 dy) +{ + assert(!m_isPrimary); + m_screen->fakeMouseRelativeMove(dx, dy); +} + +void +Screen::mouseWheel(SInt32 xDelta, SInt32 yDelta) +{ + assert(!m_isPrimary); + m_screen->fakeMouseWheel(xDelta, yDelta); +} + +void +Screen::resetOptions() +{ + // reset options + m_halfDuplex = 0; + + // if screen saver synchronization was off then turn it on since + // that's the default option state. + if (!m_screenSaverSync) { + m_screenSaverSync = true; + if (!m_isPrimary) { + m_screen->openScreensaver(false); + } + } + + // let screen handle its own options + m_screen->resetOptions(); +} + +void +Screen::setOptions(const OptionsList& options) +{ + // update options + bool oldScreenSaverSync = m_screenSaverSync; + for (UInt32 i = 0, n = (UInt32)options.size(); i < n; i += 2) { + if (options[i] == kOptionScreenSaverSync) { + m_screenSaverSync = (options[i + 1] != 0); + LOG((CLOG_DEBUG1 "screen saver synchronization %s", m_screenSaverSync ? "on" : "off")); + } + else if (options[i] == kOptionHalfDuplexCapsLock) { + if (options[i + 1] != 0) { + m_halfDuplex |= KeyModifierCapsLock; + } + else { + m_halfDuplex &= ~KeyModifierCapsLock; + } + LOG((CLOG_DEBUG1 "half-duplex caps-lock %s", ((m_halfDuplex & KeyModifierCapsLock) != 0) ? "on" : "off")); + } + else if (options[i] == kOptionHalfDuplexNumLock) { + if (options[i + 1] != 0) { + m_halfDuplex |= KeyModifierNumLock; + } + else { + m_halfDuplex &= ~KeyModifierNumLock; + } + LOG((CLOG_DEBUG1 "half-duplex num-lock %s", ((m_halfDuplex & KeyModifierNumLock) != 0) ? "on" : "off")); + } + else if (options[i] == kOptionHalfDuplexScrollLock) { + if (options[i + 1] != 0) { + m_halfDuplex |= KeyModifierScrollLock; + } + else { + m_halfDuplex &= ~KeyModifierScrollLock; + } + LOG((CLOG_DEBUG1 "half-duplex scroll-lock %s", ((m_halfDuplex & KeyModifierScrollLock) != 0) ? "on" : "off")); + } + } + + // update half-duplex options + m_screen->setHalfDuplexMask(m_halfDuplex); + + // update screen saver synchronization + if (!m_isPrimary && oldScreenSaverSync != m_screenSaverSync) { + if (m_screenSaverSync) { + m_screen->openScreensaver(false); + } + else { + m_screen->closeScreensaver(); + } + } + + // let screen handle its own options + m_screen->setOptions(options); +} + +void +Screen::setSequenceNumber(UInt32 seqNum) +{ + m_screen->setSequenceNumber(seqNum); +} + +UInt32 +Screen::registerHotKey(KeyID key, KeyModifierMask mask) +{ + return m_screen->registerHotKey(key, mask); +} + +void +Screen::unregisterHotKey(UInt32 id) +{ + m_screen->unregisterHotKey(id); +} + +void +Screen::fakeInputBegin() +{ + assert(!m_fakeInput); + + m_fakeInput = true; + m_screen->fakeInputBegin(); +} + +void +Screen::fakeInputEnd() +{ + assert(m_fakeInput); + + m_fakeInput = false; + m_screen->fakeInputEnd(); +} + +bool +Screen::isOnScreen() const +{ + return m_entered; +} + +bool +Screen::isLockedToScreen() const +{ + // check for pressed mouse buttons + // HACK: commented out as it breaks new drag drop feature + UInt32 buttonID = 0; + + if (m_screen->isAnyMouseButtonDown(buttonID)) { + if (buttonID != kButtonLeft) { + LOG((CLOG_DEBUG "locked by mouse buttonID: %d", buttonID)); + } + + if (m_enableDragDrop) { + return (buttonID == kButtonLeft) ? false : true; + } + else { + return true; + } + } + + // not locked + return false; +} + +SInt32 +Screen::getJumpZoneSize() const +{ + if (!m_isPrimary) { + return 0; + } + else { + return m_screen->getJumpZoneSize(); + } +} + +void +Screen::getCursorCenter(SInt32& x, SInt32& y) const +{ + m_screen->getCursorCenter(x, y); +} + +KeyModifierMask +Screen::getActiveModifiers() const +{ + return m_screen->getActiveModifiers(); +} + +KeyModifierMask +Screen::pollActiveModifiers() const +{ + return m_screen->pollActiveModifiers(); +} + +bool +Screen::isDraggingStarted() const +{ + return m_screen->isDraggingStarted(); +} + +bool +Screen::isFakeDraggingStarted() const +{ + return m_screen->isFakeDraggingStarted(); +} + +void +Screen::setDraggingStarted(bool started) +{ + m_screen->setDraggingStarted(started); +} + +void +Screen::startDraggingFiles(DragFileList& fileList) +{ + m_screen->fakeDraggingFiles(fileList); +} + +void +Screen::setEnableDragDrop(bool enabled) +{ + m_enableDragDrop = enabled; +} + +String& +Screen::getDraggingFilename() const +{ + return m_screen->getDraggingFilename(); +} + +void +Screen::clearDraggingFilename() +{ + m_screen->clearDraggingFilename(); +} + +const String& +Screen::getDropTarget() const +{ + return m_screen->getDropTarget(); +} + +void* +Screen::getEventTarget() const +{ + return m_screen; +} + +bool +Screen::getClipboard(ClipboardID id, IClipboard* clipboard) const +{ + return m_screen->getClipboard(id, clipboard); +} + +void +Screen::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const +{ + m_screen->getShape(x, y, w, h); +} + +void +Screen::getCursorPos(SInt32& x, SInt32& y) const +{ + m_screen->getCursorPos(x, y); +} + +void +Screen::enablePrimary() +{ + // get notified of screen saver activation/deactivation + m_screen->openScreensaver(true); + + // claim screen changed size + m_events->addEvent(Event(m_events->forIScreen().shapeChanged(), getEventTarget())); +} + +void +Screen::enableSecondary() +{ + // assume primary has all clipboards + for (ClipboardID id = 0; id < kClipboardEnd; ++id) { + grabClipboard(id); + } + + // disable the screen saver if synchronization is enabled + if (m_screenSaverSync) { + m_screen->openScreensaver(false); + } +} + +void +Screen::disablePrimary() +{ + // done with screen saver + m_screen->closeScreensaver(); +} + +void +Screen::disableSecondary() +{ + // done with screen saver + m_screen->closeScreensaver(); +} + +void +Screen::enterPrimary() +{ + // do nothing +} + +void +Screen::enterSecondary(KeyModifierMask) +{ + // do nothing +} + +void +Screen::leavePrimary() +{ + // we don't track keys while on the primary screen so update our + // idea of them now. this is particularly to update the state of + // the toggle modifiers. + m_screen->updateKeyState(); +} + +void +Screen::leaveSecondary() +{ + // release any keys we think are still down + m_screen->fakeAllKeysUp(); +} + +} |
