diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 5a770161ca..ba12c3ff33 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -534,11 +534,15 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) 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; } @@ -546,11 +550,12 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HAND 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->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) { /* 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; if (remote_desktop) { - if (!data->in_title_click && !data->focus_click_pending) { + if (!windowdata->in_title_click && !windowdata->focus_click_pending) { static int wobble; float floatX = (float)x / w; 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 */ 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 */ - RECT rect = data->cursor_clipped_rect; + RECT rect = windowdata->cursor_clipped_rect; int warpX = rect.left + ((rect.right - rect.left) / 2) + wobble; 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); if (SDL_abs(relX) < 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) { /* Ignore this motion, probably a pen lift and drop */ } 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.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; - if (!data->videodata->raw_keyboard_enabled) { + if (!data->raw_keyboard_enabled) { return; } if (rawkeyboard->Flags & RI_KEY_E1) { // First key in a Ctrl+{key} sequence - data->videodata->pending_E1_key_sequence = SDL_TRUE; + data->pending_E1_key_sequence = SDL_TRUE; return; } Uint8 state = (rawkeyboard->Flags & RI_KEY_BREAK) ? SDL_RELEASED : SDL_PRESSED; SDL_Scancode code; - if (data->videodata->pending_E1_key_sequence) { + if (data->pending_E1_key_sequence) { if (rawkeyboard->MakeCode == 0x45) { // Ctrl+NumLock == 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?) code = SDL_SCANCODE_UNKNOWN; } - data->videodata->pending_E1_key_sequence = SDL_FALSE; + data->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; @@ -660,26 +665,19 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_WindowData *data, H } code = windows_scancode_table[index]; } + if (state && !SDL_GetKeyboardFocus()) { + return; + } SDL_SendKeyboardKey(timestamp, keyboardID, state, code); } void WIN_PollRawInput(SDL_VideoDevice *_this) { - SDL_Window *window; - SDL_WindowData *data; + SDL_VideoData *data = _this->driverdata; UINT size, i, count, total = 0; RAWINPUT *input; 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) { BOOL isWow64; @@ -735,10 +733,10 @@ void WIN_PollRawInput(SDL_VideoDevice *_this) timestamp += increment; if (input->header.dwType == RIM_TYPEMOUSE) { 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) { 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); } } } diff --git a/src/video/windows/SDL_windowsrawinput.c b/src/video/windows/SDL_windowsrawinput.c index fe34f6ff9b..e53451a0a1 100644 --- a/src/video/windows/SDL_windowsrawinput.c +++ b/src/video/windows/SDL_windowsrawinput.c @@ -32,12 +32,14 @@ typedef struct { + SDL_bool done; HANDLE ready_event; HANDLE done_event; HANDLE thread; } RawInputThreadData; static RawInputThreadData thread_data = { + SDL_FALSE, 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! */ SetEvent(data->ready_event); - for ( ; ; ) { - if (MsgWaitForMultipleObjects(1, &data->done_event, 0, INFINITE, QS_RAWINPUT) != WAIT_OBJECT_0 + 1) { + while (!data->done) { + if (MsgWaitForMultipleObjects(1, &data->done_event, FALSE, INFINITE, QS_RAWINPUT) != (WAIT_OBJECT_0 + 1)) { break; } @@ -96,8 +98,9 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param) static void CleanupRawInputThreadData(RawInputThreadData *data) { if (data->thread != INVALID_HANDLE_VALUE) { + data->done = SDL_TRUE; SetEvent(data->done_event); - WaitForSingleObject(data->thread, 500); + WaitForSingleObject(data->thread, 3000); CloseHandle(data->thread); data->thread = INVALID_HANDLE_VALUE; } @@ -126,6 +129,7 @@ static int WIN_SetRawInputEnabled(SDL_VideoDevice *_this, SDL_bool enabled) goto done; } + thread_data.done = SDL_FALSE; thread_data.done_event = CreateEvent(NULL, FALSE, FALSE, NULL); if (thread_data.done_event == INVALID_HANDLE_VALUE) { WIN_SetError("CreateEvent"); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index d77d71f0fb..32b42ce725 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -107,6 +107,7 @@ static void WIN_DeleteDevice(SDL_VideoDevice *device) if (device->wakeup_lock) { SDL_DestroyMutex(device->wakeup_lock); } + SDL_free(device->driverdata->rawinput); SDL_free(device->driverdata); SDL_free(device); } diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h index 4e959dbd66..390e2a68fb 100644 --- a/src/video/windows/SDL_windowsvideo.h +++ b/src/video/windows/SDL_windowsvideo.h @@ -406,6 +406,12 @@ struct SDL_VideoData 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_keyboard_enabled; SDL_bool pending_E1_key_sequence; diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 30f92628e6..78171f7e7a 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -587,9 +587,6 @@ static void CleanupWindowData(SDL_VideoDevice *_this, SDL_Window *window) #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); } window->driverdata = NULL; diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h index 9cd8e52a00..e2811d8dee 100644 --- a/src/video/windows/SDL_windowswindow.h +++ b/src/video/windows/SDL_windowswindow.h @@ -69,14 +69,6 @@ struct SDL_WindowData RECT cursor_clipped_rect; UINT windowed_mode_corner_rounding; 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 destroy_parent_with_window; SDL_DisplayID last_displayID;