KeyboardLayout::~KeyboardLayout () { #ifndef WINCE ReleaseDeadKeyTables (); #endif }
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 }
KeyboardLayout::~KeyboardLayout () { ReleaseDeadKeyTables (); }