[PATCH] xinput: new syntax to select devices by type

Simon Thum simon.thum at gmx.de
Thu Mar 26 07:15:26 PDT 2009


see manpage changes for details. Also, states clearly
when device selection fails because it is a 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 c9ff46f..f66fd71 100644
--- a/man/xinput.man
+++ b/man/xinput.man
@@ -80,7 +80,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 locator notation \fI[Type-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..7dde29b 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, 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


--------------080606040309010904020003
Content-Type: text/plain;
 name="0003-xinput-mention-set-float-prop-in-manpage.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="0003-xinput-mention-set-float-prop-in-manpage.patch"



More information about the xorg-devel mailing list