Changeset 51439 in vbox for trunk/src/VBox
- Timestamp:
- May 28, 2014 9:27:03 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 93994
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
r50693 r51439 363 363 } 364 364 365 /** 366 * @brief isSyntheticLCtrl 367 * @param pMsg Windows WM_[SYS]KEY* event message structure 368 * @return true if this is a synthetic LCtrl event, false otherwise 369 * This function is a heuristic to tell whether a key event is the first in 370 * a synthetic LCtrl+RAlt sequence which Windows uses to signal AltGr. Our 371 * heuristic is in two parts. First of all, we check whether there is a pending 372 * RAlt key event matching this LCtrl event (i.e. both key up or both key down) 373 * and if there is, we check whether the current layout has an AltGr key. We 374 * check this by looking to see if any of the layout-dependent keys has a symbol 375 * associated when AltGr is pressed. 376 */ 377 static bool isSyntheticLCtrl(MSG *pMsg) 378 { 379 MSG peekMsg; 380 /** Keyboard state array with VK_CONTROL and VK_MENU depressed. */ 381 const BYTE auKeyStates[256] = 382 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x80 }; 383 WORD ach; 384 unsigned i; 385 386 Assert( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN 387 || pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP); 388 if ( ((RT_HIWORD(pMsg->lParam) & 0xFF) != 0x1d /* scan code: Control */) 389 || RT_HIWORD(pMsg->lParam) & KF_EXTENDED) 390 return false; 391 if (!PeekMessage(&peekMsg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE)) 392 return false; 393 if ( (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) 394 && (peekMsg.message != WM_KEYDOWN && peekMsg.message != WM_SYSKEYDOWN)) 395 return false; 396 if ( (pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP) 397 && (peekMsg.message != WM_KEYUP && peekMsg.message != WM_SYSKEYUP)) 398 return false; 399 if ( ((RT_HIWORD(peekMsg.lParam) & 0xFF) != 0x38 /* scan code: Alt */) 400 || !(RT_HIWORD(peekMsg.lParam) & KF_EXTENDED)) 401 return false; 402 /* If we got this far then we have a key event which could potentially 403 * be a synthetic left control. Now we check to see whether the current 404 * keyboard layout actually has an AltGr key by checking whether any of 405 * the keys which might do produce a symbol when AltGr (Control + Alt) is 406 * depressed. Generally this loop will exit pretty early (it exits on the 407 * first iteration for my German layout). If there is no AltGr key in the 408 * layout then it will run right through, but that should not happen very 409 * often as we should hardly ever reach the loop in that case. 410 * 411 * In theory we could do this once and cache the result, but that involves 412 * tracking layout switches to invalidate the cache, and I don't think 413 * that the added complexity is worth the price. 414 */ 415 for (i = '0'; i <= VK_OEM_102; ++i) 416 { 417 if (ToAscii(i, 0, auKeyStates, &ach, 0)) 418 break; 419 /* Skip ranges of virtual keys which are undefined or not relevant. */ 420 if (i == '9') 421 i = 'A' - 1; 422 if (i == 'Z') 423 i = VK_OEM_1 - 1; 424 if (i == VK_OEM_3) 425 i = VK_OEM_4 - 1; 426 if (i == VK_OEM_8) 427 i = VK_OEM_102 - 1; 428 } 429 if (i > VK_OEM_102) 430 return false; 431 return true; 432 } 433 365 434 bool UIKeyboardHandler::winEventFilter(MSG *pMsg, ulong uScreenId) 366 435 { … … 386 455 pMsg->lParam &= ~(0x1 << 25); 387 456 fResult = false; 457 break; 458 } 459 460 if (isSyntheticLCtrl(pMsg)) 461 { 462 fResult = true; 388 463 break; 389 464 } … … 977 1052 return false; 978 1053 979 /* Sometimes it happens that Win inserts additional events on some key980 * press/release. For example, it prepends ALT_GR in German layout with981 * the VK_LCONTROL vkey with curious 0x21D scan code (seems to be necessary982 * to specially treat ALT_GR to enter additional chars to regular apps).983 * These events are definitely unwanted in VM, so filter them out. */984 /* Note (michael): it also sometimes sends the VK_CAPITAL vkey with scan985 * code 0x23a. If this is not passed through then it is impossible to986 * cancel CapsLock on a French keyboard. I didn't find any other examples987 * of these strange events. Let's hope we are not missing anything else988 * of importance! */989 if (m_views[m_iKeyboardHookViewIndex]->hasFocus() && (event.scanCode & ~0xFF))990 {991 if (event.vkCode == VK_CAPITAL)992 return false;993 else994 return true;995 }996 997 /** @todo this needs to be after the preceding check so that998 * we ignore those spurious key events even when the999 * keyboard is not captured. However, that is probably a1000 * hint that that filtering should be done somewhere else,1001 * and not in the keyboard capture handler. */1002 1054 if (!m_fIsKeyboardCaptured) 1003 1055 return false;
Note:
See TracChangeset
for help on using the changeset viewer.