From 51aecf8056748b4a9abcf67ec8f5dc7c73f76af2 Mon Sep 17 00:00:00 2001 From: Jeremy White Date: Mon, 31 Dec 2007 09:49:19 -0600 Subject: [PATCH] wintab32: Add logic to detect specific tablet cursor types, use it to discard non tablet X devices. --- dlls/winex11.drv/wintab.c | 98 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/dlls/winex11.drv/wintab.c b/dlls/winex11.drv/wintab.c index e3c7b5738e2..335d7f54fdf 100644 --- a/dlls/winex11.drv/wintab.c +++ b/dlls/winex11.drv/wintab.c @@ -362,6 +362,80 @@ 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); } +BOOL match_token(const char *haystack, const char *needle) +{ + const char *p, *q; + for (p = haystack; *p; ) + { + while (*p && isspace(*p)) + p++; + if (! *p) + break; + + for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++) + p++; + if (! *q && (isspace(*p) || !*p)) + return TRUE; + + while (*p && ! isspace(*p)) + p++; + } + 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 +*/ + +#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 && match_token(name, "wacom")) + return TRUE; + if (type && match_token(type, "wacom")) + return TRUE; + return FALSE; +} + +static BOOL is_cursor(const char *name, const char *type) +{ + if (name && match_token(name, "cursor")) + return TRUE; + if (type && match_token(type, "cursor")) + return TRUE; + return FALSE; +} + +static BOOL is_stylus(const char *name, const char *type) +{ + if (name && match_token(name, "stylus")) + return TRUE; + if (type && match_token(type, "stylus")) + return TRUE; + return FALSE; +} + +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; +} + +static BOOL is_pad(const char *name, const char *type) +{ + if (name && match_token(name, "pad")) + return TRUE; + if (type && match_token(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}; @@ -440,16 +514,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; @@ -463,6 +538,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; } @@ -481,6 +557,7 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) TRACE("No buttons, Non Tablet Device\n"); pXCloseDevice(data->display, opendevice); cursor_target --; + XFree(device_type); continue; } @@ -495,10 +572,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 | @@ -509,9 +596,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; @@ -632,6 +719,9 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) any = (XAnyClassPtr) ((char*) any + any->length); } } + + XFree(device_type); + } pXFreeDeviceList(devices); gSysDevice.NCSRTYPES = cursor_target+1;