00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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
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
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
00135 m_screen->checkClipboards();
00136
00137
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
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
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
00279 m_halfDuplex = 0;
00280
00281
00282
00283 if (!m_screenSaverSync) {
00284 m_screenSaverSync = true;
00285 if (!m_isPrimary) {
00286 m_screen->openScreensaver(false);
00287 }
00288 }
00289
00290
00291 m_screen->resetOptions();
00292 }
00293
00294 void
00295 CScreen::setOptions(const COptionsList& options)
00296 {
00297
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
00334 m_screen->setHalfDuplexMask(m_halfDuplex);
00335
00336
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
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
00396 if (m_screen->isAnyMouseButtonDown()) {
00397 LOG((CLOG_DEBUG "locked by mouse button"));
00398 return true;
00399 }
00400
00401
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
00462 m_screen->openScreensaver(true);
00463
00464
00465 EVENTQUEUE->addEvent(CEvent(getShapeChangedEvent(), getEventTarget()));
00466 }
00467
00468 void
00469 CScreen::enableSecondary()
00470 {
00471
00472 for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
00473 grabClipboard(id);
00474 }
00475
00476
00477 if (m_screenSaverSync) {
00478 m_screen->openScreensaver(false);
00479 }
00480 }
00481
00482 void
00483 CScreen::disablePrimary()
00484 {
00485
00486 m_screen->closeScreensaver();
00487 }
00488
00489 void
00490 CScreen::disableSecondary()
00491 {
00492
00493 m_screen->closeScreensaver();
00494 }
00495
00496 void
00497 CScreen::enterPrimary()
00498 {
00499
00500 }
00501
00502 void
00503 CScreen::enterSecondary(KeyModifierMask)
00504 {
00505
00506 }
00507
00508 void
00509 CScreen::leavePrimary()
00510 {
00511
00512
00513
00514 m_screen->updateKeyState();
00515 }
00516
00517 void
00518 CScreen::leaveSecondary()
00519 {
00520
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 }