mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-23 10:53:27 +08:00
Added SDL_HINT_WINDOWS_RAW_KEYBOARD to control whether raw keyboard is enabled on Windows
This commit is contained in:
parent
9095cb64c4
commit
78c7834f90
@ -575,6 +575,7 @@
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsmouse.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsopengl.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsopengles.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsrawinput.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsshape.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsvideo.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsvulkan.h" />
|
||||
@ -835,6 +836,7 @@
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsmouse.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsopengl.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsopengles.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsrawinput.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsshape.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsvideo.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsvulkan.c" />
|
||||
|
@ -211,6 +211,7 @@
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsmouse.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsopengl.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsopengles.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsrawinput.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsshape.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsvideo.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsvulkan.c" />
|
||||
@ -440,6 +441,7 @@
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsmouse.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsopengl.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsopengles.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsrawinput.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsshape.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsvideo.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsvulkan.h" />
|
||||
|
@ -473,6 +473,7 @@
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsmouse.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsopengl.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsopengles.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsrawinput.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsshape.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsvideo.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsvulkan.h" />
|
||||
@ -689,6 +690,7 @@
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsmouse.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsopengl.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsopengles.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsrawinput.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsshape.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsvideo.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsvulkan.c" />
|
||||
|
@ -681,6 +681,9 @@
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsopengl.h">
|
||||
<Filter>video\windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsrawinput.h">
|
||||
<Filter>video\windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\video\windows\SDL_windowsshape.h">
|
||||
<Filter>video\windows</Filter>
|
||||
</ClInclude>
|
||||
@ -1294,6 +1297,9 @@
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsopengles.c">
|
||||
<Filter>video\windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsrawinput.c">
|
||||
<Filter>video\windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowsshape.c">
|
||||
<Filter>video\windows</Filter>
|
||||
</ClCompile>
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
205
src/video/windows/SDL_windowsrawinput.c
Normal file
205
src/video/windows/SDL_windowsrawinput.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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 */
|
29
src/video/windows/SDL_windowsrawinput.h
Normal file
29
src/video/windows/SDL_windowsrawinput.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_ */
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user