# HG changeset patch # User David Ludwig # Date 1419093939 18000 # Sat Dec 20 11:45:39 2014 -0500 # Node ID 17230d3d7a81011b8fed1a49ea8e990ad212b967 # Parent 2b2cfda260855c47cfc2fb7e61e2a43027394562 Partial fix for bug 2726 - Win32 'mouse' events not applying 'SDL_TOUCH_MOUSEID' This is a Win32-specific fix for bug 2726. A WinRT fix for this bug was applied separately, via https://hg.libsdl.org/SDL/rev/bea2e725e29a This fix applies SDL_TOUCH_MOUSEID to 'mouse' events coming from touch devices, but only when relative-mouse-mode is turned OFF. This bug is still present when relative-mouse-mode is ON, however Microsoft does not provide documentation on whether or not those input events (which come from WM_INPUT) can be identified as touch-specific or not. Unofficially, that data might be available (via GetMessageExtraInfo()), however this patch only uses MS-documented APIs. diff -r 2b2cfda26085 -r 17230d3d7a81 src/video/windows/SDL_windowsevents.c --- a/src/video/windows/SDL_windowsevents.c Sat Dec 13 13:20:19 2014 -0800 +++ b/src/video/windows/SDL_windowsevents.c Sat Dec 20 11:45:39 2014 -0500 @@ -44,6 +44,9 @@ #include "wmmsg.h" #endif +/* For processing mouse WM_*BUTTON* and WM_MOUSEMOVE message-data from GetMessageExtraInfo() */ +#define MOUSEEVENTF_FROMTOUCH 0xFF515700 + /* Masks for processing the windows KEYDOWN and KEYUP messages */ #define REPEATED_KEYMASK (1<<30) #define EXTENDED_KEYMASK (1<<24) @@ -195,7 +198,7 @@ void -WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button) +WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID) { if (data->focus_click_pending && button == SDL_BUTTON_LEFT && !bwParamMousePressed) { data->focus_click_pending = SDL_FALSE; @@ -203,9 +206,9 @@ } if (bwParamMousePressed && !bSDLMousePressed) { - SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button); + SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button); } else if (!bwParamMousePressed && bSDLMousePressed) { - SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button); + SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button); } } @@ -214,15 +217,15 @@ * so this funciton reconciles our view of the world with the current buttons reported by windows */ void -WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data) +WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mouseID) { if (wParam != data->mouse_button_flags) { Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL); - WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT); - WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE); - WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT); - WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1); - WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2); + WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, mouseID); + WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, mouseID); + WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, mouseID); + WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, mouseID); + WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, mouseID); data->mouse_button_flags = wParam; } } @@ -234,25 +237,25 @@ if (rawButtons != data->mouse_button_flags) { Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL); if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0); if ((rawButtons & RI_MOUSE_BUTTON_1_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0); if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0); if ((rawButtons & RI_MOUSE_BUTTON_2_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0); if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0); if ((rawButtons & RI_MOUSE_BUTTON_3_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0); if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0); if ((rawButtons & RI_MOUSE_BUTTON_4_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0); if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN)) - WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2); + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0); if ((rawButtons & RI_MOUSE_BUTTON_5_UP)) - WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2); + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0); data->mouse_button_flags = rawButtons; } } @@ -270,23 +273,23 @@ keyState = GetAsyncKeyState(VK_LBUTTON); if (!(keyState & 0x8000)) { - WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT); + WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0); } keyState = GetAsyncKeyState(VK_RBUTTON); if (!(keyState & 0x8000)) { - WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT); + WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0); } keyState = GetAsyncKeyState(VK_MBUTTON); if (!(keyState & 0x8000)) { - WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE); + WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0); } keyState = GetAsyncKeyState(VK_XBUTTON1); if (!(keyState & 0x8000)) { - WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1); + WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0); } keyState = GetAsyncKeyState(VK_XBUTTON2); if (!(keyState & 0x8000)) { - WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2); + WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0); } data->mouse_button_flags = 0; } @@ -409,7 +412,8 @@ { SDL_Mouse *mouse = SDL_GetMouse(); if (!mouse->relative_mode || mouse->relative_mode_warp) { - SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0); + SDL_SendMouseMotion(data->window, mouseID, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); } } /* don't break here, fall through to check the wParam like the button presses */ @@ -428,7 +432,8 @@ { SDL_Mouse *mouse = SDL_GetMouse(); if (!mouse->relative_mode || mouse->relative_mode_warp) { - WIN_CheckWParamMouseButtons(wParam, data); + SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0); + WIN_CheckWParamMouseButtons(wParam, data, mouseID); } } break;