[PATCH] xinput: new syntax to select devices by type and index
Simon Thum
simon.thum at gmx.de
Thu Mar 26 07:15:26 PDT 2009
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
--------------040703070003070605010800--
More information about the xorg-devel
mailing list