298
298
xf86DeleteInput(pInfo, 0);
302
* Splits a wacom device name into its constituent pieces. For instance,
303
* "Wacom Intuos Pro Finger touch" would be split into "Wacom Intuos Pro"
304
* (the base kernel device name), "Finger" (an descriptor of the specific
305
* event interface), and "touch" (a suffix added by this driver to indicate
306
* the specific tool).
308
static void wcmSplitName(char* devicename, char *basename, char *subdevice, char *tool, size_t len)
310
char *name = strdupa(devicename);
313
*basename = *subdevice = *tool = '\0';
315
a = strrchr(name, ' ');
319
b = strrchr(name, ' ');
320
if (b && (!strcmp(b, " Pen") || !strcmp(b, " Finger") || !strcmp(b, " Pad")))
323
strncat(subdevice, b+1, len-1);
325
strncat(tool, a+1, len-1);
327
strncat(basename, name, len-1);
331
* Determines if two input devices represent independent parts (stylus,
332
* eraser, pad) of the same underlying device. If the 'logical_only'
333
* flag is set, the function will only return true if the two devices
334
* are represented by the same logical device (i.e., share the same
335
* input device node). Otherwise, the function will attempt to determine
336
* if the two devices are part of the same physical tablet, such as
337
* when a tablet reports 'pen' and 'touch' through separate device
340
static Bool wcmIsSiblingDevice(InputInfoPtr a, InputInfoPtr b, Bool logical_only)
342
WacomDevicePtr privA = (WacomDevicePtr)a->private;
343
WacomDevicePtr privB = (WacomDevicePtr)b->private;
345
if (strcmp(a->drv->driverName, "wacom") || strcmp(b->drv->driverName, "wacom"))
351
if (DEVICE_ID(privA->flags) == DEVICE_ID(privB->flags))
354
if (!strcmp(privA->common->device_path, privB->common->device_path))
359
// TODO: Udev might provide more accurate data, but this should
360
// be good enough in practice.
362
char baseA[len], subA[len], toolA[len];
363
char baseB[len], subB[len], toolB[len];
364
wcmSplitName(privA->name, baseA, subA, toolA, len);
365
wcmSplitName(privB->name, baseB, subB, toolB, len);
367
if (strcmp(baseA, baseB))
369
// Fallback for (arbitrary) static xorg.conf device names
370
return (privA->common->tablet_id == privB->common->tablet_id);
373
if (strlen(subA) != 0 && strlen(subB) != 0)
301
380
/* wcmMatchDevice - locate matching device and merge common structure. If an
302
381
* already initialized device shares the same device file and driver, remove
303
382
* the new device's "common" struct and point to the one of the already
323
402
WacomDevicePtr privMatch = (WacomDevicePtr)pMatch->private;
325
if ((pLocal != pMatch) &&
326
strstr(pMatch->drv->driverName, "wacom") &&
327
!strcmp(privMatch->common->device_path, common->device_path))
404
if (wcmIsSiblingDevice(pLocal, pMatch, TRUE))
329
406
DBG(2, priv, "port share between %s and %s\n",
330
407
pLocal->name, pMatch->name);
389
* Link the touch tool to the pen of the same device
390
* so we can arbitrate the events when posting them.
466
* Lookup to find the associated pen and touch for the same device.
467
* Store touch tool in wcmTouchDevice for pen and touch, respectively,
468
* of the same device. Update TabletFeature to indicate it is a hybrid
471
* @return True if found a touch tool for hybrid devices.
392
static void wcmLinkTouchAndPen(InputInfoPtr pInfo)
474
static Bool wcmLinkTouchAndPen(InputInfoPtr pInfo)
394
476
WacomDevicePtr priv = pInfo->private;
395
477
WacomCommonPtr common = priv->common;
397
479
WacomCommonPtr tmpcommon = NULL;
398
480
WacomDevicePtr tmppriv = NULL;
400
/* Lookup to find the associated pen and touch with same product id */
401
for (; device != NULL; device = device->next)
403
if (!strcmp(device->drv->driverName, "wacom"))
405
tmppriv = (WacomDevicePtr) device->private;
406
tmpcommon = tmppriv->common;
408
/* skip the same tool or already linked devices */
409
if ((tmppriv == priv) || tmpcommon->wcmTouchDevice)
412
if (tmpcommon->tablet_id == common->tablet_id)
414
if (IsTouch(tmppriv) && IsTablet(priv))
415
common->wcmTouchDevice = tmppriv;
416
else if (IsTouch(priv) && IsTablet(tmppriv))
417
tmpcommon->wcmTouchDevice = priv;
419
if (common->wcmTouchDevice ||
420
tmpcommon->wcmTouchDevice)
422
TabletSetFeature(common, WCM_PENTOUCH);
423
TabletSetFeature(tmpcommon, WCM_PENTOUCH);
427
if (common->wcmTouchDevice)
432
/* Lookup for pen and touch devices with different product ids */
433
for (; device != NULL; device = device->next)
435
if (!strcmp(device->drv->driverName, "wacom"))
437
tmppriv = (WacomDevicePtr) device->private;
438
tmpcommon = tmppriv->common;
440
/* skip the same tool or already linked devices */
441
if ((tmppriv == priv) || tmpcommon->wcmTouchDevice)
444
if (IsTouch(tmppriv) && IsTablet(priv))
445
common->wcmTouchDevice = tmppriv;
446
else if (IsTouch(priv) && IsTablet(tmppriv))
447
tmpcommon->wcmTouchDevice = priv;
449
if (common->wcmTouchDevice || tmpcommon->wcmTouchDevice)
451
TabletSetFeature(common, WCM_PENTOUCH);
452
TabletSetFeature(tmpcommon, WCM_PENTOUCH);
455
if (common->wcmTouchDevice)
482
/* Lookup to find the associated pen and touch */
483
for (; device != NULL; device = device->next)
485
if (!wcmIsSiblingDevice(pInfo, device, FALSE))
488
tmppriv = (WacomDevicePtr) device->private;
489
tmpcommon = tmppriv->common;
491
DBG(4, priv, "Considering link with %s...\n", tmppriv->name);
493
/* already linked devices */
494
if (tmpcommon->wcmTouchDevice && IsTablet(tmppriv))
496
DBG(4, priv, "A link is already in place. Ignoring.\n");
500
if (IsTouch(tmppriv))
502
common->wcmTouchDevice = tmppriv;
503
tmpcommon->wcmTouchDevice = tmppriv;
505
else if (IsTouch(priv))
507
common->wcmTouchDevice = priv;
508
tmpcommon->wcmTouchDevice = priv;
512
DBG(4, priv, "A link is not necessary. Ignoring.\n");
515
if ((common->wcmTouchDevice && IsTablet(priv)) ||
516
(tmpcommon->wcmTouchDevice && IsTablet(tmppriv)))
518
TabletSetFeature(common, WCM_PENTOUCH);
519
TabletSetFeature(tmpcommon, WCM_PENTOUCH);
522
if (common->wcmTouchDevice)
524
DBG(4, priv, "Link created!\n");
528
DBG(4, priv, "No suitable device to link with found.\n");