From 896f0a2fdd7e11a032a462ae585c79a86791e92c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 6 Jan 2025 11:29:38 -0500 Subject: [PATCH] windows: handle WM_POINTERCAPTURECHANGED events, fix maybe-undefined behavior. Fixes #11843. Fixes #11844. --- src/video/windows/SDL_windowsevents.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 54609d03da9ad..b5e39f8a78439 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -94,6 +94,9 @@ #ifndef WM_POINTERLEAVE #define WM_POINTERLEAVE 0x024A #endif +#ifndef WM_POINTERCAPTURECHANGED +#define WM_POINTERCAPTURECHANGED 0x024C +#endif #ifndef WM_UNICHAR #define WM_UNICHAR 0x0109 #endif @@ -1163,18 +1166,17 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara returnCode = 0; } break; + case WM_POINTERCAPTURECHANGED: case WM_POINTERLEAVE: { const UINT32 pointerid = GET_POINTERID_WPARAM(wParam); void *hpointer = (void *) (size_t) pointerid; const SDL_PenID pen = SDL_FindPenByHandle(hpointer); - if (pen == 0) { - break; // not a pen, or not a pen we already knew about. - } - - // if this just left the _window_, we don't care. If this is no longer visible to the tablet, time to remove it! - if (!IS_POINTER_INCONTACT_WPARAM(wParam)) { - SDL_RemovePenDevice(WIN_GetEventTimestamp(), pen); + if (pen != 0) { + // if this just left the _window_, we don't care. If this is no longer visible to the tablet, time to remove it! + if ((msg == WM_POINTERCAPTURECHANGED) || !IS_POINTER_INCONTACT_WPARAM(wParam)) { + SDL_RemovePenDevice(WIN_GetEventTimestamp(), pen); + } } returnCode = 0; } break; @@ -1182,6 +1184,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara case WM_POINTERUPDATE: { POINTER_INPUT_TYPE pointer_type = PT_POINTER; if (!data->videodata->GetPointerType || !data->videodata->GetPointerType(GET_POINTERID_WPARAM(wParam), &pointer_type)) { + returnCode = 0; break; // oh well. } @@ -1195,6 +1198,8 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara case WM_POINTERDOWN: case WM_POINTERUP: { + returnCode = 0; // always mark this event handled, so it doesn't go to DefWindowProc (see #11843). + POINTER_PEN_INFO pen_info; const UINT32 pointerid = GET_POINTERID_WPARAM(wParam); void *hpointer = (void *) (size_t) pointerid; @@ -1242,8 +1247,6 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara if (msg == WM_POINTERDOWN) { SDL_SendPenTouch(timestamp, pen, window, (pen_info.penFlags & PEN_FLAG_INVERTED) != 0, true); } - - returnCode = 0; } break; case WM_MOUSEMOVE: