[wintab32] Refine how we determine cursor types; use that to discard non tablet devices.

Jeremy White jwhite at codeweavers.com
Wed Dec 26 13:53:36 CST 2007


---
 dlls/winex11.drv/wintab.c |   92 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/dlls/winex11.drv/wintab.c b/dlls/winex11.drv/wintab.c
index c3ad140..e9ce095 100644
--- a/dlls/winex11.drv/wintab.c
+++ b/dlls/winex11.drv/wintab.c
@@ -362,6 +362,74 @@ static void trace_axes(XValuatorInfoPtr val)
         TRACE("        Axis %d: [resolution %d|min_value %d|max_value %d]\n", i, axis->resolution, axis->min_value, axis->max_value);
 }

+/* FIXME:  strcasestr is not available on all platforms; implement a simple version */
+static char * poormans_strcasestr(const char *haystack, const char *needle)
+{
+    const char *h, *p, *q;
+    for (h = haystack; *h; h++)
+    {
+        for (p = h, q = needle; *p && *q && tolower(*p) == tolower(*q); p++,q++)
+            ;
+        if (!*q)
+            return (char *) h;
+    }
+
+    return NULL;
+}
+
+/*    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
+*/
+
+#define IS_TABLET_CURSOR(n, t)   (is_wacom((n), (t)) || is_cursor((n), (t)) || is_stylus((n), (t)) || is_eraser((n), (t)) || is_pad((n), (t)))
+
+static BOOL is_wacom(const char *name, const char *type)
+{
+    if (name && poormans_strcasestr(name, "wacom"))
+        return TRUE;
+    if (type && poormans_strcasestr(type, "wacom"))
+        return TRUE;
+    return FALSE;
+}
+
+static BOOL is_cursor(const char *name, const char *type)
+{
+    if (name && poormans_strcasestr(name, "cursor"))
+        return TRUE;
+    if (type && poormans_strcasestr(type, "cursor"))
+        return TRUE;
+    return FALSE;
+}
+
+static BOOL is_stylus(const char *name, const char *type)
+{
+    if (name && poormans_strcasestr(name, "stylus"))
+        return TRUE;
+    if (type && poormans_strcasestr(type, "stylus"))
+        return TRUE;
+    return FALSE;
+}
+
+static BOOL is_eraser(const char *name, const char *type)
+{
+    if (name && poormans_strcasestr(name, "eraser"))
+        return TRUE;
+    if (type && poormans_strcasestr(type, "eraser"))
+        return TRUE;
+    return FALSE;
+}
+
+static BOOL is_pad(const char *name, const char *type)
+{
+    if (name && poormans_strcasestr(name, "pad"))
+        return TRUE;
+    if (type && poormans_strcasestr(type, "pad"))
+        return TRUE;
+    return FALSE;
+}
+
+
 void X11DRV_LoadTabletInfo(HWND hwnddefault)
 {
     const WCHAR SZ_CONTEXT_NAME[] = {'W','i','n','e',' ','T','a','b','l','e','t',' ','C','o','n','t','e','x','t',0};
@@ -439,16 +507,17 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault)
     for (loop=0; loop < num_devices; loop++)
     {
         int class_loop;
+        char *device_type = XGetAtomName(data->display, devices[loop].type);

         TRACE("Device %i:  [id %d|name %s|type %s|num_classes %d|use %s]\n",
-                loop, (int) devices[loop].id, devices[loop].name,
-                XGetAtomName(data->display, devices[loop].type),
+                loop, (int) devices[loop].id, devices[loop].name, device_type,
                 devices[loop].num_classes,
                 devices[loop].use == IsXKeyboard ? "IsXKeyboard" :
                     devices[loop].use == IsXPointer ? "IsXPointer" :
                     devices[loop].use == IsXExtensionDevice ? "IsXExtensionDevice" :
                     "Unknown"
                 );
+
         if (devices[loop].use == IsXExtensionDevice)
         {
             LPWTI_CURSORS_INFO cursor;
@@ -462,6 +531,7 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault)
             {
                 ERR("Input device '%s' name too long - skipping\n", wine_dbgstr_a(target->name));
                 cursor_target--;
+                XFree(device_type);
                 continue;
             }

@@ -480,6 +550,7 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault)
                     TRACE("No buttons, Non Tablet Device\n");
                     pXCloseDevice(data->display, opendevice);
                     cursor_target --;
+                    XFree(device_type);
                     continue;
                 }

@@ -494,10 +565,20 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault)
             {
                 WARN("Unable to open device %s\n",target->name);
                 cursor_target --;
+                XFree(device_type);
                 continue;
             }
             MultiByteToWideChar(CP_UNIXCP, 0, target->name, -1, cursor->NAME, WT_MAX_NAME_LEN);

+            if (! IS_TABLET_CURSOR(target->name, device_type))
+            {
+                WARN("Skipping device %d [name %s|type %s]; not apparently a tablet cursor type device\n",
+                        loop, devices[loop].name, device_type);
+                XFree(device_type);
+                cursor_target --;
+                continue;
+            }
+
             cursor->ACTIVE = 1;
             cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS |  PK_X | PK_Y |
                               PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
@@ -508,9 +589,9 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault)
             cursor->NPBTNMARKS[0] = 0 ;
             cursor->NPBTNMARKS[1] = 1 ;
             cursor->CAPABILITIES = CRC_MULTIMODE;
-            if (strcasecmp(target->name,"stylus")==0)
+            if (is_stylus(target->name, device_type))
                 cursor->TYPE = CSR_TYPE_PEN;
-            if (strcasecmp(target->name,"eraser")==0)
+            if (is_eraser(target->name, device_type))
                 cursor->TYPE = CSR_TYPE_ERASER;


@@ -631,6 +712,9 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault)
                 any = (XAnyClassPtr) ((char*) any + any->length);
             }
         }
+
+        XFree(device_type);
+
     }
     pXFreeDeviceList(devices);
     gSysDevice.NCSRTYPES = cursor_target+1;



More information about the wine-patches mailing list