Fix X11 tablet pen and eraser distinction being wrong in some cases.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 24 Nov 2018 22:21:13 +0000 (23:21 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 24 Nov 2018 22:24:32 +0000 (23:24 +0100)
This extends the earlier fix to use the latest logic from Wine's wintab.c,
to better handle eraser detection.

intern/ghost/intern/GHOST_SystemX11.cpp

index 06754bc9300610404a4b5e792d11fceb6e68a091..0c0abc9535644016f5d78fcc3c8d18ea65e59d56 100644 (file)
@@ -2163,11 +2163,8 @@ int GHOST_X11_ApplicationIOErrorHandler(Display * /*display*/)
 }
 
 #ifdef WITH_X11_XINPUT
-/* These C functions are copied from Wine 1.1.13's wintab.c */
-#define BOOL int
-#define TRUE 1
-#define FALSE 0
 
+/* These C functions are copied from Wine 3.12's wintab.c */
 static bool match_token(const char *haystack, const char *needle)
 {
        const char *p, *q;
@@ -2180,15 +2177,14 @@ static bool match_token(const char *haystack, const char *needle)
                for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
                        p++;
                if (!*q && (isspace(*p) || !*p))
-                       return TRUE;
+                       return true;
 
                while (*p && !isspace(*p))
                        p++;
        }
-       return FALSE;
+       return false;
 }
 
-
 /* Determining if an X device is a Tablet style device is an imperfect science.
  * We rely on common conventions around device names as well as the type reported
  * by Wacom tablets.  This code will likely need to be expanded for alternate tablet types
@@ -2199,35 +2195,10 @@ static bool match_token(const char *haystack, const char *needle)
  * Wacoms x11 config "cursor" refers to its device slot (which we mirror with
  * our gSysCursors) for puck like devices (tablet mice essentially).
  */
-#if 0 // unused
-static BOOL is_tablet_cursor(const char *name, const char *type)
-{
-       int i;
-       static const char *tablet_cursor_whitelist[] = {
-               "wacom",
-               "wizardpen",
-               "acecad",
-               "tablet",
-               "cursor",
-               "stylus",
-               "eraser",
-               "pad",
-               NULL
-       };
-
-       for (i = 0; tablet_cursor_whitelist[i] != NULL; i++) {
-               if (name && match_token(name, tablet_cursor_whitelist[i]))
-                       return TRUE;
-               if (type && match_token(type, tablet_cursor_whitelist[i]))
-                       return TRUE;
-       }
-       return FALSE;
-}
-#endif
-static BOOL is_stylus(const char *name, const char *type)
+static GHOST_TTabletMode tablet_mode_from_name(const char *name, const char *type)
 {
        int i;
-       static const char *tablet_stylus_whitelist[] = {
+       static const chartablet_stylus_whitelist[] = {
                "stylus",
                "wizardpen",
                "acecad",
@@ -2235,28 +2206,28 @@ static BOOL is_stylus(const char *name, const char *type)
                NULL
        };
 
-       for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
-               if (name && match_token(name, tablet_stylus_whitelist[i]))
-                       return TRUE;
-               if (type && match_token(type, tablet_stylus_whitelist[i]))
-                       return TRUE;
+       /* First check device type to avoid cases where name is "Pen and Eraser" and type is "ERASER" */
+       for (i=0; tablet_stylus_whitelist[i] != NULL; i++) {
+               if (type && match_token(type, tablet_stylus_whitelist[i])) {
+                       return GHOST_kTabletModeStylus;
+               }
+       }
+       if (type && match_token(type, "eraser")) {
+               return GHOST_kTabletModeEraser;
+       }
+       for (i=0; tablet_stylus_whitelist[i] != NULL; i++) {
+               if (name && match_token(name, tablet_stylus_whitelist[i])) {
+                       return GHOST_kTabletModeStylus;
+               }
+       }
+       if (name && match_token(name, "eraser")) {
+               return GHOST_kTabletModeEraser;
        }
 
-       return FALSE;
+       return GHOST_kTabletModeNone;
 }
 
-static BOOL is_eraser(const char *name, const char *type)
-{
-       if (name && match_token(name, "eraser"))
-               return TRUE;
-       if (type && match_token(type, "eraser"))
-               return TRUE;
-       return FALSE;
-}
-#undef BOOL
-#undef TRUE
-#undef FALSE
-/* end code copied from wine */
+/* End code copied from Wine. */
 
 void GHOST_SystemX11::refreshXInputDevices()
 {
@@ -2285,9 +2256,10 @@ void GHOST_SystemX11::refreshXInputDevices()
 
 //                             printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
 
+                               GHOST_TTabletMode tablet_mode = tablet_mode_from_name(device_info[i].name, device_type);
 
                                if ((m_xtablet.StylusDevice == NULL) &&
-                                   (is_stylus(device_info[i].name, device_type) && (device_info[i].type != m_atom.TABLET)))
+                                   ((tablet_mode == GHOST_kTabletModeStylus) && (device_info[i].type != m_atom.TABLET)))
                                    /* for libinput to work reliable, only lookup ValuatorClass in Tablet type:'STYLUS' */
                                {
 //                                     printf("\tfound stylus\n");
@@ -2325,7 +2297,7 @@ void GHOST_SystemX11::refreshXInputDevices()
                                        }
                                }
                                else if ((m_xtablet.EraserDevice == NULL) &&
-                                        (is_eraser(device_info[i].name, device_type)))
+                                        (tablet_mode == GHOST_kTabletModeEraser))
                                {
 //                                     printf("\tfound eraser\n");
                                        m_xtablet.EraserID = device_info[i].id;