void vncKeymap::ClearShiftKeys() { // Otherwise, we can't distinguish the keys anyway... // Clear the shift key states SetShiftState(VK_SHIFT, FALSE); SetShiftState(VK_CONTROL, FALSE); SetShiftState(VK_MENU, FALSE); }
void vncKeymap::ClearShiftKeys() { if (vncService::IsWinNT()) { // On NT, clear both sets of keys // LEFT SetShiftState(VK_LSHIFT, FALSE); SetShiftState(VK_LCONTROL, FALSE); SetShiftState(VK_LMENU, FALSE); // RIGHT SetShiftState(VK_RSHIFT, FALSE); SetShiftState(VK_RCONTROL, FALSE); SetShiftState(VK_RMENU, FALSE); } else { // Otherwise, we can't distinguish the keys anyway... // Clear the shift key states SetShiftState(VK_SHIFT, FALSE); SetShiftState(VK_CONTROL, FALSE); SetShiftState(VK_MENU, FALSE); } }
void KeyboardLayout::DeactivateDeadKeyState () { if (mActiveDeadKey < 0) return; BYTE kbdState [256]; memset (kbdState, 0, sizeof (kbdState)); SetShiftState (kbdState, mDeadKeyShiftState); EnsureDeadKeyActive (PR_FALSE, mActiveDeadKey, kbdState); mActiveDeadKey = -1; }
PRUint32 KeyboardLayout::GetDeadKeyCombinations (PRUint8 aDeadKey, const PBYTE aDeadKeyKbdState, PRUint16 aShiftStatesWithBaseChars, DeadKeyEntry* aDeadKeyArray, PRUint32 aMaxEntries) { PRBool deadKeyActive = PR_FALSE; PRUint32 entries = 0; BYTE kbdState [256]; memset (kbdState, 0, sizeof (kbdState)); for (PRUint32 shiftState = 0; shiftState < 16; shiftState++) { if (!(aShiftStatesWithBaseChars & (1 << shiftState))) continue; SetShiftState (kbdState, shiftState); for (PRUint32 virtualKey = 0; virtualKey < 256; virtualKey++) { PRInt32 vki = GetKeyIndex (virtualKey); // Dead-key can pair only with such key that produces exactly one base character. if (vki >= 0 && mVirtualKeys [vki].GetNativeUniChars (shiftState) == 1) { // Ensure dead-key is in active state, when it swallows entered character and waits for the next pressed key. if (!deadKeyActive) deadKeyActive = EnsureDeadKeyActive (PR_TRUE, aDeadKey, aDeadKeyKbdState); // Depending on the character the followed the dead-key, the keyboard driver can produce // one composite character, or a dead-key character followed by a second character. PRUint16 compositeChars [5]; PRInt32 rv; rv = ::ToUnicodeEx (virtualKey, 0, kbdState, (LPWSTR)compositeChars, NS_ARRAY_LENGTH (compositeChars), 0, mKeyboardLayout); switch (rv) { case 0: // This key combination does not produce any characters. The dead-key is still in active state. break; case 1: { // Exactly one composite character produced. Now, when dead-key is not active, repeat the last // character one more time to determine the base character. PRUint16 baseChars [5]; rv = ::ToUnicodeEx (virtualKey, 0, kbdState, (LPWSTR)baseChars, NS_ARRAY_LENGTH (baseChars), 0, mKeyboardLayout); NS_ASSERTION (rv == 1, "One base character expected"); if (rv == 1 && entries < aMaxEntries) if (AddDeadKeyEntry (baseChars [0], compositeChars [0], aDeadKeyArray, entries)) entries++; deadKeyActive = PR_FALSE; break; } default: // 1. Unexpected dead-key. Dead-key chaining is not supported. // 2. More than one character generated. This is not a valid dead-key and base character combination. deadKeyActive = PR_FALSE; break; } } } } if (deadKeyActive) deadKeyActive = EnsureDeadKeyActive (PR_FALSE, aDeadKey, aDeadKeyKbdState); NS_QuickSort (aDeadKeyArray, entries, sizeof (DeadKeyEntry), CompareDeadKeyEntries, nsnull); return entries; }
void KeyboardLayout::LoadLayout (HKL aLayout) { #ifndef WINCE PRUint32 shiftState; BYTE kbdState [256]; BYTE originalKbdState [256]; PRUint16 shiftStatesWithDeadKeys = 0; // Bitfield with all shift states that have at least one dead-key. PRUint16 shiftStatesWithBaseChars = 0; // Bitfield with all shift states that produce any possible dead-key base characters. memset (kbdState, 0, sizeof (kbdState)); mActiveDeadKey = -1; mNumOfChars = 0; mKeyboardLayout = aLayout; ReleaseDeadKeyTables (); ::GetKeyboardState (originalKbdState); // For each shift state gather all printable characters that are produced // for normal case when no any dead-key is active. for (shiftState = 0; shiftState < 16; shiftState++) { SetShiftState (kbdState, shiftState); for (PRUint32 virtualKey = 0; virtualKey < 256; virtualKey++) { PRInt32 vki = GetKeyIndex (virtualKey); if (vki < 0) continue; NS_ASSERTION (vki < NS_ARRAY_LENGTH (mVirtualKeys), "invalid index"); PRUint16 uniChars [5]; PRInt32 rv; rv = ::ToUnicodeEx (virtualKey, 0, kbdState, (LPWSTR)uniChars, NS_ARRAY_LENGTH (uniChars), 0, mKeyboardLayout); if (rv < 0) // dead-key { shiftStatesWithDeadKeys |= 1 << shiftState; // Repeat dead-key to deactivate it and get its character representation. PRUint16 deadChar [2]; rv = ::ToUnicodeEx (virtualKey, 0, kbdState, (LPWSTR)deadChar, NS_ARRAY_LENGTH (deadChar), 0, mKeyboardLayout); NS_ASSERTION (rv == 2, "Expecting twice repeated dead-key character"); mVirtualKeys [vki].SetDeadChar (shiftState, deadChar [0]); } else { if (rv == 1) // dead-key can pair only with exactly one base character. shiftStatesWithBaseChars |= 1 << shiftState; mVirtualKeys [vki].SetNormalChars (shiftState, uniChars, rv); } } } // Now process each dead-key to find all its base characters and resulting composite characters. for (shiftState = 0; shiftState < 16; shiftState++) { if (!(shiftStatesWithDeadKeys & (1 << shiftState))) continue; SetShiftState (kbdState, shiftState); for (PRUint32 virtualKey = 0; virtualKey < 256; virtualKey++) { PRInt32 vki = GetKeyIndex (virtualKey); if (vki >= 0 && mVirtualKeys [vki].IsDeadKey (shiftState)) { DeadKeyEntry deadKeyArray [256]; PRInt32 n = GetDeadKeyCombinations (virtualKey, kbdState, shiftStatesWithBaseChars, deadKeyArray, NS_ARRAY_LENGTH (deadKeyArray)); const DeadKeyTable* dkt = mVirtualKeys [vki].MatchingDeadKeyTable (deadKeyArray, n); if (!dkt) dkt = AddDeadKeyTable (deadKeyArray, n); mVirtualKeys [vki].AttachDeadKeyTable (shiftState, dkt); } } } ::SetKeyboardState (originalKbdState); #endif }
void vncKeymap::DoXkeysym(CARD32 keysym, BOOL keydown) { int i; // Cull out some particular keysyms for (i=0; i < (sizeof(ignorekeymap) / sizeof(UINT)); i++) if (ignorekeymap[i] == keysym) return; // First just try to map the virtual keycode using our lookup-table for (i = 0; i < (sizeof(keymap) / sizeof(vncKeymapping)); i++) { if (keymap[i].Xcode == keysym) { UINT virtcode = keymap[i].wincode; // Now simulate the keyboard event KeybdEvent((unsigned char) (virtcode & 255), keydown ? 0 : KEYEVENTF_KEYUP); return; } } // Otherwise, get the OS to tell us how to simulate it SHORT keyval = VkScanKey((char) (keysym & 255)); //VkKeyScan((char) (keysym & 255)); //keyval = (GetKeyState(keyval) << 8) | keyval; // Retrieve the keycode and shift state BYTE keycode = LOBYTE(keyval); BYTE keymask = HIBYTE(keyval); if (keycode == -1) return; BOOL lshift; BOOL ctrl; BOOL alt; // Correct the keymask shift state to cope with the capslock state // Changed to 'Async' by qsf 27/4/99. BOOL capslock = (GetAsyncKeyState(VK_CAPITAL) & 0x8000) != 0; keymask = capslock ? keymask ^ 1 : keymask; // No, so the modifier keys come in only one flavour // Toggle shift to the required position lshift = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0; SetShiftState(VK_SHIFT, keymask & 1); // But only toggle Ctrl & Alt if they aught to be down ctrl = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0; if (!ctrl) SetShiftState(VK_CONTROL, keymask & 2); alt = (GetAsyncKeyState(VK_MENU) & 0x8000) != 0; if (!alt) SetShiftState(VK_MENU, keymask & 4); // Now send the desired keycode KeybdEvent((unsigned char) (keycode & 255), keydown ? 0 : KEYEVENTF_KEYUP); // No, so just reset the single versions SetShiftState(VK_SHIFT, lshift); SetShiftState(VK_CONTROL, ctrl); SetShiftState(VK_MENU, alt); }