From 78c7834f90a2250896862f1a44aa05f00dc7befb Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 25 Mar 2024 14:46:31 -0700 Subject: [PATCH] Added SDL_HINT_WINDOWS_RAW_KEYBOARD to control whether raw keyboard is enabled on Windows --- VisualC-GDK/SDL/SDL.vcxproj | 2 + VisualC-GDK/SDL/SDL.vcxproj.filters | 2 + VisualC/SDL/SDL.vcxproj | 2 + VisualC/SDL/SDL.vcxproj.filters | 6 + include/SDL3/SDL_hints.h | 33 ++-- src/video/windows/SDL_windowsevents.c | 26 ++- src/video/windows/SDL_windowsmouse.c | 159 +----------------- src/video/windows/SDL_windowsrawinput.c | 205 ++++++++++++++++++++++++ src/video/windows/SDL_windowsrawinput.h | 29 ++++ src/video/windows/SDL_windowsvideo.c | 19 ++- src/video/windows/SDL_windowsvideo.h | 4 +- 11 files changed, 301 insertions(+), 186 deletions(-) create mode 100644 src/video/windows/SDL_windowsrawinput.c create mode 100644 src/video/windows/SDL_windowsrawinput.h diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj index 6b7c093e1..6614442e5 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj +++ b/VisualC-GDK/SDL/SDL.vcxproj @@ -575,6 +575,7 @@ + @@ -835,6 +836,7 @@ + diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters index 09c467159..722b2ed3c 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj.filters +++ b/VisualC-GDK/SDL/SDL.vcxproj.filters @@ -211,6 +211,7 @@ + @@ -440,6 +441,7 @@ + diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index ec15d4ea8..7cc840594 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -473,6 +473,7 @@ + @@ -689,6 +690,7 @@ + diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index b70f19667..77b54b847 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -681,6 +681,9 @@ video\windows + + video\windows + video\windows @@ -1294,6 +1297,9 @@ video\windows + + video\windows + video\windows diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index 6357056c3..065b1b319 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -2380,6 +2380,17 @@ extern "C" { */ #define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" +/** + * A variable controlling whether SDL generates window-close events for Alt+F4 on Windows. + * + * The variable can be set to the following values: + * "0" - SDL will only do normal key handling for Alt+F4. + * "1" - SDL will generate a window-close event when it sees Alt+F4. (default) + * + * This hint can be set anytime. + */ +#define SDL_HINT_WINDOWS_CLOSE_ON_ALT_F4 "SDL_WINDOWS_CLOSE_ON_ALT_F4" + /** * A variable controlling whether menus can be opened with their keyboard shortcut (Alt+mnemonic). * @@ -2408,6 +2419,17 @@ extern "C" { */ #define SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP "SDL_WINDOWS_ENABLE_MESSAGELOOP" +/** + * A variable controlling whether raw keyboard events are used on Windows + * + * The variable can be set to the following values: + * "0" - The Windows message loop is used for keyboard events. + * "1" - Low latency raw keyboard events are used. (default) + * + * This hint can be set anytime. + */ +#define SDL_HINT_WINDOWS_RAW_KEYBOARD "SDL_WINDOWS_RAW_KEYBOARD" + /** * A variable controlling whether SDL uses Critical Sections for mutexes on Windows. * @@ -2442,17 +2464,6 @@ extern "C" { #define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON" #define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL" -/** - * A variable controlling whether SDL generates window-close events for Alt+F4 on Windows. - * - * The variable can be set to the following values: - * "0" - SDL will only do normal key handling for Alt+F4. - * "1" - SDL will generate a window-close event when it sees Alt+F4. (default) - * - * This hint can be set anytime. - */ -#define SDL_HINT_WINDOWS_CLOSE_ON_ALT_F4 "SDL_WINDOWS_CLOSE_ON_ALT_F4" - /** * A variable controlling whether SDL uses the D3D9Ex API introduced in Windows Vista, instead of normal D3D9. * diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index b7c8af674..81be09e52 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -512,11 +512,11 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) } if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) { - if (data->raw_input_enable_count == 0) { + if (!data->raw_keyboard_enabled) { SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, SDL_PRESSED, scanCode); } } else { - if (data->raw_input_enable_count == 0) { + if (!data->raw_keyboard_enabled) { SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, SDL_RELEASED, scanCode); } @@ -536,11 +536,9 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HANDLE hDevice, RAWMOUSE *rawmouse) { - SDL_Mouse *mouse = SDL_GetMouse(); SDL_MouseID mouseID; - /* We only use raw mouse input in relative mode */ - if (!mouse->relative_mode || mouse->relative_mode_warp) { + if (!data->videodata->raw_mouse_enabled) { return; } @@ -633,6 +631,10 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_WindowData *data, H { SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)hDevice; + if (!data->videodata->raw_keyboard_enabled) { + return; + } + Uint8 state = (rawkeyboard->Flags & RI_KEY_BREAK) ? SDL_RELEASED : SDL_PRESSED; Uint16 scanCode = rawkeyboard->MakeCode; if (rawkeyboard->Flags & RI_KEY_E0) { @@ -656,10 +658,6 @@ void WIN_PollRawInput(SDL_VideoDevice *_this) RAWINPUT *input; Uint64 now; - if (_this->driverdata->raw_input_enable_count == 0) { - return; - } - /* Relative mouse motion is delivered to the window with keyboard focus */ window = SDL_GetKeyboardFocus(); if (!window) { @@ -905,8 +903,8 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, SDL_bool initial_c } SDL_free(old_keyboards); - SDL_free(old_mice); SDL_free(new_keyboards); + SDL_free(old_mice); SDL_free(new_mice); SetupDiDestroyDeviceInfoList(devinfo); @@ -1058,10 +1056,6 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara RAWINPUT inp; UINT size = sizeof(inp); - if (data->raw_input_enable_count == 0) { - break; - } - /* Relative mouse motion is delivered to the window with keyboard focus */ if (data->window != SDL_GetKeyboardFocus()) { break; @@ -1135,7 +1129,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara } } - if (data->videodata->raw_input_enable_count == 0 && code != SDL_SCANCODE_UNKNOWN) { + if (!data->videodata->raw_keyboard_enabled && code != SDL_SCANCODE_UNKNOWN) { SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_GLOBAL_KEYBOARD_ID, SDL_PRESSED, code); } } @@ -1149,7 +1143,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam); const Uint8 *keyboardState = SDL_GetKeyboardState(NULL); - if (data->videodata->raw_input_enable_count == 0 && code != SDL_SCANCODE_UNKNOWN) { + if (!data->videodata->raw_keyboard_enabled && code != SDL_SCANCODE_UNKNOWN) { if (code == SDL_SCANCODE_PRINTSCREEN && keyboardState[code] == SDL_RELEASED) { SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_GLOBAL_KEYBOARD_ID, SDL_PRESSED, code); diff --git a/src/video/windows/SDL_windowsmouse.c b/src/video/windows/SDL_windowsmouse.c index 74ddae624..657c49815 100644 --- a/src/video/windows/SDL_windowsmouse.c +++ b/src/video/windows/SDL_windowsmouse.c @@ -24,6 +24,7 @@ #include "SDL_windowsvideo.h" #include "SDL_windowsevents.h" +#include "SDL_windowsrawinput.h" #include "../SDL_video_c.h" #include "../../events/SDL_mouse_c.h" @@ -33,156 +34,6 @@ DWORD SDL_last_warp_time = 0; HCURSOR SDL_cursor = NULL; static SDL_Cursor *SDL_blank_cursor = NULL; -typedef struct -{ - HANDLE ready_event; - HANDLE done_event; - HANDLE thread; -} RawInputThreadData; - -static RawInputThreadData thread_data = { - INVALID_HANDLE_VALUE, - INVALID_HANDLE_VALUE, - INVALID_HANDLE_VALUE -}; - -static DWORD WINAPI WIN_RawInputThread(LPVOID param) -{ - SDL_VideoDevice *_this = SDL_GetVideoDevice(); - RawInputThreadData *data = (RawInputThreadData *)param; - RAWINPUTDEVICE devices[2]; - HWND window; - - window = CreateWindowEx(0, TEXT("Message"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); - if (!window) { - return 0; - } - - devices[0].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; - devices[0].usUsage = USB_USAGE_GENERIC_MOUSE; - devices[0].dwFlags = 0; - devices[0].hwndTarget = window; - - devices[1].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; - devices[1].usUsage = USB_USAGE_GENERIC_KEYBOARD; - devices[1].dwFlags = 0; - devices[1].hwndTarget = window; - - if (!RegisterRawInputDevices(devices, SDL_arraysize(devices), sizeof(devices[0]))) { - DestroyWindow(window); - return 0; - } - - /* Make sure we get events as soon as possible */ - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - - /* Tell the parent we're ready to go! */ - SetEvent(data->ready_event); - - for ( ; ; ) { - if (MsgWaitForMultipleObjects(1, &data->done_event, 0, INFINITE, QS_RAWINPUT) != WAIT_OBJECT_0 + 1) { - break; - } - - /* Clear the queue status so MsgWaitForMultipleObjects() will wait again */ - (void)GetQueueStatus(QS_RAWINPUT); - - WIN_PollRawInput(_this); - } - - devices[0].dwFlags |= RIDEV_REMOVE; - devices[1].dwFlags |= RIDEV_REMOVE; - RegisterRawInputDevices(devices, SDL_arraysize(devices), sizeof(devices[0])); - - DestroyWindow(window); - - return 0; -} - -static void CleanupRawInputThreadData(RawInputThreadData *data) -{ - if (data->thread != INVALID_HANDLE_VALUE) { - SetEvent(data->done_event); - WaitForSingleObject(data->thread, 500); - CloseHandle(data->thread); - data->thread = INVALID_HANDLE_VALUE; - } - - if (data->ready_event != INVALID_HANDLE_VALUE) { - CloseHandle(data->ready_event); - data->ready_event = INVALID_HANDLE_VALUE; - } - - if (data->done_event != INVALID_HANDLE_VALUE) { - CloseHandle(data->done_event); - data->done_event = INVALID_HANDLE_VALUE; - } -} - -static int ToggleRawInput(SDL_VideoDevice *_this, SDL_bool enabled) -{ - SDL_VideoData *data = _this->driverdata; - int result = -1; - - if (enabled) { - ++data->raw_input_enable_count; - if (data->raw_input_enable_count > 1) { - return 0; /* already done. */ - } - } else { - if (data->raw_input_enable_count == 0) { - return 0; /* already done. */ - } - --data->raw_input_enable_count; - if (data->raw_input_enable_count > 0) { - return 0; /* not time to disable yet */ - } - } - - if (enabled) { - HANDLE handles[2]; - - thread_data.ready_event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (thread_data.ready_event == INVALID_HANDLE_VALUE) { - WIN_SetError("CreateEvent"); - goto done; - } - - thread_data.done_event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (thread_data.done_event == INVALID_HANDLE_VALUE) { - WIN_SetError("CreateEvent"); - goto done; - } - - thread_data.thread = CreateThread(NULL, 0, WIN_RawInputThread, &thread_data, 0, NULL); - if (thread_data.thread == INVALID_HANDLE_VALUE) { - WIN_SetError("CreateThread"); - goto done; - } - - /* Wait for the thread to signal ready or exit */ - handles[0] = thread_data.ready_event; - handles[1] = thread_data.thread; - if (WaitForMultipleObjects(2, handles, FALSE, INFINITE) != WAIT_OBJECT_0) { - SDL_SetError("Couldn't set up raw input handling"); - goto done; - } - result = 0; - } else { - CleanupRawInputThreadData(&thread_data); - result = 0; - } - -done: - if (enabled && result < 0) { - CleanupRawInputThreadData(&thread_data); - - /* Reset so we can try again */ - data->raw_input_enable_count = 0; - } - return result; -} - static SDL_Cursor *WIN_CreateDefaultCursor() { SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor)); @@ -516,7 +367,7 @@ static int WIN_WarpMouseGlobal(float x, float y) static int WIN_SetRelativeMouseMode(SDL_bool enabled) { - return ToggleRawInput(SDL_GetVideoDevice(), enabled); + return WIN_SetRawMouseEnabled(SDL_GetVideoDevice(), enabled); } static int WIN_CaptureMouse(SDL_Window *window) @@ -581,12 +432,6 @@ void WIN_InitMouse(SDL_VideoDevice *_this) void WIN_QuitMouse(SDL_VideoDevice *_this) { - SDL_VideoData *data = _this->driverdata; - if (data->raw_input_enable_count) { /* force RAWINPUT off here. */ - data->raw_input_enable_count = 1; - ToggleRawInput(_this, SDL_FALSE); - } - if (SDL_blank_cursor) { WIN_FreeCursor(SDL_blank_cursor); SDL_blank_cursor = NULL; diff --git a/src/video/windows/SDL_windowsrawinput.c b/src/video/windows/SDL_windowsrawinput.c new file mode 100644 index 000000000..9c63c8e2a --- /dev/null +++ b/src/video/windows/SDL_windowsrawinput.c @@ -0,0 +1,205 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + +#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) + +#include "SDL_windowsvideo.h" +#include "SDL_windowsevents.h" + +#include "../../joystick/usb_ids.h" + +typedef struct +{ + HANDLE ready_event; + HANDLE done_event; + HANDLE thread; +} RawInputThreadData; + +static RawInputThreadData thread_data = { + INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE +}; + +static DWORD WINAPI WIN_RawInputThread(LPVOID param) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + RawInputThreadData *data = (RawInputThreadData *)param; + RAWINPUTDEVICE devices[2]; + HWND window; + + window = CreateWindowEx(0, TEXT("Message"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); + if (!window) { + return 0; + } + + devices[0].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; + devices[0].usUsage = USB_USAGE_GENERIC_MOUSE; + devices[0].dwFlags = 0; + devices[0].hwndTarget = window; + + devices[1].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; + devices[1].usUsage = USB_USAGE_GENERIC_KEYBOARD; + devices[1].dwFlags = 0; + devices[1].hwndTarget = window; + + if (!RegisterRawInputDevices(devices, SDL_arraysize(devices), sizeof(devices[0]))) { + DestroyWindow(window); + return 0; + } + + /* Make sure we get events as soon as possible */ + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + + /* Tell the parent we're ready to go! */ + SetEvent(data->ready_event); + + for ( ; ; ) { + if (MsgWaitForMultipleObjects(1, &data->done_event, 0, INFINITE, QS_RAWINPUT) != WAIT_OBJECT_0 + 1) { + break; + } + + /* Clear the queue status so MsgWaitForMultipleObjects() will wait again */ + (void)GetQueueStatus(QS_RAWINPUT); + + WIN_PollRawInput(_this); + } + + devices[0].dwFlags |= RIDEV_REMOVE; + devices[1].dwFlags |= RIDEV_REMOVE; + RegisterRawInputDevices(devices, SDL_arraysize(devices), sizeof(devices[0])); + + DestroyWindow(window); + + return 0; +} + +static void CleanupRawInputThreadData(RawInputThreadData *data) +{ + if (data->thread != INVALID_HANDLE_VALUE) { + SetEvent(data->done_event); + WaitForSingleObject(data->thread, 500); + CloseHandle(data->thread); + data->thread = INVALID_HANDLE_VALUE; + } + + if (data->ready_event != INVALID_HANDLE_VALUE) { + CloseHandle(data->ready_event); + data->ready_event = INVALID_HANDLE_VALUE; + } + + if (data->done_event != INVALID_HANDLE_VALUE) { + CloseHandle(data->done_event); + data->done_event = INVALID_HANDLE_VALUE; + } +} + +static int WIN_SetRawInputEnabled(SDL_VideoDevice *_this, SDL_bool enabled) +{ + int result = -1; + + if (enabled) { + HANDLE handles[2]; + + thread_data.ready_event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (thread_data.ready_event == INVALID_HANDLE_VALUE) { + WIN_SetError("CreateEvent"); + goto done; + } + + thread_data.done_event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (thread_data.done_event == INVALID_HANDLE_VALUE) { + WIN_SetError("CreateEvent"); + goto done; + } + + thread_data.thread = CreateThread(NULL, 0, WIN_RawInputThread, &thread_data, 0, NULL); + if (thread_data.thread == INVALID_HANDLE_VALUE) { + WIN_SetError("CreateThread"); + goto done; + } + + /* Wait for the thread to signal ready or exit */ + handles[0] = thread_data.ready_event; + handles[1] = thread_data.thread; + if (WaitForMultipleObjects(2, handles, FALSE, INFINITE) != WAIT_OBJECT_0) { + SDL_SetError("Couldn't set up raw input handling"); + goto done; + } + result = 0; + } else { + CleanupRawInputThreadData(&thread_data); + result = 0; + } + +done: + if (enabled && result < 0) { + CleanupRawInputThreadData(&thread_data); + } + return result; +} + +static int WIN_UpdateRawInputEnabled(SDL_VideoDevice *_this) +{ + SDL_VideoData *data = _this->driverdata; + SDL_bool enabled = (data->raw_mouse_enabled || data->raw_keyboard_enabled); + if (enabled != data->raw_input_enabled) { + if (WIN_SetRawInputEnabled(_this, enabled) == 0) { + data->raw_input_enabled = enabled; + } else { + return -1; + } + } + return 0; +} + +int WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, SDL_bool enabled) +{ + SDL_VideoData *data = _this->driverdata; + data->raw_mouse_enabled = enabled; + return WIN_UpdateRawInputEnabled(_this); +} + +int WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, SDL_bool enabled) +{ + SDL_VideoData *data = _this->driverdata; + data->raw_keyboard_enabled = enabled; + return WIN_UpdateRawInputEnabled(_this); +} + +#else + +int WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +int WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +#endif /* !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES */ + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */ diff --git a/src/video/windows/SDL_windowsrawinput.h b/src/video/windows/SDL_windowsrawinput.h new file mode 100644 index 000000000..1ace79662 --- /dev/null +++ b/src/video/windows/SDL_windowsrawinput.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifndef SDL_windowsrawinput_h_ +#define SDL_windowsrawinput_h_ + +extern int WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, SDL_bool enabled); +extern int WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, SDL_bool enabled); + +#endif /* SDL_windowsrawinput_h_ */ diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 368cbb024..d77d71f0f 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -32,8 +32,9 @@ #include "SDL_windowsvideo.h" #include "SDL_windowsframebuffer.h" -#include "SDL_windowsvulkan.h" #include "SDL_windowsmessagebox.h" +#include "SDL_windowsrawinput.h" +#include "SDL_windowsvulkan.h" #ifdef SDL_GDK_TEXTINPUT #include "../gdk/SDL_gdktextinput.h" @@ -50,6 +51,13 @@ SDL_bool g_WindowsEnableMessageLoop = SDL_TRUE; SDL_bool g_WindowsEnableMenuMnemonics = SDL_FALSE; SDL_bool g_WindowFrameUsableWhileCursorHidden = SDL_TRUE; +static void SDLCALL UpdateWindowsRawKeyboard(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + SDL_VideoDevice *_this = (SDL_VideoDevice *)userdata; + SDL_bool enabled = SDL_GetStringBoolean(newValue, SDL_TRUE); + WIN_SetRawKeyboardEnabled(_this, enabled); +} + static void SDLCALL UpdateWindowsEnableMessageLoop(void *userdata, const char *name, const char *oldValue, const char *newValue) { g_WindowsEnableMessageLoop = SDL_GetStringBoolean(newValue, SDL_TRUE); @@ -458,6 +466,7 @@ int WIN_VideoInit(SDL_VideoDevice *_this) WIN_CheckKeyboardAndMouseHotplug(_this, SDL_TRUE); #endif + SDL_AddHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this); SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL); SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL); SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL); @@ -477,6 +486,14 @@ void WIN_VideoQuit(SDL_VideoDevice *_this) WIN_QuitKeyboard(_this); WIN_QuitMouse(_this); #endif + + SDL_DelHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this); + SDL_DelHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL); + SDL_DelHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL); + SDL_DelHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL); + + WIN_SetRawMouseEnabled(_this, SDL_FALSE); + WIN_SetRawKeyboardEnabled(_this, SDL_FALSE); } #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h index 9dbcc0100..10f709f1e 100644 --- a/src/video/windows/SDL_windowsvideo.h +++ b/src/video/windows/SDL_windowsvideo.h @@ -406,7 +406,9 @@ struct SDL_VideoData SDL_bool cleared; - int raw_input_enable_count; + SDL_bool raw_mouse_enabled; + SDL_bool raw_keyboard_enabled; + SDL_bool raw_input_enabled; #ifndef SDL_DISABLE_WINDOWS_IME SDL_bool ime_com_initialized;