Partial fix for bug 2726 - Win32 'mouse' events not applying 'SDL_TOUCH_MOUSEID'
authorDavid Ludwig <dludwig@pobox.com>
Sat, 20 Dec 2014 11:45:39 -0500
changeset 96686ab4d6f34afb
parent 9667 e55dad50b3ae
child 9669 1021c9bd0f64
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.
src/video/windows/SDL_windowsevents.c
     1.1 --- a/src/video/windows/SDL_windowsevents.c	Thu May 28 09:52:48 2015 -0700
     1.2 +++ b/src/video/windows/SDL_windowsevents.c	Sat Dec 20 11:45:39 2014 -0500
     1.3 @@ -45,6 +45,9 @@
     1.4  #include "wmmsg.h"
     1.5  #endif
     1.6  
     1.7 +/* For processing mouse WM_*BUTTON* and WM_MOUSEMOVE message-data from GetMessageExtraInfo() */
     1.8 +#define MOUSEEVENTF_FROMTOUCH 0xFF515700
     1.9 +
    1.10  /* Masks for processing the windows KEYDOWN and KEYUP messages */
    1.11  #define REPEATED_KEYMASK    (1<<30)
    1.12  #define EXTENDED_KEYMASK    (1<<24)
    1.13 @@ -196,7 +199,7 @@
    1.14  
    1.15  
    1.16  void
    1.17 -WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button)
    1.18 +WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID)
    1.19  {
    1.20      if (data->focus_click_pending && button == SDL_BUTTON_LEFT && !bwParamMousePressed) {
    1.21          data->focus_click_pending = SDL_FALSE;
    1.22 @@ -204,9 +207,9 @@
    1.23      }
    1.24  
    1.25      if (bwParamMousePressed && !bSDLMousePressed) {
    1.26 -        SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button);
    1.27 +        SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button);
    1.28      } else if (!bwParamMousePressed && bSDLMousePressed) {
    1.29 -        SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button);
    1.30 +        SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button);
    1.31      }
    1.32  }
    1.33  
    1.34 @@ -215,15 +218,15 @@
    1.35  *  so this funciton reconciles our view of the world with the current buttons reported by windows
    1.36  */
    1.37  void
    1.38 -WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data)
    1.39 +WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mouseID)
    1.40  {
    1.41      if (wParam != data->mouse_button_flags) {
    1.42          Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
    1.43 -        WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT);
    1.44 -        WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE);
    1.45 -        WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT);
    1.46 -        WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1);
    1.47 -        WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2);
    1.48 +        WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, mouseID);
    1.49 +        WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, mouseID);
    1.50 +        WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, mouseID);
    1.51 +        WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, mouseID);
    1.52 +        WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, mouseID);
    1.53          data->mouse_button_flags = wParam;
    1.54      }
    1.55  }
    1.56 @@ -235,25 +238,25 @@
    1.57      if (rawButtons != data->mouse_button_flags) {
    1.58          Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
    1.59          if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN))
    1.60 -            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT);
    1.61 +            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
    1.62          if ((rawButtons & RI_MOUSE_BUTTON_1_UP))
    1.63 -            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT);
    1.64 +            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
    1.65          if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN))
    1.66 -            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT);
    1.67 +            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
    1.68          if ((rawButtons & RI_MOUSE_BUTTON_2_UP))
    1.69 -            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT);
    1.70 +            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
    1.71          if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN))
    1.72 -            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE);
    1.73 +            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
    1.74          if ((rawButtons & RI_MOUSE_BUTTON_3_UP))
    1.75 -            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE);
    1.76 +            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
    1.77          if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN))
    1.78 -            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1);
    1.79 +            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
    1.80          if ((rawButtons & RI_MOUSE_BUTTON_4_UP))
    1.81 -            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1);
    1.82 +            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
    1.83          if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN))
    1.84 -            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2);
    1.85 +            WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
    1.86          if ((rawButtons & RI_MOUSE_BUTTON_5_UP))
    1.87 -            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2);
    1.88 +            WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
    1.89          data->mouse_button_flags = rawButtons;
    1.90      }
    1.91  }
    1.92 @@ -271,23 +274,23 @@
    1.93  
    1.94      keyState = GetAsyncKeyState(VK_LBUTTON);
    1.95      if (!(keyState & 0x8000)) {
    1.96 -        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT);
    1.97 +        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
    1.98      }
    1.99      keyState = GetAsyncKeyState(VK_RBUTTON);
   1.100      if (!(keyState & 0x8000)) {
   1.101 -        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT);
   1.102 +        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
   1.103      }
   1.104      keyState = GetAsyncKeyState(VK_MBUTTON);
   1.105      if (!(keyState & 0x8000)) {
   1.106 -        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE);
   1.107 +        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
   1.108      }
   1.109      keyState = GetAsyncKeyState(VK_XBUTTON1);
   1.110      if (!(keyState & 0x8000)) {
   1.111 -        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1);
   1.112 +        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
   1.113      }
   1.114      keyState = GetAsyncKeyState(VK_XBUTTON2);
   1.115      if (!(keyState & 0x8000)) {
   1.116 -        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2);
   1.117 +        WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
   1.118      }
   1.119      data->mouse_button_flags = 0;
   1.120  }
   1.121 @@ -410,7 +413,8 @@
   1.122          {
   1.123              SDL_Mouse *mouse = SDL_GetMouse();
   1.124              if (!mouse->relative_mode || mouse->relative_mode_warp) {
   1.125 -                SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
   1.126 +                SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0);
   1.127 +                SDL_SendMouseMotion(data->window, mouseID, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
   1.128              }
   1.129          }
   1.130          /* don't break here, fall through to check the wParam like the button presses */
   1.131 @@ -429,7 +433,8 @@
   1.132          {
   1.133              SDL_Mouse *mouse = SDL_GetMouse();
   1.134              if (!mouse->relative_mode || mouse->relative_mode_warp) {
   1.135 -                WIN_CheckWParamMouseButtons(wParam, data);
   1.136 +                SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0);
   1.137 +                WIN_CheckWParamMouseButtons(wParam, data, mouseID);
   1.138              }
   1.139          }
   1.140          break;