Commit cc64b369fbfd5c40389e9925f95da00533c26d78

Sam Lantinga 2019-08-30T15:32:15

Allow mouse messages from Wacom pens, e.g. right click pen buttons, etc.

diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index cc6d5aa..3ff169a 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -47,9 +47,6 @@
 #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)
@@ -246,7 +243,7 @@ WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePress
 
 /*
 * Some windows systems fail to send a WM_LBUTTONDOWN sometimes, but each mouse move contains the current button state also
-*  so this funciton reconciles our view of the world with the current buttons reported by windows
+*  so this function reconciles our view of the world with the current buttons reported by windows
 */
 static void
 WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mouseID)
@@ -365,26 +362,40 @@ static SDL_bool isVistaOrNewer = SDL_FALSE;
    This is used to implement a workaround.. */
 static SDL_bool isWin10FCUorNewer = SDL_FALSE;
 
-/* Checks a mouse or raw packet for touch indication.
-   returns: 0 for not touch input, 1 for touch input.
-*/
-static LPARAM
-GetMessageExtraInfoAndCheckMousePacketTouch(int *checkTouch) {
+/* We want to generate mouse events from mouse and pen, and touch events from touchscreens */
+#define MI_WP_SIGNATURE         0xFF515700
+#define MI_WP_SIGNATURE_MASK    0xFFFFFF00
+#define IsTouchEvent(dw) ((dw) & MI_WP_SIGNATURE_MASK) == MI_WP_SIGNATURE
+
+typedef enum
+{
+    SDL_MOUSE_EVENT_SOURCE_UNKNOWN,
+    SDL_MOUSE_EVENT_SOURCE_MOUSE,
+    SDL_MOUSE_EVENT_SOURCE_TOUCH,
+    SDL_MOUSE_EVENT_SOURCE_PEN,
+} SDL_MOUSE_EVENT_SOURCE;
+
+static SDL_MOUSE_EVENT_SOURCE GetMouseMessageSource()
+{
     LPARAM extrainfo = GetMessageExtraInfo();
     /* Mouse data (ignoring synthetic mouse events generated for touchscreens) */
     /* Versions below Vista will set the low 7 bits to the Mouse ID and don't use bit 7:
        Check bits 8-32 for the signature (which will indicate a Tablet PC Pen or Touch Device).
        Only check bit 7 when Vista and up(Cleared=Pen, Set=Touch(which we need to filter out)),
        when the signature is set. The Mouse ID will be zero for an actual mouse. */
-    *checkTouch = (!(((extrainfo & 0x7F) && (isVistaOrNewer ? (extrainfo & 0x80) : 1)) || ((extrainfo & 0xFFFFFF00) == 0xFF515700)));
-    return extrainfo;
+    if (IsTouchEvent(extrainfo)) {
+        if (extrainfo & 0x80) {
+            return SDL_MOUSE_EVENT_SOURCE_TOUCH;
+        } else {
+            return SDL_MOUSE_EVENT_SOURCE_PEN;
+        }
+    }
+    return SDL_MOUSE_EVENT_SOURCE_MOUSE;
 }
 
 LRESULT CALLBACK
 WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-    int checkTouch = -1; /* Default to -1 for not yet loaded */
-    LPARAM extrainfo;    /* The extra info when checkTouch >= 0. */
     SDL_WindowData *data;
     LRESULT returnCode = -1;
 
@@ -512,10 +523,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
     case WM_MOUSEMOVE:
         {
             SDL_Mouse *mouse = SDL_GetMouse();
-            extrainfo = GetMessageExtraInfoAndCheckMousePacketTouch(&checkTouch); /* load */
             if (!mouse->relative_mode || mouse->relative_mode_warp) {
                 /* Only generate mouse events for real mouse */
-                if (((extrainfo & MOUSEEVENTF_FROMTOUCH) != MOUSEEVENTF_FROMTOUCH) && checkTouch) {
+                if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH) {
                     SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
                     if (isWin10FCUorNewer && mouse->relative_mode_warp) {
                         /* To work around #3931, Win10 bug introduced in Fall Creators Update, where
@@ -546,11 +556,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
     case WM_XBUTTONDBLCLK:
         {
             SDL_Mouse *mouse = SDL_GetMouse();
-            if (checkTouch < 0) {
-                extrainfo = GetMessageExtraInfoAndCheckMousePacketTouch(&checkTouch);
-            }
             if (!mouse->relative_mode || mouse->relative_mode_warp) {
-                if (((extrainfo & MOUSEEVENTF_FROMTOUCH) != MOUSEEVENTF_FROMTOUCH) && checkTouch) {
+                if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH) {
                     WIN_CheckWParamMouseButtons(wParam, data, 0);
                 }
             }
@@ -576,9 +583,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
             /* Mouse data (ignoring synthetic mouse events generated for touchscreens) */
             if (inp.header.dwType == RIM_TYPEMOUSE) {
-                extrainfo = GetMessageExtraInfoAndCheckMousePacketTouch(&checkTouch);
-                if (!checkTouch)
+                if (GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH) {
                     break;
+                }
                 if (isRelative) {
                     RAWMOUSE* rawmouse = &inp.data.mouse;