// Converts WM_CHAR lParam + ModifyerKeys to an IBusKey. public static IBusKey Convert(uint lParam, Keys modifyerKeys) { // lparm & 0x0f == repeat count // (lParam & 0xFF0000) >> 16 == scan code // (lParam & 0xFF0000) >> 16 == extended keys // (lParam & 20000000) >> 29 == is Alt IBusKey ret = new IBusKey(); uint scancode = (lParam & 0xFF0000) >> 16; bool shifted = ((modifyerKeys & Keys.CapsLock) == 0 && (modifyerKeys & Keys.Shift) != 0 || ((modifyerKeys & Keys.CapsLock) != 0 && (modifyerKeys & Keys.Shift) == 0)); ret.keyval = KeycodeToKeysym(scancode, shifted); ret.keycode = scancode; ret.state = ModifyerKeysToState(modifyerKeys); return(ret); }
/// <summary> /// Handle actual key presses. /// </summary> /// <returns> /// true if we handled keypress /// false if keypress needs handling by someone else /// </returns> public bool NotifyKeyPress(uint charCodeUtf16, uint lParam, Keys modifierKeys) { if (!IBusCommunicator.Connected) { return(false); } m_ignoreInitialPreedit = false; // reset saved preedit selection that we might have set in NotifyMouseClick(). m_savedPreeditSelection = null; // modifierKeys doesn't contains CapsLock and // mono Control.IsKeyLocked(Keys.CapsLock) doesn't work on mono. // so we guess the caps state by unicode value and the shift state // this is far from ideal. if (char.IsUpper((char)charCodeUtf16) && (modifierKeys & Keys.Shift) == 0) { modifierKeys |= Keys.CapsLock; } else if (char.IsLower((char)charCodeUtf16) && (modifierKeys & Keys.Shift) != 0) { modifierKeys |= Keys.CapsLock; } IBusKey key = KeysConverter.Convert(lParam, modifierKeys); if (IBusCommunicator.ProcessKeyEvent(key.keyval, key.keycode, key.state)) { return(true); } // if ProcessKeyEvent doesn't consume the key // we need to kill any preedits and // sync before continuing processing the keypress ResetAndWaitForCommit(); return(false); }