Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

CScreen.cpp

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

Generated on Fri Nov 6 00:21:14 2009 for synergy-plus by  doxygen 1.3.9.1