From 3eb8f35f3bdc7a014b9092985ed4627da9fda2c6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 26 Mar 2024 09:22:00 -0700 Subject: [PATCH] windows: handle the Pause key sequence for raw keyboard input --- src/video/windows/SDL_windowsevents.c | 39 ++++++++++++++++++--------- src/video/windows/SDL_windowsvideo.h | 1 + 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 9794ec4c0..9c690b562 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -601,9 +601,9 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HAND } } else { /* Send relative motion if we didn't warp last frame (had good position data) - We also sometimes get large deltas due to coalesced mouse motion and warping, - so ignore those. - */ + We also sometimes get large deltas due to coalesced mouse motion and warping, + so ignore those. + */ const int MAX_RELATIVE_MOTION = (h / 6); if (SDL_abs(relX) < MAX_RELATIVE_MOTION && SDL_abs(relY) < MAX_RELATIVE_MOTION) { @@ -635,18 +635,31 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_WindowData *data, H return; } - Uint8 state = (rawkeyboard->Flags & RI_KEY_BREAK) ? SDL_RELEASED : SDL_PRESSED; - Uint16 scanCode = rawkeyboard->MakeCode; - if (rawkeyboard->Flags & RI_KEY_E0) { - scanCode |= (0xE0 << 8); - } else if (rawkeyboard->Flags & RI_KEY_E1) { - scanCode |= (0xE1 << 8); + if (rawkeyboard->Flags & RI_KEY_E1) { + // First key in a Ctrl+{key} sequence + data->videodata->pending_E1_key_sequence = SDL_TRUE; + return; } - // Pack scan code into one byte to make the index - Uint8 index = LOBYTE(scanCode) | (HIBYTE(scanCode) ? 0x80 : 0x00); - SDL_Scancode code = windows_scancode_table[index]; - + Uint8 state = (rawkeyboard->Flags & RI_KEY_BREAK) ? SDL_RELEASED : SDL_PRESSED; + SDL_Scancode code; + if (data->videodata->pending_E1_key_sequence) { + if (rawkeyboard->MakeCode == 0x45) { + // Ctrl+NumLock == Pause + code = SDL_SCANCODE_PAUSE; + } else { + // Ctrl+ScrollLock == Break (no SDL scancode?) + code = SDL_SCANCODE_UNKNOWN; + } + data->videodata->pending_E1_key_sequence = SDL_FALSE; + } else { + // The code is in the lower 7 bits, the high bit is set for the E0 prefix + Uint8 index = (Uint8)rawkeyboard->MakeCode; + if (rawkeyboard->Flags & RI_KEY_E0) { + index |= 0x80; + } + code = windows_scancode_table[index]; + } SDL_SendKeyboardKey(timestamp, keyboardID, state, code); } diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h index 10f709f1e..4e959dbd6 100644 --- a/src/video/windows/SDL_windowsvideo.h +++ b/src/video/windows/SDL_windowsvideo.h @@ -408,6 +408,7 @@ struct SDL_VideoData SDL_bool raw_mouse_enabled; SDL_bool raw_keyboard_enabled; + SDL_bool pending_E1_key_sequence; SDL_bool raw_input_enabled; #ifndef SDL_DISABLE_WINDOWS_IME