This MR lets conhost support IME input window mode.
Note: this MR doesn't include support for properly displaying the glyphs when they fall out of charset of current code page.
It also lets some diacritics to work. Note: for these, the generated INPUT_RECORD sequence still widely differs from native: - it matches the key down INPUT_RECORD + unicode char (which is what most app will use) - it differs on the rest (no key-up, no dead char...) but that shouldn't matter too much
From: Eric Pouech epouech@codeweavers.com
This lets some characters (like diacritics, generated by two keys, (eg. circumflex-e on a French keyboard layout)) have usable key-down INPUT_RECORD.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/conhost/window.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/programs/conhost/window.c b/programs/conhost/window.c index a5dd9979534..9817c5fdac9 100644 --- a/programs/conhost/window.c +++ b/programs/conhost/window.c @@ -1237,6 +1237,25 @@ static void record_key_input( struct console *console, BOOL down, WPARAM wparam, write_console_input( console, &ir, 1, TRUE ); }
+/* generate input_record from WM_CHAR message. */ +static void record_char_input( struct console *console, WCHAR ch, LPARAM lparam ) +{ + INPUT_RECORD ir; + SHORT sh = VkKeyScanW( ch ); + + if (sh == ~0) return; + ir.EventType = KEY_EVENT; + ir.Event.KeyEvent.bKeyDown = TRUE; + ir.Event.KeyEvent.wRepeatCount = 0; + ir.Event.KeyEvent.wVirtualKeyCode = LOBYTE(sh); + ir.Event.KeyEvent.wVirtualScanCode = MapVirtualKeyW( LOBYTE(sh), 0 ); + ir.Event.KeyEvent.uChar.UnicodeChar = ch; + ir.Event.KeyEvent.dwControlKeyState = 0; + if (lparam & (1u << 24)) ir.Event.KeyEvent.dwControlKeyState |= ENHANCED_KEY; + + write_console_input( console, &ir, 1, TRUE ); +} + static void record_mouse_input( struct console *console, COORD c, WPARAM wparam, DWORD event ) { BYTE key_state[256]; @@ -2124,6 +2143,13 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp record_key_input( console, msg == WM_SYSKEYDOWN, wparam, lparam ); break;
+ case WM_CHAR: + if (console->window && console->window->in_selection) + handle_selection_key( console, TRUE, LOBYTE( VkKeyScanW( (WCHAR)wparam ) ), lparam ); + else + record_char_input( console, (WCHAR)wparam, lparam ); + break; + case WM_LBUTTONDOWN: if (console->window && (console->window->quick_edit || console->window->in_selection)) {
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/conhost/conhost.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 4272e8b12f5..7610cb69c72 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -2841,6 +2841,12 @@ static NTSTATUS process_console_ioctls( struct console *console ) } }
+static BOOL is_key_message( const MSG *msg ) +{ + return msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN || + msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP; +} + static int main_loop( struct console *console, HANDLE signal ) { HANDLE signal_event = NULL; @@ -2875,10 +2881,15 @@ static int main_loop( struct console *console, HANDLE signal ) if (res == WAIT_OBJECT_0 + wait_cnt) { MSG msg; + while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) { + BOOL translated = FALSE; if (msg.message == WM_QUIT) return 0; - DispatchMessageW(&msg); + if (is_key_message( &msg ) && msg.wParam == VK_PROCESSKEY) + translated = TranslateMessage( &msg ); + if (!translated || msg.hwnd != console->win) + DispatchMessageW( &msg ); } continue; }