Fixed event handle accumulation when the SDL window doesn't have focus
This also fixes a crash on shutdown caused by the raw input thread failing to stopmain
parent
6d37f4798e
commit
af5728b94d
|
@ -534,11 +534,15 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HANDLE hDevice, RAWMOUSE *rawmouse)
|
static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDLE hDevice, RAWMOUSE *rawmouse)
|
||||||
{
|
{
|
||||||
SDL_MouseID mouseID;
|
if (!data->raw_mouse_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!data->videodata->raw_mouse_enabled) {
|
// Relative mouse motion is delivered to the window with keyboard focus
|
||||||
|
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||||
|
if (!window) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,11 +550,12 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HAND
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseID = (SDL_MouseID)(uintptr_t)hDevice;
|
SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)hDevice;
|
||||||
|
SDL_WindowData *windowdata = window->driverdata;
|
||||||
|
|
||||||
if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
|
if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
|
||||||
if (rawmouse->lLastX || rawmouse->lLastY) {
|
if (rawmouse->lLastX || rawmouse->lLastY) {
|
||||||
SDL_SendMouseMotion(timestamp, data->window, mouseID, SDL_TRUE, (float)rawmouse->lLastX, (float)rawmouse->lLastY);
|
SDL_SendMouseMotion(timestamp, window, mouseID, SDL_TRUE, (float)rawmouse->lLastX, (float)rawmouse->lLastY);
|
||||||
}
|
}
|
||||||
} else if (rawmouse->lLastX || rawmouse->lLastY) {
|
} else if (rawmouse->lLastX || rawmouse->lLastY) {
|
||||||
/* This is absolute motion, either using a tablet or mouse over RDP
|
/* This is absolute motion, either using a tablet or mouse over RDP
|
||||||
|
@ -581,7 +586,7 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HAND
|
||||||
relY = y - data->last_raw_mouse_position.y;
|
relY = y - data->last_raw_mouse_position.y;
|
||||||
|
|
||||||
if (remote_desktop) {
|
if (remote_desktop) {
|
||||||
if (!data->in_title_click && !data->focus_click_pending) {
|
if (!windowdata->in_title_click && !windowdata->focus_click_pending) {
|
||||||
static int wobble;
|
static int wobble;
|
||||||
float floatX = (float)x / w;
|
float floatX = (float)x / w;
|
||||||
float floatY = (float)y / h;
|
float floatY = (float)y / h;
|
||||||
|
@ -589,7 +594,7 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HAND
|
||||||
/* See if the mouse is at the edge of the screen, or in the RDP title bar area */
|
/* See if the mouse is at the edge of the screen, or in the RDP title bar area */
|
||||||
if (floatX <= 0.01f || floatX >= 0.99f || floatY <= 0.01f || floatY >= 0.99f || y < 32) {
|
if (floatX <= 0.01f || floatX >= 0.99f || floatY <= 0.01f || floatY >= 0.99f || y < 32) {
|
||||||
/* Wobble the cursor position so it's not ignored if the last warp didn't have any effect */
|
/* Wobble the cursor position so it's not ignored if the last warp didn't have any effect */
|
||||||
RECT rect = data->cursor_clipped_rect;
|
RECT rect = windowdata->cursor_clipped_rect;
|
||||||
int warpX = rect.left + ((rect.right - rect.left) / 2) + wobble;
|
int warpX = rect.left + ((rect.right - rect.left) / 2) + wobble;
|
||||||
int warpY = rect.top + ((rect.bottom - rect.top) / 2);
|
int warpY = rect.top + ((rect.bottom - rect.top) / 2);
|
||||||
|
|
||||||
|
@ -607,7 +612,7 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HAND
|
||||||
const int MAX_RELATIVE_MOTION = (h / 6);
|
const int MAX_RELATIVE_MOTION = (h / 6);
|
||||||
if (SDL_abs(relX) < MAX_RELATIVE_MOTION &&
|
if (SDL_abs(relX) < MAX_RELATIVE_MOTION &&
|
||||||
SDL_abs(relY) < MAX_RELATIVE_MOTION) {
|
SDL_abs(relY) < MAX_RELATIVE_MOTION) {
|
||||||
SDL_SendMouseMotion(timestamp, data->window, mouseID, SDL_TRUE, (float)relX, (float)relY);
|
SDL_SendMouseMotion(timestamp, window, mouseID, SDL_TRUE, (float)relX, (float)relY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -617,33 +622,33 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HAND
|
||||||
SDL_abs(relY) > MAXIMUM_TABLET_RELATIVE_MOTION) {
|
SDL_abs(relY) > MAXIMUM_TABLET_RELATIVE_MOTION) {
|
||||||
/* Ignore this motion, probably a pen lift and drop */
|
/* Ignore this motion, probably a pen lift and drop */
|
||||||
} else {
|
} else {
|
||||||
SDL_SendMouseMotion(timestamp, data->window, mouseID, SDL_TRUE, (float)relX, (float)relY);
|
SDL_SendMouseMotion(timestamp, window, mouseID, SDL_TRUE, (float)relX, (float)relY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data->last_raw_mouse_position.x = x;
|
data->last_raw_mouse_position.x = x;
|
||||||
data->last_raw_mouse_position.y = y;
|
data->last_raw_mouse_position.y = y;
|
||||||
}
|
}
|
||||||
WIN_CheckRawMouseButtons(timestamp, hDevice, rawmouse->usButtonFlags, data, mouseID);
|
WIN_CheckRawMouseButtons(timestamp, hDevice, rawmouse->usButtonFlags, windowdata, mouseID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_WindowData *data, HANDLE hDevice, RAWKEYBOARD *rawkeyboard)
|
static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_VideoData *data, HANDLE hDevice, RAWKEYBOARD *rawkeyboard)
|
||||||
{
|
{
|
||||||
SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)hDevice;
|
SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)hDevice;
|
||||||
|
|
||||||
if (!data->videodata->raw_keyboard_enabled) {
|
if (!data->raw_keyboard_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawkeyboard->Flags & RI_KEY_E1) {
|
if (rawkeyboard->Flags & RI_KEY_E1) {
|
||||||
// First key in a Ctrl+{key} sequence
|
// First key in a Ctrl+{key} sequence
|
||||||
data->videodata->pending_E1_key_sequence = SDL_TRUE;
|
data->pending_E1_key_sequence = SDL_TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8 state = (rawkeyboard->Flags & RI_KEY_BREAK) ? SDL_RELEASED : SDL_PRESSED;
|
Uint8 state = (rawkeyboard->Flags & RI_KEY_BREAK) ? SDL_RELEASED : SDL_PRESSED;
|
||||||
SDL_Scancode code;
|
SDL_Scancode code;
|
||||||
if (data->videodata->pending_E1_key_sequence) {
|
if (data->pending_E1_key_sequence) {
|
||||||
if (rawkeyboard->MakeCode == 0x45) {
|
if (rawkeyboard->MakeCode == 0x45) {
|
||||||
// Ctrl+NumLock == Pause
|
// Ctrl+NumLock == Pause
|
||||||
code = SDL_SCANCODE_PAUSE;
|
code = SDL_SCANCODE_PAUSE;
|
||||||
|
@ -651,7 +656,7 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_WindowData *data, H
|
||||||
// Ctrl+ScrollLock == Break (no SDL scancode?)
|
// Ctrl+ScrollLock == Break (no SDL scancode?)
|
||||||
code = SDL_SCANCODE_UNKNOWN;
|
code = SDL_SCANCODE_UNKNOWN;
|
||||||
}
|
}
|
||||||
data->videodata->pending_E1_key_sequence = SDL_FALSE;
|
data->pending_E1_key_sequence = SDL_FALSE;
|
||||||
} else {
|
} else {
|
||||||
// The code is in the lower 7 bits, the high bit is set for the E0 prefix
|
// The code is in the lower 7 bits, the high bit is set for the E0 prefix
|
||||||
Uint8 index = (Uint8)rawkeyboard->MakeCode;
|
Uint8 index = (Uint8)rawkeyboard->MakeCode;
|
||||||
|
@ -660,26 +665,19 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_WindowData *data, H
|
||||||
}
|
}
|
||||||
code = windows_scancode_table[index];
|
code = windows_scancode_table[index];
|
||||||
}
|
}
|
||||||
|
if (state && !SDL_GetKeyboardFocus()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
SDL_SendKeyboardKey(timestamp, keyboardID, state, code);
|
SDL_SendKeyboardKey(timestamp, keyboardID, state, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN_PollRawInput(SDL_VideoDevice *_this)
|
void WIN_PollRawInput(SDL_VideoDevice *_this)
|
||||||
{
|
{
|
||||||
SDL_Window *window;
|
SDL_VideoData *data = _this->driverdata;
|
||||||
SDL_WindowData *data;
|
|
||||||
UINT size, i, count, total = 0;
|
UINT size, i, count, total = 0;
|
||||||
RAWINPUT *input;
|
RAWINPUT *input;
|
||||||
Uint64 now;
|
Uint64 now;
|
||||||
|
|
||||||
/* Relative mouse motion is delivered to the window with keyboard focus */
|
|
||||||
window = SDL_GetKeyboardFocus();
|
|
||||||
if (!window) {
|
|
||||||
// Clear the queue status so MsgWaitForMultipleObjects() will wait again
|
|
||||||
(void)GetQueueStatus(QS_RAWINPUT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data = window->driverdata;
|
|
||||||
|
|
||||||
if (data->rawinput_offset == 0) {
|
if (data->rawinput_offset == 0) {
|
||||||
BOOL isWow64;
|
BOOL isWow64;
|
||||||
|
|
||||||
|
@ -735,10 +733,10 @@ void WIN_PollRawInput(SDL_VideoDevice *_this)
|
||||||
timestamp += increment;
|
timestamp += increment;
|
||||||
if (input->header.dwType == RIM_TYPEMOUSE) {
|
if (input->header.dwType == RIM_TYPEMOUSE) {
|
||||||
RAWMOUSE *rawmouse = (RAWMOUSE *)((BYTE *)input + data->rawinput_offset);
|
RAWMOUSE *rawmouse = (RAWMOUSE *)((BYTE *)input + data->rawinput_offset);
|
||||||
WIN_HandleRawMouseInput(timestamp, window->driverdata, input->header.hDevice, rawmouse);
|
WIN_HandleRawMouseInput(timestamp, data, input->header.hDevice, rawmouse);
|
||||||
} else if (input->header.dwType == RIM_TYPEKEYBOARD) {
|
} else if (input->header.dwType == RIM_TYPEKEYBOARD) {
|
||||||
RAWKEYBOARD *rawkeyboard = (RAWKEYBOARD *)((BYTE *)input + data->rawinput_offset);
|
RAWKEYBOARD *rawkeyboard = (RAWKEYBOARD *)((BYTE *)input + data->rawinput_offset);
|
||||||
WIN_HandleRawKeyboardInput(timestamp, window->driverdata, input->header.hDevice, rawkeyboard);
|
WIN_HandleRawKeyboardInput(timestamp, data, input->header.hDevice, rawkeyboard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,14 @@
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
SDL_bool done;
|
||||||
HANDLE ready_event;
|
HANDLE ready_event;
|
||||||
HANDLE done_event;
|
HANDLE done_event;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
} RawInputThreadData;
|
} RawInputThreadData;
|
||||||
|
|
||||||
static RawInputThreadData thread_data = {
|
static RawInputThreadData thread_data = {
|
||||||
|
SDL_FALSE,
|
||||||
INVALID_HANDLE_VALUE,
|
INVALID_HANDLE_VALUE,
|
||||||
INVALID_HANDLE_VALUE,
|
INVALID_HANDLE_VALUE,
|
||||||
INVALID_HANDLE_VALUE
|
INVALID_HANDLE_VALUE
|
||||||
|
@ -76,8 +78,8 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param)
|
||||||
/* Tell the parent we're ready to go! */
|
/* Tell the parent we're ready to go! */
|
||||||
SetEvent(data->ready_event);
|
SetEvent(data->ready_event);
|
||||||
|
|
||||||
for ( ; ; ) {
|
while (!data->done) {
|
||||||
if (MsgWaitForMultipleObjects(1, &data->done_event, 0, INFINITE, QS_RAWINPUT) != WAIT_OBJECT_0 + 1) {
|
if (MsgWaitForMultipleObjects(1, &data->done_event, FALSE, INFINITE, QS_RAWINPUT) != (WAIT_OBJECT_0 + 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +98,9 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param)
|
||||||
static void CleanupRawInputThreadData(RawInputThreadData *data)
|
static void CleanupRawInputThreadData(RawInputThreadData *data)
|
||||||
{
|
{
|
||||||
if (data->thread != INVALID_HANDLE_VALUE) {
|
if (data->thread != INVALID_HANDLE_VALUE) {
|
||||||
|
data->done = SDL_TRUE;
|
||||||
SetEvent(data->done_event);
|
SetEvent(data->done_event);
|
||||||
WaitForSingleObject(data->thread, 500);
|
WaitForSingleObject(data->thread, 3000);
|
||||||
CloseHandle(data->thread);
|
CloseHandle(data->thread);
|
||||||
data->thread = INVALID_HANDLE_VALUE;
|
data->thread = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +129,7 @@ static int WIN_SetRawInputEnabled(SDL_VideoDevice *_this, SDL_bool enabled)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_data.done = SDL_FALSE;
|
||||||
thread_data.done_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
thread_data.done_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
if (thread_data.done_event == INVALID_HANDLE_VALUE) {
|
if (thread_data.done_event == INVALID_HANDLE_VALUE) {
|
||||||
WIN_SetError("CreateEvent");
|
WIN_SetError("CreateEvent");
|
||||||
|
|
|
@ -107,6 +107,7 @@ static void WIN_DeleteDevice(SDL_VideoDevice *device)
|
||||||
if (device->wakeup_lock) {
|
if (device->wakeup_lock) {
|
||||||
SDL_DestroyMutex(device->wakeup_lock);
|
SDL_DestroyMutex(device->wakeup_lock);
|
||||||
}
|
}
|
||||||
|
SDL_free(device->driverdata->rawinput);
|
||||||
SDL_free(device->driverdata);
|
SDL_free(device->driverdata);
|
||||||
SDL_free(device);
|
SDL_free(device);
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,6 +406,12 @@ struct SDL_VideoData
|
||||||
|
|
||||||
SDL_bool cleared;
|
SDL_bool cleared;
|
||||||
|
|
||||||
|
BYTE *rawinput;
|
||||||
|
UINT rawinput_offset;
|
||||||
|
UINT rawinput_size;
|
||||||
|
UINT rawinput_count;
|
||||||
|
Uint64 last_rawinput_poll;
|
||||||
|
SDL_Point last_raw_mouse_position;
|
||||||
SDL_bool raw_mouse_enabled;
|
SDL_bool raw_mouse_enabled;
|
||||||
SDL_bool raw_keyboard_enabled;
|
SDL_bool raw_keyboard_enabled;
|
||||||
SDL_bool pending_E1_key_sequence;
|
SDL_bool pending_E1_key_sequence;
|
||||||
|
|
|
@ -587,9 +587,6 @@ static void CleanupWindowData(SDL_VideoDevice *_this, SDL_Window *window)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
|
||||||
SDL_free(data->rawinput);
|
|
||||||
#endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
|
|
||||||
SDL_free(data);
|
SDL_free(data);
|
||||||
}
|
}
|
||||||
window->driverdata = NULL;
|
window->driverdata = NULL;
|
||||||
|
|
|
@ -69,14 +69,6 @@ struct SDL_WindowData
|
||||||
RECT cursor_clipped_rect;
|
RECT cursor_clipped_rect;
|
||||||
UINT windowed_mode_corner_rounding;
|
UINT windowed_mode_corner_rounding;
|
||||||
COLORREF dwma_border_color;
|
COLORREF dwma_border_color;
|
||||||
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
|
||||||
BYTE *rawinput;
|
|
||||||
UINT rawinput_offset;
|
|
||||||
UINT rawinput_size;
|
|
||||||
UINT rawinput_count;
|
|
||||||
Uint64 last_rawinput_poll;
|
|
||||||
#endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
|
|
||||||
SDL_Point last_raw_mouse_position;
|
|
||||||
SDL_bool mouse_tracked;
|
SDL_bool mouse_tracked;
|
||||||
SDL_bool destroy_parent_with_window;
|
SDL_bool destroy_parent_with_window;
|
||||||
SDL_DisplayID last_displayID;
|
SDL_DisplayID last_displayID;
|
||||||
|
|
Loading…
Reference in New Issue