Changeset 2752 for trunk/synergy/lib/platform/CPMScreen.cpp
- Timestamp:
- Jul 29, 2006, 6:43:07 AM (19 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/synergy/lib/platform/CPMScreen.cpp
r2751 r2752 2 2 * synergy -- mouse and keyboard sharing utility 3 3 * Copyright (C) 2002 Chris Schoeneman 4 * Copyright (C) 2006 Knut St. Osmundsen 4 5 * 5 6 * This package is free software; you can redistribute it and/or … … 13 14 */ 14 15 15 #include "CMSWindowsScreen.h" 16 #include "CMSWindowsClipboard.h" 17 #include "CMSWindowsDesks.h" 18 #include "CMSWindowsEventQueueBuffer.h" 19 #include "CMSWindowsKeyState.h" 20 #include "CMSWindowsScreenSaver.h" 16 #include "CPMScreen.h" 17 #include "CPMClipboard.h" 18 #include "CPMEventQueueBuffer.h" 19 #include "CPMKeyState.h" 20 #include "CPMScreenSaver.h" 21 21 #include "CClipboard.h" 22 22 #include "CKeyMap.h" … … 32 32 #include "TMethodJob.h" 33 33 #include "CArch.h" 34 #include "C ArchMiscWindows.h"34 #include "CPMUtil.h" 35 35 #include <string.h> 36 #include <pbt.h>37 36 38 37 // 39 // add backwards compatible multihead support (and suppress bogus warning). 40 // this isn't supported on MinGW yet AFAICT. 38 // CPMScreen 41 39 // 42 #if defined(_MSC_VER) 43 #pragma warning(push) 44 #pragma warning(disable: 4706) // assignment within conditional 45 #define COMPILE_MULTIMON_STUBS 46 #include <multimon.h> 47 #pragma warning(pop) 48 #endif 49 50 // X button stuff 51 #if !defined(WM_XBUTTONDOWN) 52 #define WM_XBUTTONDOWN 0x020B 53 #define WM_XBUTTONUP 0x020C 54 #define WM_XBUTTONDBLCLK 0x020D 55 #define WM_NCXBUTTONDOWN 0x00AB 56 #define WM_NCXBUTTONUP 0x00AC 57 #define WM_NCXBUTTONDBLCLK 0x00AD 58 #define MOUSEEVENTF_XDOWN 0x0080 59 #define MOUSEEVENTF_XUP 0x0100 60 #define XBUTTON1 0x0001 61 #define XBUTTON2 0x0002 62 #endif 63 #if !defined(VK_XBUTTON1) 64 #define VK_XBUTTON1 0x05 65 #define VK_XBUTTON2 0x06 66 #endif 67 68 // WM_POWERBROADCAST stuff 69 #if !defined(PBT_APMRESUMEAUTOMATIC) 70 #define PBT_APMRESUMEAUTOMATIC 0x0012 71 #endif 72 73 // 74 // CMSWindowsScreen 75 // 76 77 HINSTANCE CMSWindowsScreen::s_instance = NULL; 78 CMSWindowsScreen* CMSWindowsScreen::s_screen = NULL; 79 80 CMSWindowsScreen::CMSWindowsScreen(bool isPrimary) : 40 41 CPMScreen* CPMScreen::s_screen = NULL; 42 43 CPMScreen::CPMScreen(bool isPrimary) : 81 44 m_isPrimary(isPrimary), 82 m_is95Family(CArchMiscWindows::isWindows95Family()),83 45 m_isOnScreen(m_isPrimary), 84 46 m_class(0), 85 47 m_x(0), m_y(0), 86 m_ w(0), m_h(0),48 m_cx(0), m_cy(0), 87 49 m_xCenter(0), m_yCenter(0), 88 50 m_multimon(false), … … 92 54 m_markReceived(0), 93 55 m_fixTimer(NULL), 94 m_keyLayout(NULL),95 56 m_screensaver(NULL), 96 57 m_screensaverNotify(false), 97 58 m_screensaverActive(false), 98 m_window(NULL ),99 m_nextClipboardWindow(NULL ),59 m_window(NULLHANDLE), 60 m_nextClipboardWindow(NULLHANDLE), 100 61 m_ownClipboard(false), 101 m_desks(NULL), 102 m_hookLibrary(NULL), 62 m_hmodHook(NULLHANDLE), 103 63 m_init(NULL), 104 64 m_cleanup(NULL), … … 107 67 m_setMode(NULL), 108 68 m_keyState(NULL), 109 m_hasMouse( GetSystemMetrics(SM_MOUSEPRESENT) != 0),69 m_hasMouse(WinQuerySysValue(HWND_DESKTOP, SV_MOUSEPRESENT) != FALSE), 110 70 m_showingMouse(false) 111 71 { 112 assert(s_instance != NULL); 113 assert(s_screen == NULL); 72 assert(s_screen == NULL); 114 73 115 74 s_screen = this; 116 75 try { 117 76 if (m_isPrimary) { 118 m_hookLibrary = openHookLibrary("synrgyhk"); 119 } 120 m_screensaver = new CMSWindowsScreenSaver(); 121 m_desks = new CMSWindowsDesks(m_isPrimary, 122 m_hookLibrary, m_screensaver, 123 new TMethodJob<CMSWindowsScreen>(this, 124 &CMSWindowsScreen::updateKeysCB)); 125 m_keyState = new CMSWindowsKeyState(m_desks, getEventTarget()); 77 m_hmodHook = openHookLibrary("synrgyhk"); 78 } 79 m_screensaver = new CPMScreenSaver(); 80 m_keyState = new CPMKeyState(getEventTarget()); 126 81 updateScreenShape(); 127 82 m_class = createWindowClass(); 128 83 m_window = createWindow(m_class, "Synergy"); 129 84 forceShowCursor(); 130 LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d %s", m_x, m_y, m_ w, m_h, m_multimon ? "(multi-monitor)" : ""));85 LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d %s", m_x, m_y, m_cx, m_cy, m_multimon ? "(multi-monitor)" : "")); 131 86 LOG((CLOG_DEBUG "window is 0x%08x", m_window)); 132 87 } 133 88 catch (...) { 134 89 delete m_keyState; 135 delete m_desks;136 90 delete m_screensaver; 137 91 destroyWindow(m_window); 138 92 destroyClass(m_class); 139 closeHookLibrary(m_h ookLibrary);93 closeHookLibrary(m_hmodHook); 140 94 s_screen = NULL; 141 95 throw; … … 144 98 // install event handlers 145 99 EVENTQUEUE->adoptHandler(CEvent::kSystem, IEventQueue::getSystemTarget(), 146 new TMethodEventJob<C MSWindowsScreen>(this,147 &C MSWindowsScreen::handleSystemEvent));100 new TMethodEventJob<CPMScreen>(this, 101 &CPMScreen::handleSystemEvent)); 148 102 149 103 // install the platform event queue 150 EVENTQUEUE->adoptBuffer(new C MSWindowsEventQueueBuffer);151 } 152 153 C MSWindowsScreen::~CMSWindowsScreen()104 EVENTQUEUE->adoptBuffer(new CPMEventQueueBuffer); 105 } 106 107 CPMScreen::~CPMScreen() 154 108 { 155 109 assert(s_screen != NULL); … … 159 113 EVENTQUEUE->removeHandler(CEvent::kSystem, IEventQueue::getSystemTarget()); 160 114 delete m_keyState; 161 delete m_desks;162 115 delete m_screensaver; 163 116 destroyWindow(m_window); 164 117 destroyClass(m_class); 165 closeHookLibrary(m_h ookLibrary);118 closeHookLibrary(m_hmodHook); 166 119 s_screen = NULL; 167 120 } 168 121 169 122 void 170 CMSWindowsScreen::init(HINSTANCE instance) 171 { 172 assert(s_instance == NULL); 173 assert(instance != NULL); 174 175 s_instance = instance; 176 } 177 178 HINSTANCE 179 CMSWindowsScreen::getInstance() 180 { 181 return s_instance; 182 } 183 184 void 185 CMSWindowsScreen::enable() 123 CPMScreen::enable() 186 124 { 187 125 assert(m_isOnScreen == m_isPrimary); … … 190 128 m_fixTimer = EVENTQUEUE->newTimer(1.0, NULL); 191 129 EVENTQUEUE->adoptHandler(CEvent::kTimer, m_fixTimer, 192 new TMethodEventJob<CMSWindowsScreen>(this, 193 &CMSWindowsScreen::handleFixes)); 130 new TMethodEventJob<CPMScreen>(this, &CPMScreen::handleFixes)); 194 131 195 132 // install our clipboard snooper 196 m_nextClipboardWindow = SetClipboardViewer(m_window); 197 133 HAB hab = CPMUtil::getHAB(); 134 m_nextClipboardWindow = WinQueryClipbrdViewer(hab); 135 WinSetClipbrdViewer(hab, m_window); 136 137 /// @todo start here! 198 138 // track the active desk and (re)install the hooks 199 139 m_desks->enable(); … … 201 141 if (m_isPrimary) { 202 142 // set jump zones 203 m_setZone(m_x, m_y, m_ w, m_h, getJumpZoneSize());143 m_setZone(m_x, m_y, m_cx, m_cy, getJumpZoneSize()); 204 144 205 145 // watch jump zones 206 146 m_setMode(kHOOK_WATCH_JUMP_ZONE); 207 147 } 208 else { 209 // prevent the system from entering power saving modes. if 210 // it did we'd be forced to disconnect from the server and 211 // the server would not be able to wake us up. 212 CArchMiscWindows::addBusyState(CArchMiscWindows::kSYSTEM); 213 } 214 } 215 216 void 217 CMSWindowsScreen::disable() 148 } 149 150 void 151 CPMScreen::disable() 218 152 { 219 153 // stop tracking the active desk … … 223 157 // disable hooks 224 158 m_setMode(kHOOK_DISABLE); 225 226 // enable special key sequences on win95 family227 enableSpecialKeys(true);228 }229 else {230 // allow the system to enter power saving mode231 CArchMiscWindows::removeBusyState(CArchMiscWindows::kSYSTEM |232 CArchMiscWindows::kDISPLAY);233 159 } 234 160 … … 237 163 238 164 // stop snooping the clipboard 239 ChangeClipboardChain(m_window, m_nextClipboardWindow);165 WinSetClipbrdViewer(m_window, m_nextClipboardWindow); 240 166 m_nextClipboardWindow = NULL; 241 167 … … 252 178 253 179 void 254 C MSWindowsScreen::enter()180 CPMScreen::enter() 255 181 { 256 182 m_desks->enter(); 257 183 if (m_isPrimary) { 258 // enable special key sequences on win95 family259 enableSpecialKeys(true);260 261 184 // watch jump zones 262 185 m_setMode(kHOOK_WATCH_JUMP_ZONE); … … 272 195 273 196 bool 274 CMSWindowsScreen::leave() 275 { 276 // get keyboard layout of foreground window. we'll use this 277 // keyboard layout for translating keys sent to clients. 278 HWND window = GetForegroundWindow(); 279 DWORD thread = GetWindowThreadProcessId(window, NULL); 280 m_keyLayout = GetKeyboardLayout(thread); 281 282 // tell the key mapper about the keyboard layout 283 m_keyState->setKeyLayout(m_keyLayout); 284 285 // tell desk that we're leaving and tell it the keyboard layout 286 m_desks->leave(m_keyLayout); 287 197 CPMScreen::leave() 198 { 288 199 if (m_isPrimary) { 289 200 // warp to center 290 201 warpCursor(m_xCenter, m_yCenter); 291 202 292 // disable special key sequences on win95 family293 enableSpecialKeys(false);294 295 203 // all messages prior to now are invalid 296 204 nextMark(); … … 312 220 313 221 bool 314 C MSWindowsScreen::setClipboard(ClipboardID, const IClipboard* src)315 { 316 C MSWindowsClipboard dst(m_window);222 CPMScreen::setClipboard(ClipboardID, const IClipboard* src) 223 { 224 CPMClipboard dst(m_window); 317 225 if (src != NULL) { 318 226 // save clipboard data 319 227 return CClipboard::copy(&dst, src); 320 228 } 321 else { 322 // assert clipboard ownership 323 if (!dst.open(0)) { 324 return false; 325 } 326 dst.empty(); 327 dst.close(); 328 return true; 329 } 330 } 331 332 void 333 CMSWindowsScreen::checkClipboards() 334 { 335 // if we think we own the clipboard but we don't then somebody 336 // grabbed the clipboard on this screen without us knowing. 337 // tell the server that this screen grabbed the clipboard. 338 // 339 // this works around bugs in the clipboard viewer chain. 340 // sometimes NT will simply never send WM_DRAWCLIPBOARD 341 // messages for no apparent reason and rebooting fixes the 342 // problem. since we don't want a broken clipboard until the 343 // next reboot we do this double check. clipboard ownership 344 // won't be reflected on other screens until we leave but at 345 // least the clipboard itself will work. 346 if (m_ownClipboard && !CMSWindowsClipboard::isOwnedBySynergy()) { 229 // assert clipboard ownership 230 if (!dst.open(0)) { 231 return false; 232 } 233 dst.empty(); 234 dst.close(); 235 return true; 236 } 237 238 void 239 CPMScreen::checkClipboards() 240 { 241 // be careful, even if we don't have the NT bugs. 242 if (m_ownClipboard && !CPMClipboard::isOwnedBySynergy()) { 347 243 LOG((CLOG_DEBUG "clipboard changed: lost ownership and no notification received")); 348 244 m_ownClipboard = false; … … 353 249 354 250 void 355 CMSWindowsScreen::openScreensaver(bool notify) 356 { 357 assert(m_screensaver != NULL); 358 251 CPMScreen::openScreensaver(bool notify) 252 { 359 253 m_screensaverNotify = notify; 360 if (m_screensaverNotify) { 361 m_desks->installScreensaverHooks(true); 362 } 363 else { 254 if (!m_screensaverNotify) { 364 255 m_screensaver->disable(); 365 256 } … … 367 258 368 259 void 369 CMSWindowsScreen::closeScreensaver() 370 { 371 if (m_screensaver != NULL) { 372 if (m_screensaverNotify) { 373 m_desks->installScreensaverHooks(false); 374 } 375 else { 376 m_screensaver->enable(); 377 } 378 } 379 m_screensaverNotify = false; 380 } 381 382 void 383 CMSWindowsScreen::screensaver(bool activate) 384 { 385 assert(m_screensaver != NULL); 386 387 if (activate) { 388 m_screensaver->activate(); 389 } 390 else { 391 m_screensaver->deactivate(); 392 } 393 } 394 395 void 396 CMSWindowsScreen::resetOptions() 397 { 398 m_desks->resetOptions(); 399 } 400 401 void 402 CMSWindowsScreen::setOptions(const COptionsList& options) 403 { 404 m_desks->setOptions(options); 405 } 406 407 void 408 CMSWindowsScreen::setSequenceNumber(UInt32 seqNum) 260 CPMScreen::closeScreensaver() 261 { 262 if (!m_screensaverNotify) { 263 m_screensaver->enable(); 264 } 265 } 266 267 void 268 CPMScreen::screensaver(bool activate) 269 { 270 if (activate) { 271 m_screensaver->activate(); 272 } 273 else { 274 m_screensaver->deactivate(); 275 } 276 } 277 278 void 279 CPMScreen::resetOptions() 280 { 281 //example m_xtestIsXineramaUnaware = true; 282 } 283 284 void 285 CPMScreen::setOptions(const COptionsList& options) 286 { 287 for (UInt32 i = 0, n = options.size(); i < n; i += 2) { 288 //example if (options[i] == kOptionXTestXineramaUnaware) { 289 //example m_xtestIsXineramaUnaware = (options[i + 1] != 0); 290 //example LOG((CLOG_DEBUG1 "XTest is Xinerama unaware %s", m_xtestIsXineramaUnaware ? "true" : "false")); 291 //example } 292 } 293 } 294 295 void 296 CPMScreen::setSequenceNumber(UInt32 seqNum) 409 297 { 410 298 m_sequenceNumber = seqNum; … … 412 300 413 301 bool 414 C MSWindowsScreen::isPrimary() const302 CPMScreen::isPrimary() const 415 303 { 416 304 return m_isPrimary; … … 418 306 419 307 void* 420 CMSWindowsScreen::getEventTarget() const 421 { 422 return const_cast<CMSWindowsScreen*>(this); 423 } 424 425 bool 426 CMSWindowsScreen::getClipboard(ClipboardID, IClipboard* dst) const 427 { 428 CMSWindowsClipboard src(m_window); 429 CClipboard::copy(dst, &src); 430 return true; 431 } 432 433 void 434 CMSWindowsScreen::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const 308 CPMScreen::getEventTarget() const 309 { 310 return const_cast<CPMScreen*>(this); 311 } 312 313 bool 314 CPMScreen::getClipboard(ClipboardID, IClipboard* dst) const 315 { 316 CPMClipboard src(m_window); 317 return CClipboard::copy(dst, &src); 318 } 319 320 void 321 CPMScreen::getShape(SInt32& x, SInt32& y, SInt32& cx, SInt32& cy) const 435 322 { 436 323 assert(m_class != 0); … … 438 325 x = m_x; 439 326 y = m_y; 440 w = m_w; 441 h = m_h; 442 } 443 444 void 445 CMSWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const 446 { 447 m_desks->getCursorPos(x, y); 448 } 449 450 void 451 CMSWindowsScreen::reconfigure(UInt32 activeSides) 452 { 453 assert(m_isPrimary); 454 455 LOG((CLOG_DEBUG "active sides: %x", activeSides)); 456 m_setSides(activeSides); 457 } 458 459 void 460 CMSWindowsScreen::warpCursor(SInt32 x, SInt32 y) 327 cx= m_cx; 328 cy = m_cy; 329 } 330 331 void 332 CPMScreen::getCursorPos(SInt32& x, SInt32& y) const 333 { 334 CURSORINFO Info; 335 if (WinQueryCursorInfo(HWND_DESKTOP, &Info)) { 336 x = Info.x; 337 y = m_cy - Info.y; 338 } else { 339 x = 0; 340 y = 0; 341 } 342 } 343 344 void 345 CPMScreen::reconfigure(UInt32 activeSides) 346 { 347 // do nothing. 348 } 349 350 void 351 CPMScreen::warpCursor(SInt32 x, SInt32 y) 461 352 { 462 353 // warp mouse … … 464 355 465 356 // remove all input events before and including warp 466 MSG msg; 467 while (PeekMessage(&msg, NULL, SYNERGY_MSG_INPUT_FIRST, 468 SYNERGY_MSG_INPUT_LAST, PM_REMOVE)) { 357 QMSG qmsg; 358 while (WinPeekMsg(m_hab, &qmsg, NULLHANDLE, SYNERGY_MSG_INPUT_FIRST, SYNERGY_MSG_INPUT_LAST, PM_REMOVE)) { 469 359 // do nothing 470 360 } … … 476 366 477 367 UInt32 478 C MSWindowsScreen::registerHotKey(KeyID key, KeyModifierMask mask)368 CPMScreen::registerHotKey(KeyID key, KeyModifierMask mask) 479 369 { 480 370 // only allow certain modifiers … … 490 380 } 491 381 382 #if 1 383 LOG((CLOG_WARN "not implemented id=%04x mask=%04x", key, mask)); 384 return 0; 385 #else 492 386 // convert to win32 493 387 UINT modifiers = 0; … … 545 439 LOG((CLOG_DEBUG "registered hotkey %s (id=%04x mask=%04x) as id=%d", CKeyMap::formatKey(key, mask).c_str(), key, mask, id)); 546 440 return id; 547 } 548 549 void 550 CMSWindowsScreen::unregisterHotKey(UInt32 id) 441 #endif 442 } 443 444 void 445 CPMScreen::unregisterHotKey(UInt32 id) 551 446 { 552 447 // look up hotkey … … 558 453 // unregister with OS 559 454 bool err; 455 #if 1 456 err = true; 457 #else 560 458 if (i->second.getVirtualKey() != 0) { 561 459 err = !UnregisterHotKey(NULL, id); 562 } 563 else { 460 } else { 564 461 err = false; 565 462 } 463 #endif 566 464 if (err) { 567 465 LOG((CLOG_WARN "failed to unregister hotkey id=%d", id)); … … 578 476 579 477 void 580 C MSWindowsScreen::fakeInputBegin()478 CPMScreen::fakeInputBegin() 581 479 { 582 480 assert(m_isPrimary); … … 589 487 590 488 void 591 C MSWindowsScreen::fakeInputEnd()489 CPMScreen::fakeInputEnd() 592 490 { 593 491 assert(m_isPrimary); … … 600 498 601 499 SInt32 602 C MSWindowsScreen::getJumpZoneSize() const500 CPMScreen::getJumpZoneSize() const 603 501 { 604 502 return 1; … … 606 504 607 505 bool 608 C MSWindowsScreen::isAnyMouseButtonDown() const506 CPMScreen::isAnyMouseButtonDown() const 609 507 { 610 508 static const char* buttonToName[] = { … … 628 526 629 527 void 630 C MSWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const528 CPMScreen::getCursorCenter(SInt32& x, SInt32& y) const 631 529 { 632 530 x = m_xCenter; … … 635 533 636 534 void 637 C MSWindowsScreen::fakeMouseButton(ButtonID id, bool press) const535 CPMScreen::fakeMouseButton(ButtonID id, bool press) const 638 536 { 639 537 m_desks->fakeMouseButton(id, press); … … 641 539 642 540 void 643 C MSWindowsScreen::fakeMouseMove(SInt32 x, SInt32 y) const541 CPMScreen::fakeMouseMove(SInt32 x, SInt32 y) const 644 542 { 645 543 m_desks->fakeMouseMove(x, y); … … 647 545 648 546 void 649 C MSWindowsScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const547 CPMScreen::fakeMouseRelativeMove(SInt32 dx, SInt32 dy) const 650 548 { 651 549 m_desks->fakeMouseRelativeMove(dx, dy); … … 653 551 654 552 void 655 C MSWindowsScreen::fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const553 CPMScreen::fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const 656 554 { 657 555 m_desks->fakeMouseWheel(xDelta, yDelta); … … 659 557 660 558 void 661 C MSWindowsScreen::updateKeys()559 CPMScreen::updateKeys() 662 560 { 663 561 m_desks->updateKeys(); … … 665 563 666 564 void 667 C MSWindowsScreen::fakeKeyDown(KeyID id, KeyModifierMask mask,565 CPMScreen::fakeKeyDown(KeyID id, KeyModifierMask mask, 668 566 KeyButton button) 669 567 { … … 673 571 674 572 void 675 C MSWindowsScreen::fakeKeyRepeat(KeyID id, KeyModifierMask mask,573 CPMScreen::fakeKeyRepeat(KeyID id, KeyModifierMask mask, 676 574 SInt32 count, KeyButton button) 677 575 { … … 681 579 682 580 void 683 C MSWindowsScreen::fakeKeyUp(KeyButton button)581 CPMScreen::fakeKeyUp(KeyButton button) 684 582 { 685 583 CPlatformScreen::fakeKeyUp(button); … … 688 586 689 587 void 690 C MSWindowsScreen::fakeAllKeysUp()588 CPMScreen::fakeAllKeysUp() 691 589 { 692 590 CPlatformScreen::fakeAllKeysUp(); … … 695 593 696 594 HINSTANCE 697 C MSWindowsScreen::openHookLibrary(const char* name)595 CPMScreen::openHookLibrary(const char* name) 698 596 { 699 597 // load the hook library … … 729 627 730 628 void 731 C MSWindowsScreen::closeHookLibrary(HINSTANCE hookLibrary) const629 CPMScreen::closeHookLibrary(HINSTANCE hookLibrary) const 732 630 { 733 631 if (hookLibrary != NULL) { … … 737 635 } 738 636 739 HCURSOR740 CMSWindowsScreen::createBlankCursor() const741 {742 // create a transparent cursor743 int cw = GetSystemMetrics(SM_CXCURSOR);744 int ch = GetSystemMetrics(SM_CYCURSOR);745 UInt8* cursorAND = new UInt8[ch * ((cw + 31) >> 2)];746 UInt8* cursorXOR = new UInt8[ch * ((cw + 31) >> 2)];747 memset(cursorAND, 0xff, ch * ((cw + 31) >> 2));748 memset(cursorXOR, 0x00, ch * ((cw + 31) >> 2));749 HCURSOR c = CreateCursor(s_instance, 0, 0, cw, ch, cursorAND, cursorXOR);750 delete[] cursorXOR;751 delete[] cursorAND;752 return c;753 }754 755 void756 CMSWindowsScreen::destroyCursor(HCURSOR cursor) const757 {758 if (cursor != NULL) {759 DestroyCursor(cursor);760 }761 }762 763 637 ATOM 764 C MSWindowsScreen::createWindowClass() const638 CPMScreen::createWindowClass() const 765 639 { 766 640 WNDCLASSEX classInfo; 767 641 classInfo.cbSize = sizeof(classInfo); 768 642 classInfo.style = CS_DBLCLKS | CS_NOCLOSE; 769 classInfo.lpfnWndProc = &C MSWindowsScreen::wndProc;643 classInfo.lpfnWndProc = &CPMScreen::wndProc; 770 644 classInfo.cbClsExtra = 0; 771 645 classInfo.cbWndExtra = 0; … … 781 655 782 656 void 783 C MSWindowsScreen::destroyClass(ATOM windowClass) const657 CPMScreen::destroyClass(ATOM windowClass) const 784 658 { 785 659 if (windowClass != 0) { … … 789 663 790 664 HWND 791 C MSWindowsScreen::createWindow(ATOM windowClass, const char* name) const665 CPMScreen::createWindow(ATOM windowClass, const char* name) const 792 666 { 793 667 HWND window = CreateWindowEx(WS_EX_TOPMOST | … … 809 683 810 684 void 811 C MSWindowsScreen::destroyWindow(HWND hwnd) const685 CPMScreen::destroyWindow(HWND hwnd) const 812 686 { 813 687 if (hwnd != NULL) { … … 817 691 818 692 void 819 C MSWindowsScreen::sendEvent(CEvent::Type type, void* data)693 CPMScreen::sendEvent(CEvent::Type type, void* data) 820 694 { 821 695 EVENTQUEUE->addEvent(CEvent(type, getEventTarget(), data)); … … 823 697 824 698 void 825 C MSWindowsScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id)699 CPMScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id) 826 700 { 827 701 CClipboardInfo* info = (CClipboardInfo*)malloc(sizeof(CClipboardInfo)); … … 832 706 833 707 void 834 C MSWindowsScreen::handleSystemEvent(const CEvent& event, void*)708 CPMScreen::handleSystemEvent(const CEvent& event, void*) 835 709 { 836 710 MSG* msg = reinterpret_cast<MSG*>(event.getData()); … … 848 722 849 723 void 850 C MSWindowsScreen::updateButtons()724 CPMScreen::updateButtons() 851 725 { 852 726 int numButtons = GetSystemMetrics(SM_CMOUSEBUTTONS); … … 862 736 863 737 IKeyState* 864 C MSWindowsScreen::getKeyState() const738 CPMScreen::getKeyState() const 865 739 { 866 740 return m_keyState; … … 868 742 869 743 bool 870 C MSWindowsScreen::onPreDispatch(HWND hwnd,744 CPMScreen::onPreDispatch(HWND hwnd, 871 745 UINT message, WPARAM wParam, LPARAM lParam) 872 746 { … … 889 763 890 764 bool 891 C MSWindowsScreen::onPreDispatchPrimary(HWND,765 CPMScreen::onPreDispatchPrimary(HWND, 892 766 UINT message, WPARAM wParam, LPARAM lParam) 893 767 { … … 946 820 947 821 bool 948 C MSWindowsScreen::onEvent(HWND, UINT msg,822 CPMScreen::onEvent(HWND, UINT msg, 949 823 WPARAM wParam, LPARAM lParam, LRESULT* result) 950 824 { … … 1006 880 *result = TRUE; 1007 881 return true; 1008 1009 case WM_DEVICECHANGE:1010 forceShowCursor();1011 break;1012 1013 case WM_SETTINGCHANGE:1014 if (wParam == SPI_SETMOUSEKEYS) {1015 forceShowCursor();1016 }1017 break;1018 882 } 1019 883 … … 1022 886 1023 887 bool 1024 C MSWindowsScreen::onMark(UInt32 mark)888 CPMScreen::onMark(UInt32 mark) 1025 889 { 1026 890 m_markReceived = mark; … … 1029 893 1030 894 bool 1031 C MSWindowsScreen::onKey(WPARAM wParam, LPARAM lParam)895 CPMScreen::onKey(WPARAM wParam, LPARAM lParam) 1032 896 { 1033 897 static const KeyModifierMask s_ctrlAlt = … … 1172 1036 1173 1037 bool 1174 C MSWindowsScreen::onHotKey(WPARAM wParam, LPARAM lParam)1038 CPMScreen::onHotKey(WPARAM wParam, LPARAM lParam) 1175 1039 { 1176 1040 // get the key info … … 1219 1083 1220 1084 bool 1221 C MSWindowsScreen::onMouseButton(WPARAM wParam, LPARAM lParam)1085 CPMScreen::onMouseButton(WPARAM wParam, LPARAM lParam) 1222 1086 { 1223 1087 // get which button 1224 bool pressed = mapPressFromEvent( wParam, lParam);1225 ButtonID button = mapButtonFromEvent( wParam, lParam);1088 bool pressed = mapPressFromEvent((ULONG)wParam, lParam); 1089 ButtonID button = mapButtonFromEvent((ULONG)wParam, lParam); 1226 1090 1227 1091 // keep our shadow key state up to date … … 1258 1122 1259 1123 bool 1260 C MSWindowsScreen::onMouseMove(SInt32 mx, SInt32 my)1124 CPMScreen::onMouseMove(SInt32 mx, SInt32 my) 1261 1125 { 1262 1126 // compute motion delta (relative to the last known … … 1292 1156 static SInt32 bogusZoneSize = 10; 1293 1157 if (-x + bogusZoneSize > m_xCenter - m_x || 1294 x + bogusZoneSize > m_x + m_ w- m_xCenter ||1158 x + bogusZoneSize > m_x + m_cx - m_xCenter || 1295 1159 -y + bogusZoneSize > m_yCenter - m_y || 1296 y + bogusZoneSize > m_y + m_ h- m_yCenter) {1160 y + bogusZoneSize > m_y + m_cy - m_yCenter) { 1297 1161 LOG((CLOG_DEBUG "dropped bogus motion %+d,%+d", x, y)); 1298 1162 } … … 1307 1171 1308 1172 bool 1309 C MSWindowsScreen::onMouseWheel(SInt32 xDelta, SInt32 yDelta)1173 CPMScreen::onMouseWheel(SInt32 xDelta, SInt32 yDelta) 1310 1174 { 1311 1175 // ignore message if posted prior to last mark change … … 1318 1182 1319 1183 bool 1320 C MSWindowsScreen::onScreensaver(bool activated)1184 CPMScreen::onScreensaver(bool activated) 1321 1185 { 1322 1186 // ignore this message if there are any other screen saver … … 1358 1222 1359 1223 bool 1360 C MSWindowsScreen::onDisplayChange()1224 CPMScreen::onDisplayChange() 1361 1225 { 1362 1226 // screen resolution may have changed. save old shape. 1363 SInt32 xOld = m_x, yOld = m_y, wOld = m_ w, hOld = m_h;1227 SInt32 xOld = m_x, yOld = m_y, wOld = m_cx, hOld = m_cy; 1364 1228 1365 1229 // update shape … … 1367 1231 1368 1232 // do nothing if resolution hasn't changed 1369 if (xOld != m_x || yOld != m_y || wOld != m_ w || hOld != m_h) {1233 if (xOld != m_x || yOld != m_y || wOld != m_cx || hOld != m_cy) { 1370 1234 if (m_isPrimary) { 1371 1235 // warp mouse to center if off screen … … 1376 1240 // tell hook about resize if on screen 1377 1241 else { 1378 m_setZone(m_x, m_y, m_ w, m_h, getJumpZoneSize());1242 m_setZone(m_x, m_y, m_cx, m_cy, getJumpZoneSize()); 1379 1243 } 1380 1244 } … … 1383 1247 sendEvent(getShapeChangedEvent()); 1384 1248 1385 LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d %s", m_x, m_y, m_ w, m_h, m_multimon ? "(multi-monitor)" : ""));1249 LOG((CLOG_DEBUG "screen shape: %d,%d %dx%d %s", m_x, m_y, m_cx, m_cy, m_multimon ? "(multi-monitor)" : "")); 1386 1250 } 1387 1251 … … 1390 1254 1391 1255 bool 1392 C MSWindowsScreen::onClipboardChange()1256 CPMScreen::onClipboardChange() 1393 1257 { 1394 1258 // now notify client that somebody changed the clipboard (unless 1395 1259 // we're the owner). 1396 if (!C MSWindowsClipboard::isOwnedBySynergy()) {1260 if (!CPMClipboard::isOwnedBySynergy()) { 1397 1261 if (m_ownClipboard) { 1398 1262 LOG((CLOG_DEBUG "clipboard changed: lost ownership")); … … 1411 1275 1412 1276 void 1413 C MSWindowsScreen::warpCursorNoFlush(SInt32 x, SInt32 y)1277 CPMScreen::warpCursorNoFlush(SInt32 x, SInt32 y) 1414 1278 { 1415 1279 // send an event that we can recognize before the mouse warp 1416 PostThreadMessage(GetCurrentThreadId(), SYNERGY_MSG_PRE_WARP, x,y);1280 WinPostQueueMsg(m_hmq, SYNERGY_MSG_PRE_WARP, (MPARAM)x, (MPARAM)y); 1417 1281 1418 1282 // warp mouse. hopefully this inserts a mouse motion event 1419 1283 // between the previous message and the following message. 1420 SetCursorPos(x, y);1284 WinSetPointerPos(HWND_DESKTOP, x, y); 1421 1285 1422 1286 // yield the CPU. there's a race condition when warping: … … 1439 1303 1440 1304 // send an event that we can recognize after the mouse warp 1441 PostThreadMessage(GetCurrentThreadId(), SYNERGY_MSG_POST_WARP, 0, 0);1442 } 1443 1444 void 1445 C MSWindowsScreen::nextMark()1305 WinPostQueueMsg(m_hmq, SYNERGY_MSG_POST_WARP, 0, 0); 1306 } 1307 1308 void 1309 CPMScreen::nextMark() 1446 1310 { 1447 1311 // next mark … … 1449 1313 1450 1314 // mark point in message queue where the mark was changed 1451 PostThreadMessage(GetCurrentThreadId(), SYNERGY_MSG_MARK,m_mark, 0);1452 } 1453 1454 bool 1455 C MSWindowsScreen::ignore() const1315 WinPostQueueMsg(m_hmq, SYNERGY_MSG_MARK, (MPARAM)m_mark, 0); 1316 } 1317 1318 bool 1319 CPMScreen::ignore() const 1456 1320 { 1457 1321 return (m_mark != m_markReceived); … … 1459 1323 1460 1324 void 1461 C MSWindowsScreen::updateScreenShape()1325 CPMScreen::updateScreenShape() 1462 1326 { 1463 1327 // get shape 1464 m_x = GetSystemMetrics(SM_XVIRTUALSCREEN);1465 m_y = GetSystemMetrics(SM_YVIRTUALSCREEN);1466 m_ w = GetSystemMetrics(SM_CXVIRTUALSCREEN);1467 m_ h = GetSystemMetrics(SM_CYVIRTUALSCREEN);1328 m_x = 0; 1329 m_y = 0; 1330 m_cx = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN); 1331 m_cy = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN); 1468 1332 1469 1333 // get center for cursor 1470 m_xCenter = GetSystemMetrics(SM_CXSCREEN) >> 1;1471 m_yCenter = GetSystemMetrics(SM_CYSCREEN) >> 1;1334 m_xCenter = m_cx / 2; 1335 m_yCenter = m_cy / 2; 1472 1336 1473 1337 // check for multiple monitors 1474 m_multimon = (m_w != GetSystemMetrics(SM_CXSCREEN) || 1475 m_h != GetSystemMetrics(SM_CYSCREEN)); 1476 1477 // tell the desks 1478 m_desks->setShape(m_x, m_y, m_w, m_h, m_xCenter, m_yCenter, m_multimon); 1479 } 1480 1481 void 1482 CMSWindowsScreen::handleFixes(const CEvent&, void*) 1483 { 1484 // fix clipboard chain 1485 fixClipboardViewer(); 1486 1338 m_multimon = false; 1339 } 1340 1341 void 1342 CPMScreen::handleFixes(const CEvent&, void*) 1343 { 1487 1344 // update keys if keyboard layouts have changed 1488 1345 if (m_keyState->didGroupsChange()) { … … 1491 1348 } 1492 1349 1493 void1494 CMSWindowsScreen::fixClipboardViewer()1495 {1496 // XXX -- disable this code for now. somehow it can cause an infinite1497 // recursion in the WM_DRAWCLIPBOARD handler. either we're sending1498 // the message to our own window or some window farther down the chain1499 // forwards the message to our window or a window farther up the chain.1500 // i'm not sure how that could happen. the m_nextClipboardWindow = NULL1501 // was not in the code that infinite loops and may fix the bug but i1502 // doubt it.1503 return;1504 ChangeClipboardChain(m_window, m_nextClipboardWindow);1505 m_nextClipboardWindow = NULL;1506 m_nextClipboardWindow = SetClipboardViewer(m_window);1507 }1508 1509 void1510 CMSWindowsScreen::enableSpecialKeys(bool enable) const1511 {1512 // enable/disable ctrl+alt+del, alt+tab, etc on win95 family.1513 // since the win95 family doesn't support low-level hooks, we1514 // use this undocumented feature to suppress normal handling1515 // of certain key combinations.1516 if (m_is95Family) {1517 DWORD dummy = 0;1518 SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,1519 enable ? FALSE : TRUE, &dummy, 0);1520 }1521 }1522 1523 1350 ButtonID 1524 CMSWindowsScreen::mapButtonFromEvent(WPARAM msg, LPARAM button) const 1525 { 1351 CPMScreen::mapButtonFromEvent(ULONG msg, MPARAM button) const 1352 { 1353 /** @todo query which is left and which is right. */ 1354 1526 1355 switch (msg) { 1527 case WM_LBUTTONDOWN: 1528 case WM_LBUTTONDBLCLK: 1529 case WM_LBUTTONUP: 1530 case WM_NCLBUTTONDOWN: 1531 case WM_NCLBUTTONDBLCLK: 1532 case WM_NCLBUTTONUP: 1533 return kButtonLeft; 1534 1535 case WM_MBUTTONDOWN: 1536 case WM_MBUTTONDBLCLK: 1537 case WM_MBUTTONUP: 1538 case WM_NCMBUTTONDOWN: 1539 case WM_NCMBUTTONDBLCLK: 1540 case WM_NCMBUTTONUP: 1541 return kButtonMiddle; 1542 1543 case WM_RBUTTONDOWN: 1544 case WM_RBUTTONDBLCLK: 1545 case WM_RBUTTONUP: 1546 case WM_NCRBUTTONDOWN: 1547 case WM_NCRBUTTONDBLCLK: 1548 case WM_NCRBUTTONUP: 1549 return kButtonRight; 1550 1551 case WM_XBUTTONDOWN: 1552 case WM_XBUTTONDBLCLK: 1553 case WM_XBUTTONUP: 1554 case WM_NCXBUTTONDOWN: 1555 case WM_NCXBUTTONDBLCLK: 1556 case WM_NCXBUTTONUP: 1557 switch (button) { 1558 case XBUTTON1: 1559 if (GetSystemMetrics(SM_CMOUSEBUTTONS) >= 4) { 1560 return kButtonExtra0 + 0; 1561 } 1562 break; 1563 1564 case XBUTTON2: 1565 if (GetSystemMetrics(SM_CMOUSEBUTTONS) >= 5) { 1566 return kButtonExtra0 + 1; 1567 } 1568 break; 1569 } 1570 return kButtonNone; 1571 1572 default: 1573 return kButtonNone; 1574 } 1575 } 1576 1577 bool 1578 CMSWindowsScreen::mapPressFromEvent(WPARAM msg, LPARAM) const 1356 case WM_BUTTON1DOWN: 1357 case WM_BUTTON1UP: 1358 case WM_BUTTON1DBLCLK: 1359 case WM_BUTTON1CLICK: //?? 1360 return kButtonLeft; 1361 1362 case WM_BUTTON2DOWN: 1363 case WM_BUTTON2UP: 1364 case WM_BUTTON2DBLCLK: 1365 case WM_BUTTON2CLICK: //?? 1366 return kButtonLeft; 1367 1368 case WM_BUTTON3DOWN: 1369 case WM_BUTTON3UP: 1370 case WM_BUTTON3DBLCLK: 1371 case WM_BUTTON3CLICK: //?? 1372 return kButtonMiddle; 1373 default: 1374 return kButtonNone; 1375 } 1376 } 1377 1378 bool 1379 CPMScreen::mapPressFromEvent(ULONG msg, LPARAM) const 1579 1380 { 1580 1381 switch (msg) { 1581 case WM_LBUTTONDOWN: 1582 case WM_MBUTTONDOWN: 1583 case WM_RBUTTONDOWN: 1584 case WM_XBUTTONDOWN: 1585 case WM_LBUTTONDBLCLK: 1586 case WM_MBUTTONDBLCLK: 1587 case WM_RBUTTONDBLCLK: 1588 case WM_XBUTTONDBLCLK: 1589 case WM_NCLBUTTONDOWN: 1590 case WM_NCMBUTTONDOWN: 1591 case WM_NCRBUTTONDOWN: 1592 case WM_NCXBUTTONDOWN: 1593 case WM_NCLBUTTONDBLCLK: 1594 case WM_NCMBUTTONDBLCLK: 1595 case WM_NCRBUTTONDBLCLK: 1596 case WM_NCXBUTTONDBLCLK: 1597 return true; 1598 1599 case WM_LBUTTONUP: 1600 case WM_MBUTTONUP: 1601 case WM_RBUTTONUP: 1602 case WM_XBUTTONUP: 1603 case WM_NCLBUTTONUP: 1604 case WM_NCMBUTTONUP: 1605 case WM_NCRBUTTONUP: 1606 case WM_NCXBUTTONUP: 1607 return false; 1608 1609 default: 1610 return false; 1611 } 1612 } 1613 1614 void 1615 CMSWindowsScreen::updateKeysCB(void*) 1382 case WM_BUTTON1DOWN: 1383 case WM_BUTTON1CLICK: //?? 1384 case WM_BUTTON1DBLCLK: 1385 case WM_BUTTON2DOWN: 1386 case WM_BUTTON2DBLCLK: 1387 case WM_BUTTON2CLICK: //?? 1388 case WM_BUTTON3DOWN: 1389 case WM_BUTTON3DBLCLK: 1390 case WM_BUTTON3CLICK: //?? 1391 return true; 1392 case WM_BUTTON1UP: 1393 case WM_BUTTON2UP: 1394 case WM_BUTTON3UP: 1395 return false; 1396 default: 1397 return false; 1398 } 1399 } 1400 1401 void 1402 CPMScreen::updateKeysCB(void*) 1616 1403 { 1617 1404 // record which keys we think are down … … 1646 1433 1647 1434 void 1648 C MSWindowsScreen::forceShowCursor()1649 { 1650 // check for mouse 1651 m_hasMouse = (GetSystemMetrics(SM_MOUSEPRESENT) != 0);1435 CPMScreen::forceShowCursor() 1436 { 1437 // check for mouse - probably not required. 1438 m_hasMouse = WinQuerySysValue(HWND_DESKTOP, SV_MOUSEPRESENT) != FALSE; 1652 1439 1653 1440 // decide if we should show the mouse … … 1656 1443 // show/hide the mouse 1657 1444 if (showMouse != m_showingMouse) { 1658 if (showMouse) { 1659 m_oldMouseKeys.cbSize = sizeof(m_oldMouseKeys); 1660 m_gotOldMouseKeys = 1661 (SystemParametersInfo(SPI_GETMOUSEKEYS, 1662 m_oldMouseKeys.cbSize, &m_oldMouseKeys, 0) != 0); 1663 if (m_gotOldMouseKeys) { 1664 m_mouseKeys = m_oldMouseKeys; 1665 m_showingMouse = true; 1666 updateForceShowCursor(); 1667 } 1668 } 1669 else { 1670 if (m_gotOldMouseKeys) { 1671 SystemParametersInfo(SPI_SETMOUSEKEYS, 1672 m_oldMouseKeys.cbSize, 1673 &m_oldMouseKeys, SPIF_SENDCHANGE); 1674 m_showingMouse = false; 1675 } 1676 } 1677 } 1678 } 1679 1680 void 1681 CMSWindowsScreen::updateForceShowCursor() 1682 { 1683 DWORD oldFlags = m_mouseKeys.dwFlags; 1684 1685 // turn on MouseKeys 1686 m_mouseKeys.dwFlags = MKF_AVAILABLE | MKF_MOUSEKEYSON; 1687 1688 // make sure MouseKeys is active in whatever state the NumLock is 1689 // not currently in. 1690 if ((m_keyState->getActiveModifiers() & KeyModifierNumLock) != 0) { 1691 m_mouseKeys.dwFlags |= MKF_REPLACENUMBERS; 1692 } 1693 1694 // update MouseKeys 1695 if (oldFlags != m_mouseKeys.dwFlags) { 1696 SystemParametersInfo(SPI_SETMOUSEKEYS, 1697 m_mouseKeys.cbSize, &m_mouseKeys, SPIF_SENDCHANGE); 1698 } 1699 } 1700 1701 LRESULT CALLBACK 1702 CMSWindowsScreen::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 1445 WinShowPointer(HWND_DESKTOP, showMouse); 1446 m_showingMouse = WinQuerySysValue(HWND_DESKTOP, SV_POINTERLEVEL) != 0; 1447 } 1448 } 1449 1450 void 1451 CPMScreen::updateForceShowCursor() 1452 { 1453 //??? 1454 } 1455 1456 HRESULT EXPENTRY 1457 CPMScreen::wndProc(HWND hwnd, UINT msg, MPARAM mp1, MPARAM mp2) 1703 1458 { 1704 1459 assert(s_screen != NULL); 1705 1460 1706 LRESULT result= 0;1707 if (!s_screen->onEvent(hwnd, msg, wParam, lParam, &result)) {1708 result = DefWindowProc(hwnd, msg, wParam, lParam);1709 } 1710 1711 return result;1461 HRESULT mr = 0; 1462 if (!s_screen->onEvent(hwnd, msg, mp1, mp2, &result)) { 1463 mr = WinDefWindowProc(hwnd, msg, mp1, mp2); 1464 } 1465 1466 return mr; 1712 1467 } 1713 1468 1714 1469 1715 1470 // 1716 // C MSWindowsScreen::CHotKeyItem1471 // CPMScreen::CHotKeyItem 1717 1472 // 1718 1473 1719 C MSWindowsScreen::CHotKeyItem::CHotKeyItem(UINT keycode, UINT mask) :1474 CPMScreen::CHotKeyItem::CHotKeyItem(UINT keycode, UINT mask) : 1720 1475 m_keycode(keycode), 1721 1476 m_mask(mask) … … 1725 1480 1726 1481 UINT 1727 C MSWindowsScreen::CHotKeyItem::getVirtualKey() const1482 CPMScreen::CHotKeyItem::getVirtualKey() const 1728 1483 { 1729 1484 return m_keycode; … … 1731 1486 1732 1487 bool 1733 C MSWindowsScreen::CHotKeyItem::operator<(const CHotKeyItem& x) const1488 CPMScreen::CHotKeyItem::operator<(const CHotKeyItem& x) const 1734 1489 { 1735 1490 return (m_keycode < x.m_keycode ||
Note:
See TracChangeset
for help on using the changeset viewer.