From 91709a267ad461b2feaf126a445d5c42e8b1ba3a Mon Sep 17 00:00:00 2001 From: John Klehm Date: Sat, 31 May 2008 16:48:19 -0500 Subject: winex11.drv: Place tablet cursors in slots based on type --- dlls/winex11.drv/wintab.c | 110 ++++++++++++++++++++++++++------------------ 1 files changed, 65 insertions(+), 45 deletions(-) diff --git a/dlls/winex11.drv/wintab.c b/dlls/winex11.drv/wintab.c index a19d02f..d8f630b 100644 --- a/dlls/winex11.drv/wintab.c +++ b/dlls/winex11.drv/wintab.c @@ -302,7 +302,7 @@ static INT button_state[10]; * now we would need Cursor #2, #5, #8, #11 * So to support that we need CURSORMAX of 12 (0 to 11) * FIXME: we dont support more than 4 regular tablets or 2 multimode tablets */ -#define CURSORMAX 10 +#define CURSORMAX 12 static LOGCONTEXTW gSysContext; static WTI_DEVICES_INFO gSysDevice; @@ -493,6 +493,30 @@ static BOOL is_eraser(const char *name, const char *type) return FALSE; } +/* cursors are placed in gSysCursor rows depending on their type + * see CURSORMAX comments for more detail */ +static BOOL add_system_cursor(LPWTI_CURSORS_INFO cursor) +{ + UINT offset = 0; + + if (cursor->TYPE == CSR_TYPE_PEN) + offset = 1; + else if (cursor->TYPE == CSR_TYPE_ERASER) + offset = 2; + + for (; offset < CURSORMAX; offset += 3) + { + if (!gSysCursor[offset].ACTIVE) + { + gSysCursor[offset] = *cursor; + ++gNumCursors; + return TRUE; + } + } + + return FALSE; +} + static void disable_system_cursors(void) { UINT i; @@ -518,7 +542,6 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) struct x11drv_thread_data *data = x11drv_thread_data(); int num_devices; int loop; - int cursor_target; XDeviceInfo *devices; XDeviceInfo *target = NULL; BOOL axis_read_complete= FALSE; @@ -578,7 +601,6 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) wine_tsx11_lock(); - cursor_target = -1; devices = pXListInputDevices(data->display, &num_devices); if (!devices) { @@ -591,7 +613,7 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) { int class_loop; char *device_type = devices[loop].type ? XGetAtomName(data->display, devices[loop].type) : NULL; - LPWTI_CURSORS_INFO cursor; + WTI_CURSORS_INFO cursor; TRACE("Device %i: [id %d|name %s|type %s|num_classes %d|use %d]\n", loop, (int) devices[loop].id, devices[loop].name, device_type ? device_type : "", @@ -607,14 +629,11 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) case IsXExtensionKeyboard: #endif TRACE("Is XExtension: Device, Keyboard, or Pointer\n"); - cursor_target++; target = &devices[loop]; - cursor = &gSysCursor[cursor_target]; if (strlen(target->name) >= WT_MAX_NAME_LEN) { ERR("Input device '%s' name too long - skipping\n", wine_dbgstr_a(target->name)); - cursor_target--; break; } @@ -627,56 +646,53 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) int shft = 0; X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL); - cursor->BUTTONS = pXGetDeviceButtonMapping(data->display, opendevice, map, 32); - if (X11DRV_check_error() || cursor->BUTTONS <= 0) + cursor.BUTTONS = pXGetDeviceButtonMapping(data->display, opendevice, map, 32); + if (X11DRV_check_error() || cursor.BUTTONS <= 0) { TRACE("No buttons, Non Tablet Device\n"); pXCloseDevice(data->display, opendevice); - cursor_target --; break; } - for (i=0; i< cursor->BUTTONS; i++,shft++) + for (i=0; i< cursor.BUTTONS; i++,shft++) { - cursor->BUTTONMAP[i] = map[i]; - cursor->SYSBTNMAP[i] = (1<display, opendevice); } else { WARN("Unable to open device %s\n",target->name); - cursor_target --; break; } - MultiByteToWideChar(CP_UNIXCP, 0, target->name, -1, cursor->NAME, WT_MAX_NAME_LEN); + 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. If this is wrong, please report it to wine-devel@winehq.org\n", loop, devices[loop].name, device_type ? device_type : ""); - cursor_target --; break; } - cursor->ACTIVE = 1; - cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | + cursor.ACTIVE = 1; + cursor.PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION; - cursor->PHYSID = target->id; - cursor->NPBUTTON = 1; - cursor->NPBTNMARKS[0] = 0 ; - cursor->NPBTNMARKS[1] = 1 ; - cursor->CAPABILITIES = CRC_MULTIMODE; + cursor.PHYSID = target->id; + cursor.NPBUTTON = 1; + cursor.NPBTNMARKS[0] = 0 ; + cursor.NPBTNMARKS[1] = 1 ; + cursor.CAPABILITIES = CRC_MULTIMODE; /* prefer finding TYPE_PEN(most capable) */ if (is_stylus(target->name, device_type)) - cursor->TYPE = CSR_TYPE_PEN; + cursor.TYPE = CSR_TYPE_PEN; else if (is_eraser(target->name, device_type)) - cursor->TYPE = CSR_TYPE_ERASER; + cursor.TYPE = CSR_TYPE_ERASER; else - cursor->TYPE = CSR_TYPE_OTHER; + cursor.TYPE = CSR_TYPE_OTHER; any = target->inputclassinfo; @@ -698,7 +714,7 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) ** the various inputs to see what the values are. Odds are that a ** more 'correct' algorithm would condense to this one anyway. */ - if (!axis_read_complete && cursor->TYPE == CSR_TYPE_PEN) + if (!axis_read_complete && cursor.TYPE == CSR_TYPE_PEN) { Axis = (XAxisInfoPtr) ((char *) Val + sizeof (XValuatorInfo)); @@ -772,43 +788,43 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) Button = (XButtonInfoPtr) any; TRACE(" ButtonInput %d: [class %d|length %d|num_buttons %d]\n", class_loop, (int) Button->class, Button->length, Button->num_buttons); - cursor->BTNNAMES = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*cchBuf); - for (i = 0; i < cursor->BUTTONS; i++) + cursor.BTNNAMES = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*cchBuf); + for (i = 0; i < cursor.BUTTONS; i++) { /* FIXME - these names are probably incorrect */ - int cch = strlenW(cursor->NAME) + 1; + int cch = strlenW(cursor.NAME) + 1; while (cch > cchBuf - cchPos - 1) /* we want one extra byte for the last NUL */ { cchBuf *= 2; - cursor->BTNNAMES = HeapReAlloc(GetProcessHeap(), 0, cursor->BTNNAMES, sizeof(WCHAR)*cchBuf); + cursor.BTNNAMES = HeapReAlloc(GetProcessHeap(), 0, cursor.BTNNAMES, sizeof(WCHAR)*cchBuf); } - strcpyW(cursor->BTNNAMES + cchPos, cursor->NAME); + strcpyW(cursor.BTNNAMES + cchPos, cursor.NAME); cchPos += cch; } - cursor->BTNNAMES[cchPos++] = 0; - cursor->BTNNAMES = HeapReAlloc(GetProcessHeap(), 0, cursor->BTNNAMES, sizeof(WCHAR)*cchPos); - cursor->cchBTNNAMES = cchPos; + cursor.BTNNAMES[cchPos++] = 0; + cursor.BTNNAMES = HeapReAlloc(GetProcessHeap(), 0, cursor.BTNNAMES, sizeof(WCHAR)*cchPos); + cursor.cchBTNNAMES = cchPos; } break; - } + } /* switch any->class */ any = (XAnyClassPtr) ((char*) any + any->length); - } + } /* for class_loop */ + if (!add_system_cursor(&cursor)) + FIXME("Skipping this cursor due to lack of system cursor slots.\n"); break; - } - + } /* switch devices.use */ XFree(device_type); - } + } /* for XListInputDevices */ pXFreeDeviceList(devices); if (axis_read_complete) + gSysDevice.NCSRTYPES = gNumCursors; + else { - gSysDevice.NCSRTYPES = cursor_target+1; - gNumCursors = cursor_target+1; - Tablet_FixupCursors(); + disable_system_cursors(); + WARN("Did not find a valid stylus, unable to determine system context parameters. Wintab is disabled.\n"); } - else - WARN("Did not find a valid stylus cursor with >= 5 axes, returning 0 valid devices.\n"); wine_tsx11_unlock(); } @@ -1312,6 +1328,10 @@ UINT X11DRV_WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput) case WTI_CURSORS+7: case WTI_CURSORS+8: case WTI_CURSORS+9: + case WTI_CURSORS+10: + case WTI_CURSORS+11: + /* CURSORMAX == 12 */ + /* FIXME: dynamic cursor support */ /* Apps will poll different slots to detect what cursors are available * if there isn't a cursor for this slot return 0 */ if (!gSysCursor[wCategory - WTI_CURSORS].ACTIVE) -- 1.5.4.3