~ubuntu-branches/ubuntu/utopic/xf86-input-wacom/utopic

« back to all changes in this revision

Viewing changes to src/wcmConfig.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2014-09-10 16:34:04 UTC
  • mfrom: (1.1.16)
  • Revision ID: package-import@ubuntu.com-20140910163404-0334r2g4juh1r1j2
Tags: 1:0.25.0-0ubuntu1
* New upstream release.
* Drop the udev script and use the upstream provided one.

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
        priv->strip_default[STRIP_RIGHT_DN] = 5;
89
89
        priv->naxes = 6;                        /* Default number of axes */
90
90
 
91
 
        /* JEJ - throttle sampling code */
92
 
        priv->throttleLimit = -1;
93
 
 
94
91
        common->wcmDevices = priv;
95
92
 
96
93
        /* tool */
103
100
        /* timers */
104
101
        priv->serial_timer = TimerSet(NULL, 0, 0, NULL, NULL);
105
102
        priv->tap_timer = TimerSet(NULL, 0, 0, NULL, NULL);
 
103
        priv->touch_timer = TimerSet(NULL, 0, 0, NULL, NULL);
106
104
 
107
105
        return 1;
108
106
 
127
125
 
128
126
        TimerFree(priv->serial_timer);
129
127
        TimerFree(priv->tap_timer);
 
128
        TimerFree(priv->touch_timer);
130
129
        free(priv->tool);
131
130
        wcmFreeCommon(&priv->common);
132
131
        free(priv);
134
133
        pInfo->private = NULL;
135
134
}
136
135
 
137
 
static int wcmSetType(InputInfoPtr pInfo, const char *type)
 
136
TEST_NON_STATIC int
 
137
wcmSetType(InputInfoPtr pInfo, const char *type)
138
138
{
139
139
        WacomDevicePtr priv = pInfo->private;
140
140
 
170
170
                goto invalid;
171
171
 
172
172
        /* Set the device id of the "last seen" device on this tool */
173
 
        priv->old_device_id = wcmGetPhyDeviceID(priv);
 
173
        priv->oldState.device_id = wcmGetPhyDeviceID(priv);
174
174
 
175
175
        if (!priv->tool)
176
176
                return 0;
298
298
        xf86DeleteInput(pInfo, 0);
299
299
}
300
300
 
 
301
/**
 
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).
 
307
 */
 
308
static void wcmSplitName(char* devicename, char *basename, char *subdevice, char *tool, size_t len)
 
309
{
 
310
        char *name = strdupa(devicename);
 
311
        char *a, *b;
 
312
 
 
313
        *basename = *subdevice = *tool = '\0';
 
314
 
 
315
        a = strrchr(name, ' ');
 
316
        if (a)
 
317
        {
 
318
                *a = '\0';
 
319
                b = strrchr(name, ' ');
 
320
                if (b && (!strcmp(b, " Pen") || !strcmp(b, " Finger") || !strcmp(b, " Pad")))
 
321
                {
 
322
                        *b = '\0';
 
323
                        strncat(subdevice, b+1, len-1);
 
324
                }
 
325
                strncat(tool, a+1, len-1);
 
326
        }
 
327
        strncat(basename, name, len-1);
 
328
}
 
329
 
 
330
/**
 
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
 
338
 * nodes.
 
339
 */
 
340
static Bool wcmIsSiblingDevice(InputInfoPtr a, InputInfoPtr b, Bool logical_only)
 
341
{
 
342
        WacomDevicePtr privA = (WacomDevicePtr)a->private;
 
343
        WacomDevicePtr privB = (WacomDevicePtr)b->private;
 
344
 
 
345
        if (strcmp(a->drv->driverName, "wacom") || strcmp(b->drv->driverName, "wacom"))
 
346
                return FALSE;
 
347
 
 
348
        if (privA == privB)
 
349
                return FALSE;
 
350
 
 
351
        if (DEVICE_ID(privA->flags) == DEVICE_ID(privB->flags))
 
352
                return FALSE;
 
353
 
 
354
        if (!strcmp(privA->common->device_path, privB->common->device_path))
 
355
                return TRUE;
 
356
 
 
357
        if (!logical_only)
 
358
        {
 
359
                // TODO: Udev might provide more accurate data, but this should
 
360
                // be good enough in practice.
 
361
                const int len = 50;
 
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);
 
366
 
 
367
                if (strcmp(baseA, baseB))
 
368
                {
 
369
                        // Fallback for (arbitrary) static xorg.conf device names
 
370
                        return (privA->common->tablet_id == privB->common->tablet_id);
 
371
                }
 
372
 
 
373
                if (strlen(subA) != 0 && strlen(subB) != 0)
 
374
                        return TRUE;
 
375
        }
 
376
 
 
377
        return FALSE;
 
378
}
 
379
 
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
322
401
        {
323
402
                WacomDevicePtr privMatch = (WacomDevicePtr)pMatch->private;
324
403
 
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))
328
405
                {
329
406
                        DBG(2, priv, "port share between %s and %s\n",
330
407
                                        pLocal->name, pMatch->name);
386
463
}
387
464
 
388
465
/**
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
 
469
 * of touch and pen.
 
470
 *
 
471
 * @return True if found a touch tool for hybrid devices.
 
472
 * false otherwise.
391
473
 */
392
 
static void wcmLinkTouchAndPen(InputInfoPtr pInfo)
 
474
static Bool wcmLinkTouchAndPen(InputInfoPtr pInfo)
393
475
{
394
476
        WacomDevicePtr priv = pInfo->private;
395
477
        WacomCommonPtr common = priv->common;
397
479
        WacomCommonPtr tmpcommon = NULL;
398
480
        WacomDevicePtr tmppriv = NULL;
399
481
 
400
 
        /* Lookup to find the associated pen and touch with same product id */
401
 
        for (; device != NULL; device = device->next)
402
 
        {
403
 
                if (!strcmp(device->drv->driverName, "wacom"))
404
 
                {
405
 
                        tmppriv = (WacomDevicePtr) device->private;
406
 
                        tmpcommon = tmppriv->common;
407
 
 
408
 
                        /* skip the same tool or already linked devices */
409
 
                        if ((tmppriv == priv) || tmpcommon->wcmTouchDevice)
410
 
                                continue;
411
 
 
412
 
                        if (tmpcommon->tablet_id == common->tablet_id)
413
 
                        {
414
 
                                if (IsTouch(tmppriv) && IsTablet(priv))
415
 
                                        common->wcmTouchDevice = tmppriv;
416
 
                                else if (IsTouch(priv) && IsTablet(tmppriv))
417
 
                                        tmpcommon->wcmTouchDevice = priv;
418
 
 
419
 
                                if (common->wcmTouchDevice ||
420
 
                                                tmpcommon->wcmTouchDevice)
421
 
                                {
422
 
                                        TabletSetFeature(common, WCM_PENTOUCH);
423
 
                                        TabletSetFeature(tmpcommon, WCM_PENTOUCH);
424
 
                                }
425
 
                        }
426
 
 
427
 
                        if (common->wcmTouchDevice)
428
 
                                return;
429
 
                }
430
 
        }
431
 
 
432
 
        /* Lookup for pen and touch devices with different product ids */
433
 
        for (; device != NULL; device = device->next)
434
 
        {
435
 
                if (!strcmp(device->drv->driverName, "wacom"))
436
 
                {
437
 
                        tmppriv = (WacomDevicePtr) device->private;
438
 
                        tmpcommon = tmppriv->common;
439
 
 
440
 
                        /* skip the same tool or already linked devices */
441
 
                        if ((tmppriv == priv) || tmpcommon->wcmTouchDevice)
442
 
                                continue;
443
 
 
444
 
                        if (IsTouch(tmppriv) && IsTablet(priv))
445
 
                                common->wcmTouchDevice = tmppriv;
446
 
                        else if (IsTouch(priv) && IsTablet(tmppriv))
447
 
                                tmpcommon->wcmTouchDevice = priv;
448
 
 
449
 
                        if (common->wcmTouchDevice || tmpcommon->wcmTouchDevice)
450
 
                        {
451
 
                                TabletSetFeature(common, WCM_PENTOUCH);
452
 
                                TabletSetFeature(tmpcommon, WCM_PENTOUCH);
453
 
                        }
454
 
 
455
 
                        if (common->wcmTouchDevice)
456
 
                                return;
457
 
                }
458
 
        }
 
482
        /* Lookup to find the associated pen and touch */
 
483
        for (; device != NULL; device = device->next)
 
484
        {
 
485
                if (!wcmIsSiblingDevice(pInfo, device, FALSE))
 
486
                        continue;
 
487
 
 
488
                tmppriv = (WacomDevicePtr) device->private;
 
489
                tmpcommon = tmppriv->common;
 
490
 
 
491
                DBG(4, priv, "Considering link with %s...\n", tmppriv->name);
 
492
 
 
493
                /* already linked devices */
 
494
                if (tmpcommon->wcmTouchDevice && IsTablet(tmppriv))
 
495
                {
 
496
                        DBG(4, priv, "A link is already in place. Ignoring.\n");
 
497
                        continue;
 
498
                }
 
499
 
 
500
                if (IsTouch(tmppriv))
 
501
                {
 
502
                        common->wcmTouchDevice = tmppriv;
 
503
                        tmpcommon->wcmTouchDevice = tmppriv;
 
504
                }
 
505
                else if (IsTouch(priv))
 
506
                {
 
507
                        common->wcmTouchDevice = priv;
 
508
                        tmpcommon->wcmTouchDevice = priv;
 
509
                }
 
510
                else
 
511
                {
 
512
                        DBG(4, priv, "A link is not necessary. Ignoring.\n");
 
513
                }
 
514
 
 
515
                if ((common->wcmTouchDevice && IsTablet(priv)) ||
 
516
                        (tmpcommon->wcmTouchDevice && IsTablet(tmppriv)))
 
517
                {
 
518
                        TabletSetFeature(common, WCM_PENTOUCH);
 
519
                        TabletSetFeature(tmpcommon, WCM_PENTOUCH);
 
520
                }
 
521
 
 
522
                if (common->wcmTouchDevice)
 
523
                {
 
524
                        DBG(4, priv, "Link created!\n");
 
525
                        return TRUE;
 
526
                }
 
527
        }
 
528
        DBG(4, priv, "No suitable device to link with found.\n");
 
529
        return FALSE;
459
530
}
460
531
 
461
532
/**
600
671
                wcmHotplugOthers(pInfo, oldname);
601
672
        }
602
673
 
603
 
        if (pInfo->fd != -1)
604
 
        {
605
 
                close(pInfo->fd);
606
 
                pInfo->fd = -1;
607
 
        }
 
674
        wcmClose(pInfo);
608
675
 
609
676
        /* only link them once per port. We need to try for both tablet tool
610
677
         * and touch since we do not know which tool will be added first.
622
689
        if (common && priv)
623
690
                common->wcmDevices = priv->next;
624
691
 
625
 
        if (pInfo->fd != -1)
626
 
        {
627
 
                close(pInfo->fd);
628
 
                pInfo->fd = -1;
629
 
        }
630
 
 
 
692
        wcmClose(pInfo);
631
693
        free(type);
632
694
        free(oldname);
633
695
        return BadMatch;
642
704
        wcmUninit, /* un-init */
643
705
        NULL,          /* module */
644
706
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
645
 
        default_options
 
707
        default_options,
 
708
#endif
 
709
#ifdef XI86_DRV_CAP_SERVER_FD
 
710
        XI86_DRV_CAP_SERVER_FD,
646
711
#endif
647
712
};
648
713