• Main Page
  • Classes
  • Files
  • File List

CScreen.cpp

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2012 Bolton Software Ltd.
00004  * Copyright (C) 2003 Chris Schoeneman
00005  * 
00006  * This package is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * found in the file COPYING that should have accompanied this file.
00009  * 
00010  * This package is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #include "CScreen.h"
00020 #include "IPlatformScreen.h"
00021 #include "ProtocolTypes.h"
00022 #include "CLog.h"
00023 #include "IEventQueue.h"
00024 #include "CClientProxy.h"
00025 #include "TMethodEventJob.h"
00026 
00027 //
00028 // CScreen
00029 //
00030 
00031 CScreen::CScreen(IPlatformScreen* platformScreen) :
00032     m_screen(platformScreen),
00033     m_isPrimary(platformScreen->isPrimary()),
00034     m_enabled(false),
00035     m_entered(m_isPrimary),
00036     m_screenSaverSync(true),
00037     m_fakeInput(false)
00038 {
00039     assert(m_screen != NULL);
00040 
00041     // reset options
00042     resetOptions();
00043 
00044     LOG((CLOG_DEBUG "opened display"));
00045 }
00046 
00047 CScreen::~CScreen()
00048 {
00049     if (m_enabled) {
00050         disable();
00051     }
00052     assert(!m_enabled);
00053     assert(m_entered == m_isPrimary);
00054     delete m_screen;
00055     LOG((CLOG_DEBUG "closed display"));
00056 }
00057 
00058 void
00059 CScreen::enable()
00060 {
00061     assert(!m_enabled);
00062 
00063     m_screen->updateKeyMap();
00064     m_screen->updateKeyState();
00065     m_screen->enable();
00066     if (m_isPrimary) {
00067         enablePrimary();
00068     }
00069     else {
00070         enableSecondary();
00071     }
00072 
00073     // note activation
00074     m_enabled = true;
00075 }
00076 
00077 void
00078 CScreen::disable()
00079 {
00080     assert(m_enabled);
00081 
00082     if (!m_isPrimary && m_entered) {
00083         leave();
00084     }
00085     else if (m_isPrimary && !m_entered) {
00086         enter(0);
00087     }
00088     m_screen->disable();
00089     if (m_isPrimary) {
00090         disablePrimary();
00091     }
00092     else {
00093         disableSecondary();
00094     }
00095 
00096     // note deactivation
00097     m_enabled = false;
00098 }
00099 
00100 void
00101 CScreen::enter(KeyModifierMask toggleMask)
00102 {
00103     assert(m_entered == false);
00104     LOG((CLOG_INFO "entering screen"));
00105 
00106     // now on screen
00107     m_entered = true;
00108 
00109     m_screen->enter();
00110     if (m_isPrimary) {
00111         enterPrimary();
00112     }
00113     else {
00114         enterSecondary(toggleMask);
00115     }
00116 }
00117 
00118 bool
00119 CScreen::leave()
00120 {
00121     assert(m_entered == true);
00122     LOG((CLOG_INFO "leaving screen"));
00123 
00124     if (!m_screen->leave()) {
00125         return false;
00126     }
00127     if (m_isPrimary) {
00128         leavePrimary();
00129     }
00130     else {
00131         leaveSecondary();
00132     }
00133 
00134     // make sure our idea of clipboard ownership is correct
00135     m_screen->checkClipboards();
00136 
00137     // now not on screen
00138     m_entered = false;
00139 
00140     return true;
00141 }
00142 
00143 void
00144 CScreen::reconfigure(UInt32 activeSides)
00145 {
00146     assert(m_isPrimary);
00147     m_screen->reconfigure(activeSides);
00148 }
00149 
00150 void
00151 CScreen::warpCursor(SInt32 x, SInt32 y)
00152 {
00153     assert(m_isPrimary);
00154     m_screen->warpCursor(x, y);
00155 }
00156 
00157 void
00158 CScreen::setClipboard(ClipboardID id, const IClipboard* clipboard)
00159 {
00160     m_screen->setClipboard(id, clipboard);
00161 }
00162 
00163 void
00164 CScreen::grabClipboard(ClipboardID id)
00165 {
00166     m_screen->setClipboard(id, NULL);
00167 }
00168 
00169 void
00170 CScreen::screensaver(bool activate)
00171 {
00172     if (!m_isPrimary) {
00173         // activate/deactivation screen saver iff synchronization enabled
00174         if (m_screenSaverSync) {
00175             m_screen->screensaver(activate);
00176         }
00177     }
00178 }
00179 
00180 void
00181 CScreen::keyDown(KeyID id, KeyModifierMask mask, KeyButton button)
00182 {
00183     assert(!m_isPrimary || m_fakeInput);
00184 
00185     // check for ctrl+alt+del emulation
00186     if (id == kKeyDelete &&
00187         (mask & (KeyModifierControl | KeyModifierAlt)) ==
00188                 (KeyModifierControl | KeyModifierAlt)) {
00189         LOG((CLOG_DEBUG "emulating ctrl+alt+del press"));
00190         if (m_screen->fakeCtrlAltDel()) {
00191             return;
00192         }
00193     }
00194     m_screen->fakeKeyDown(id, mask, button);
00195 }
00196 
00197 void
00198 CScreen::keyRepeat(KeyID id,
00199                 KeyModifierMask mask, SInt32 count, KeyButton button)
00200 {
00201     assert(!m_isPrimary);
00202     m_screen->fakeKeyRepeat(id, mask, count, button);
00203 }
00204 
00205 void
00206 CScreen::keyUp(KeyID, KeyModifierMask, KeyButton button)
00207 {
00208     assert(!m_isPrimary || m_fakeInput);
00209     m_screen->fakeKeyUp(button);
00210 }
00211 
00212 void
00213 CScreen::mouseDown(ButtonID button)
00214 {
00215     assert(!m_isPrimary);
00216     m_screen->fakeMouseButton(button, true);
00217 }
00218 
00219 void
00220 CScreen::mouseUp(ButtonID button)
00221 {
00222     assert(!m_isPrimary);
00223     m_screen->fakeMouseButton(button, false);
00224 }
00225 
00226 void
00227 CScreen::mouseMove(SInt32 x, SInt32 y)
00228 {
00229     assert(!m_isPrimary);
00230     m_screen->fakeMouseMove(x, y);
00231 }
00232 
00233 void
00234 CScreen::mouseRelativeMove(SInt32 dx, SInt32 dy)
00235 {
00236     assert(!m_isPrimary);
00237     m_screen->fakeMouseRelativeMove(dx, dy);
00238 }
00239 
00240 void
00241 CScreen::mouseWheel(SInt32 xDelta, SInt32 yDelta)
00242 {
00243     assert(!m_isPrimary);
00244     m_screen->fakeMouseWheel(xDelta, yDelta);
00245 }
00246 
00247 void
00248 CScreen::gameDeviceButtons(GameDeviceID id, GameDeviceButton buttons)
00249 {
00250     assert(!m_isPrimary);
00251     m_screen->fakeGameDeviceButtons(id, buttons);
00252 }
00253 
00254 void
00255 CScreen::gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2)
00256 {
00257     assert(!m_isPrimary);
00258     m_screen->fakeGameDeviceSticks(id, x1, y1, x2, y2);
00259 }
00260 
00261 void
00262 CScreen::gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2)
00263 {
00264     assert(!m_isPrimary);
00265     m_screen->fakeGameDeviceTriggers(id, t1, t2);
00266 }
00267 
00268 void
00269 CScreen::gameDeviceTimingReq()
00270 {
00271     assert(!m_isPrimary);
00272     m_screen->queueGameDeviceTimingReq();
00273 }
00274 
00275 void
00276 CScreen::resetOptions()
00277 {
00278     // reset options
00279     m_halfDuplex = 0;
00280 
00281     // if screen saver synchronization was off then turn it on since
00282     // that's the default option state.
00283     if (!m_screenSaverSync) {
00284         m_screenSaverSync = true;
00285         if (!m_isPrimary) {
00286             m_screen->openScreensaver(false);
00287         }
00288     }
00289 
00290     // let screen handle its own options
00291     m_screen->resetOptions();
00292 }
00293 
00294 void
00295 CScreen::setOptions(const COptionsList& options)
00296 {
00297     // update options
00298     bool oldScreenSaverSync = m_screenSaverSync;
00299     for (UInt32 i = 0, n = (UInt32)options.size(); i < n; i += 2) {
00300         if (options[i] == kOptionScreenSaverSync) {
00301             m_screenSaverSync = (options[i + 1] != 0);
00302             LOG((CLOG_DEBUG1 "screen saver synchronization %s", m_screenSaverSync ? "on" : "off"));
00303         }
00304         else if (options[i] == kOptionHalfDuplexCapsLock) {
00305             if (options[i + 1] != 0) {
00306                 m_halfDuplex |=  KeyModifierCapsLock;
00307             }
00308             else {
00309                 m_halfDuplex &= ~KeyModifierCapsLock;
00310             }
00311             LOG((CLOG_DEBUG1 "half-duplex caps-lock %s", ((m_halfDuplex & KeyModifierCapsLock) != 0) ? "on" : "off"));
00312         }
00313         else if (options[i] == kOptionHalfDuplexNumLock) {
00314             if (options[i + 1] != 0) {
00315                 m_halfDuplex |=  KeyModifierNumLock;
00316             }
00317             else {
00318                 m_halfDuplex &= ~KeyModifierNumLock;
00319             }
00320             LOG((CLOG_DEBUG1 "half-duplex num-lock %s", ((m_halfDuplex & KeyModifierNumLock) != 0) ? "on" : "off"));
00321         }
00322         else if (options[i] == kOptionHalfDuplexScrollLock) {
00323             if (options[i + 1] != 0) {
00324                 m_halfDuplex |=  KeyModifierScrollLock;
00325             }
00326             else {
00327                 m_halfDuplex &= ~KeyModifierScrollLock;
00328             }
00329             LOG((CLOG_DEBUG1 "half-duplex scroll-lock %s", ((m_halfDuplex & KeyModifierScrollLock) != 0) ? "on" : "off"));
00330         }
00331     }
00332 
00333     // update half-duplex options
00334     m_screen->setHalfDuplexMask(m_halfDuplex);
00335 
00336     // update screen saver synchronization
00337     if (!m_isPrimary && oldScreenSaverSync != m_screenSaverSync) {
00338         if (m_screenSaverSync) {
00339             m_screen->openScreensaver(false);
00340         }
00341         else {
00342             m_screen->closeScreensaver();
00343         }
00344     }
00345 
00346     // let screen handle its own options
00347     m_screen->setOptions(options);
00348 }
00349 
00350 void
00351 CScreen::setSequenceNumber(UInt32 seqNum)
00352 {
00353     m_screen->setSequenceNumber(seqNum);
00354 }
00355 
00356 UInt32
00357 CScreen::registerHotKey(KeyID key, KeyModifierMask mask)
00358 {
00359     return m_screen->registerHotKey(key, mask);
00360 }
00361 
00362 void
00363 CScreen::unregisterHotKey(UInt32 id)
00364 {
00365     m_screen->unregisterHotKey(id);
00366 }
00367 
00368 void
00369 CScreen::fakeInputBegin()
00370 {
00371     assert(!m_fakeInput);
00372 
00373     m_fakeInput = true;
00374     m_screen->fakeInputBegin();
00375 }
00376 
00377 void
00378 CScreen::fakeInputEnd()
00379 {
00380     assert(m_fakeInput);
00381 
00382     m_fakeInput = false;
00383     m_screen->fakeInputEnd();
00384 }
00385 
00386 bool
00387 CScreen::isOnScreen() const
00388 {
00389     return m_entered;
00390 }
00391 
00392 bool
00393 CScreen::isLockedToScreen() const
00394 {
00395     // check for pressed mouse buttons
00396     if (m_screen->isAnyMouseButtonDown()) {
00397         LOG((CLOG_DEBUG "locked by mouse button"));
00398         return true;
00399     }
00400 
00401     // not locked
00402     return false;
00403 }
00404 
00405 SInt32
00406 CScreen::getJumpZoneSize() const
00407 {
00408     if (!m_isPrimary) {
00409         return 0;
00410     }
00411     else {
00412         return m_screen->getJumpZoneSize();
00413     }
00414 }
00415 
00416 void
00417 CScreen::getCursorCenter(SInt32& x, SInt32& y) const
00418 {
00419     m_screen->getCursorCenter(x, y);
00420 }
00421 
00422 KeyModifierMask
00423 CScreen::getActiveModifiers() const
00424 {
00425     return m_screen->getActiveModifiers();
00426 }
00427 
00428 KeyModifierMask
00429 CScreen::pollActiveModifiers() const
00430 {
00431     return m_screen->pollActiveModifiers();
00432 }
00433 
00434 void*
00435 CScreen::getEventTarget() const
00436 {
00437     return m_screen;
00438 }
00439 
00440 bool
00441 CScreen::getClipboard(ClipboardID id, IClipboard* clipboard) const
00442 {
00443     return m_screen->getClipboard(id, clipboard);
00444 }
00445 
00446 void
00447 CScreen::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
00448 {
00449     m_screen->getShape(x, y, w, h);
00450 }
00451 
00452 void
00453 CScreen::getCursorPos(SInt32& x, SInt32& y) const
00454 {
00455     m_screen->getCursorPos(x, y);
00456 }
00457 
00458 void
00459 CScreen::enablePrimary()
00460 {
00461     // get notified of screen saver activation/deactivation
00462     m_screen->openScreensaver(true);
00463 
00464     // claim screen changed size
00465     EVENTQUEUE->addEvent(CEvent(getShapeChangedEvent(), getEventTarget()));
00466 }
00467 
00468 void
00469 CScreen::enableSecondary()
00470 {
00471     // assume primary has all clipboards
00472     for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
00473         grabClipboard(id);
00474     }
00475 
00476     // disable the screen saver if synchronization is enabled
00477     if (m_screenSaverSync) {
00478         m_screen->openScreensaver(false);
00479     }
00480 }
00481 
00482 void
00483 CScreen::disablePrimary()
00484 {
00485     // done with screen saver
00486     m_screen->closeScreensaver();
00487 }
00488 
00489 void
00490 CScreen::disableSecondary()
00491 {
00492     // done with screen saver
00493     m_screen->closeScreensaver();
00494 }
00495 
00496 void
00497 CScreen::enterPrimary()
00498 {
00499     // do nothing
00500 }
00501 
00502 void
00503 CScreen::enterSecondary(KeyModifierMask)
00504 {
00505     // do nothing
00506 }
00507 
00508 void
00509 CScreen::leavePrimary()
00510 {
00511     // we don't track keys while on the primary screen so update our
00512     // idea of them now.  this is particularly to update the state of
00513     // the toggle modifiers.
00514     m_screen->updateKeyState();
00515 }
00516 
00517 void
00518 CScreen::leaveSecondary()
00519 {
00520     // release any keys we think are still down
00521     m_screen->fakeAllKeysUp();
00522 }
00523 
00524 void
00525 CScreen::gameDeviceTimingResp(UInt16 freq)
00526 {
00527     m_screen->gameDeviceTimingResp(freq);
00528 }
00529 
00530 void
00531 CScreen::gameDeviceFeedback(GameDeviceID id, UInt16 m1, UInt16 m2)
00532 {
00533     m_screen->gameDeviceFeedback(id, m1, m2);
00534 }

Generated on Sat May 25 2013 00:00:04 for Synergy by  doxygen 1.7.1