Peter Hutterer wrote:
Now you can
xinput do-stuff [MOUSE-0]

Two things:
- How about an array notation in the form or MOUSE[1]?
  (and make MOUSE[] to have the same behaviour for your current [MOUSE-0])
That's what the attached patch does. So the above is now MOUSE[0].
- I'd prefer a commandline-switch --by-type to trigger this, rather than
  guessing from the name of the device.
Yeah, that's more extensible and more work - likely I'd have to revamp parsing. This change doesn't block that path, so this can be done when ambiguous cases show up.

What should be checked, is that this notation doesn't collide with whatever HAL or evdev do to disambiguate names (if they do at all). I don't have 2 equal mice, do you? (Does anyone?)

Cheers,

Simon
>From a378b61a5c2b65312cd3f000dfab4f84972dc80f Mon Sep 17 00:00:00 2001
From: Simon Thum <[email protected]>
Date: Thu, 26 Mar 2009 15:15:26 +0100
Subject: [PATCH] xinput: new syntax to select devices by type and index

Introduces a type-based index notation Type[Num] (the brackets
are literal). Type specifies the device type, Num is 1 for the
first device, 2 for the second and so on. 0 means select the
only device of this type; it fails when more than one device
has the specified type.

This is useful for scripting, since device type is much more
constant and portable than XIDs or device names. For example,
MOUSE[0] is a sensible default for 'the mouse that's plugged'.

Also, states clearly when device selection fails just because
it selects an extension device.
---
 man/xinput.man |    6 ++++-
 src/xinput.c   |   58 ++++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 51 insertions(+), 13 deletions(-)

diff --git a/man/xinput.man b/man/xinput.man
index eeee7b9..2dd196c 100644
--- a/man/xinput.man
+++ b/man/xinput.man
@@ -84,7 +84,11 @@ loop displaying events received. If the -proximity is given, 
ProximityIn
 and ProximityOut are registered.
 .PP
 \fIdevice_name\fP can be the device name as a string or the XID of the
-device.
+device. Also possible is a type-based index notation \fIType[Num]\fP
+(the brackets are literal).
+\fIType\fP specifies the device type, \fINum\fP is 1 for the first
+device, 2 for the second and so on. 0 means select the only device of
+this type; it fails when more than one device has the specified type.  
 .PP
 \fIproperty\fP can be the property as a string or the Atom value.
 .PP
diff --git a/src/xinput.c b/src/xinput.c
index 466a814..b149981 100644
--- a/src/xinput.c
+++ b/src/xinput.c
@@ -166,8 +166,10 @@ find_device_info(Display   *display,
     int                loop;
     int                num_devices;
     int                len = strlen(name);
-    Bool       is_id = True;
+    Bool       is_id = True, is_locator = False, is_name;
     XID                id = (XID)-1;
+    int                loc_num;
+    char       loc_type[100];
 
     for(loop=0; loop<len; loop++) {
        if (!isdigit(name[loop])) {
@@ -178,24 +180,56 @@ find_device_info(Display  *display,
 
     if (is_id) {
        id = atoi(name);
+    }else{
+       if(sscanf(name, "%[A-Z_a-z ][%i]", loc_type, &loc_num) == 2) {
+           is_locator = True;
+       }
     }
 
+    is_name = !is_id && !is_locator;
+
     devices = XListInputDevices(display, &num_devices);
 
-    for(loop=0; loop<num_devices; loop++) {
-       if ((!only_extended || (devices[loop].use >= IsXExtensionDevice)) &&
-           ((!is_id && strcmp(devices[loop].name, name) == 0) ||
-            (is_id && devices[loop].id == id))) {
-           if (found) {
-               fprintf(stderr,
-                       "Warning: There are multiple devices named \"%s\".\n"
-                       "To ensure the correct one is selected, please use "
-                       "the device ID instead.\n\n", name);
-           } else {
-               found = &devices[loop];
+    if(is_name || is_id){
+       for(loop=0; loop<num_devices; loop++) {
+           if ((is_name && strcmp(devices[loop].name, name) == 0) ||
+               (is_id && devices[loop].id == id)) {
+               if (found) {
+                   fprintf(stderr,
+                           "Warning: There are multiple devices named 
\"%s\".\n"
+                           "To ensure the correct one is selected, please use "
+                           "the device ID instead.\n\n", name);
+               } else {
+                   found = &devices[loop];
+               }
+           }
+       }
+    }else if (is_locator) {
+       for(loop=0; loop<num_devices; loop++) {
+           if (devices[loop].type != None &&
+               strcmp(XGetAtomName(display, devices[loop].type),
+                      loc_type) == 0) {
+               //Handle zero -> find only device of given type
+               if(loc_num == 0 && !found) {
+                   found = &devices[loop];
+               }else if(loc_num == 0 && found) {
+                   fprintf(stderr,
+                           "Error: selecting only device failed because there"
+                           "are multiple devices with type %s.\n\n", loc_type);
+                   return 0;
+               }else if(loc_num > 1) {
+                   loc_num--; //countdown
+               }else if(loc_num == 1 && !found) {
+                   found = &devices[loop];
+               }
            }
        }
     }
+
+    if (found && only_extended && (found->use >= IsXExtensionDevice)){
+       fprintf(stderr, "Extension device ignored.\n\n");
+       return 0;
+    }
     return found;
 }
 
-- 
1.6.0.6

_______________________________________________
xorg-devel mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to