00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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
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
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
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
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
00129 m_screen->checkClipboards();
00130
00131
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
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
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
00245 m_halfDuplex = 0;
00246
00247
00248
00249 if (!m_screenSaverSync) {
00250 m_screenSaverSync = true;
00251 if (!m_isPrimary) {
00252 m_screen->openScreensaver(false);
00253 }
00254 }
00255
00256
00257 m_screen->resetOptions();
00258 }
00259
00260 void
00261 CScreen::setOptions(const COptionsList& options)
00262 {
00263
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
00300 m_screen->setHalfDuplexMask(m_halfDuplex);
00301
00302
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
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
00362 if (m_screen->isAnyMouseButtonDown()) {
00363 LOG((CLOG_DEBUG "locked by mouse button"));
00364 return true;
00365 }
00366
00367
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
00428 m_screen->openScreensaver(true);
00429
00430
00431 EVENTQUEUE->addEvent(CEvent(getShapeChangedEvent(), getEventTarget()));
00432 }
00433
00434 void
00435 CScreen::enableSecondary()
00436 {
00437
00438 for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
00439 grabClipboard(id);
00440 }
00441
00442
00443 if (m_screenSaverSync) {
00444 m_screen->openScreensaver(false);
00445 }
00446 }
00447
00448 void
00449 CScreen::disablePrimary()
00450 {
00451
00452 m_screen->closeScreensaver();
00453 }
00454
00455 void
00456 CScreen::disableSecondary()
00457 {
00458
00459 m_screen->closeScreensaver();
00460 }
00461
00462 void
00463 CScreen::enterPrimary()
00464 {
00465
00466 }
00467
00468 void
00469 CScreen::enterSecondary(KeyModifierMask)
00470 {
00471
00472 }
00473
00474 void
00475 CScreen::leavePrimary()
00476 {
00477
00478
00479
00480 m_screen->updateKeyState();
00481 }
00482
00483 void
00484 CScreen::leaveSecondary()
00485 {
00486
00487 m_screen->fakeAllKeysUp();
00488 }