On Thu, Mar 6, 2014 at 3:50 PM, Peter Hutterer <peter.hutte...@who-t.net> wrote:
> On Mon, Feb 24, 2014 at 01:31:54PM -0800, Jason Gerecke wrote:
>> This is a re-submission of Ping's earlier touchswitch patches, updated
>> to address the bug that I had discovered. Correctly associating the
>> correct pen and touch "halves" of a single device under all conditions
>> proved to be a bit more difficult than expected, so I've fixed it as
>> best I can.
>>
>> The revised code should work in all cases that worked before, but with
>> fewer false-positives and false-negatives. The only tablet I'm aware of
>> which still foils the scheme is the Cintiq Companion Hybrid, due to its
>> EMR and MFT kernel devices having different names. If somebody is bored
>> and familiar with libudev, they might be able to come up with something
>> even more accurate.
>
> I found the code below in my junk-code directory, and it works for my 0xE6
> here. Benjamin pasted a udevadm output for a 22HDT and the problem there is
> that there are multiple parents. So the code we'll need is a bit more
> complicated, looks like you need to go up the parents to find the top-most
> with ID_VENDOR_ID=056a.
>
> The tree looks something like this:
>  - USB hub
>    DEVTYPE=usb_device
>    ID_VENDOR_ID=xyz
>    \
>     - Cintiq_22HDT_HUB
>       DEVTYPE=usb_device
>       ID_VENDOR_ID=056a
>       \
>        - Cintiq_22HDT_TOUCH
>          DEVTYPE=usb_device
>          ID_VENDOR_ID=056a
>          \
>            - the "Finger" eventX device is somewhere in here
>       \
>        - Cintiq_22HDT_Tablet
>          DEVTYPE=usb_device
>          ID_VENDOR_ID=056a
>          \
>            - the "Pen" eventX device is somewhere in here
>
> so in pseudocode something like:
>
> next_parent = device;
> while (next_parent = 
> udev_device_get_parent_with_subsystem_devtype(next_parent, "usb", 
> "usb_device")) {
>     vendor_id = udev_device_get_property_value(next_parent, "ID_VENDOR_ID");
>     if (strcmp(vendor_id, "056a") == 0)
>         real_parent = next_parent;
> }
>
> then you can get the top-most parent device for the tablet. And that should
> be the same for Finger and Touch, regardless of naming, regardless of the
> kernel driver being used (Benjamin's udev output used hid-mt, the tree may
> be less deep if you have the same kernel driver).
>
> Do that for both devices and if the syspath is the same, you have the same
> device. I think, this needs testing with the newer tablets that I don't have
> right here, and especially with multiple tablets plugged in too.
> And obiously you'll want to use the device's vendor_id, not a hardcoded
> string :)
>
> Cheers,
>    Peter
>
Simply traversing the parents and stopping at the last 0x56a device
doesn't cut it for the Cintiq 24HDT, unfortunately. The internal hub
for the 22HDT and the Companion Hybrid both seem to use our VID, but
my 24HDT has a hub with VID 0x409 (NEC Corp). Also, the Cintiq's have
an external USB port that a user could connect a second tablet to,
potentially triggering incorrect cross-device links.

It could be useful as an additional check, but its not the silver
bullet I'd like...

Jason
---
Now instead of four in the eights place /
you’ve got three, ‘Cause you added one  /
(That is to say, eight) to the two,     /
But you can’t take seven from three,    /
So you look at the sixty-fours....


>
> $> cat udev-same-parent.c
>
> #include <stdio.h>
> #include <libudev.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <unistd.h>
> #include <string.h>
> #include <stdlib.h>
>
> static struct udev_device *udev_from_file(struct udev *udev, const char 
> *filename)
> {
>     struct stat st;
>     stat(filename, &st);
>     return udev_device_new_from_devnum(udev, 'c', st.st_rdev);
> }
>
> int main(int argc, char** argv)
> {
>     int rc = 1;
>     struct udev *udev = NULL;
>     struct udev_device *dev1, *dev2 = NULL;
>     struct udev_device *parent1, *parent2;
>     const char *syspath1, *syspath2;
>
>     if (argc < 3)
>         goto out;
>
>     udev = udev_new();
>     dev1 = udev_from_file(udev, argv[1]);
>     dev2 = udev_from_file(udev, argv[2]);
>
>     if (!dev1 || !dev2)
>         goto out;
>
>     parent1 = udev_device_get_parent_with_subsystem_devtype(dev1, "usb", 
> "usb_device");
>     parent2 = udev_device_get_parent_with_subsystem_devtype(dev2, "usb", 
> "usb_device");
>
>     syspath1 = udev_device_get_syspath(parent1);
>     syspath2 = udev_device_get_syspath(parent2);
>
>     if (strcmp(syspath1, syspath2) == 0)
>         printf("Yep, they're the same physical device\n");
>     else
>         printf("Nope, different devices\n");
>
> out:
>     udev_device_unref(dev1);
>     udev_device_unref(dev2);
>     udev_unref(udev);
>     return rc;
> }
>

------------------------------------------------------------------------------
Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce.
With Perforce, you get hassle-free workflows. Merge that actually works. 
Faster operations. Version large binaries.  Built-in WAN optimization and the
freedom to use Git, Perforce or both. Make the move to Perforce.
http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to