#include <ctype.h>
#include <string.h>
+int xi_opcode;
+
typedef int (*prog)(Display* display, int argc, char *argv[],
char *prog_name, char *prog_desc);
set_mode
},
{"list",
- "[--loop || --short || <device name>...]",
+ "[--short || --long] [<device name>...]",
list
},
{"query-state",
"[-proximity] <device name>",
test
},
- {"version",
- "",
- version
- },
#if HAVE_XI2
{ "create-master",
- "<id> [sendCore (dflt:1)] [enable (dflt:1)]",
+ "<id> [<sendCore (dflt:1)>] [<enable (dflt:1)>]",
create_master
},
{ "remove-master",
- "<id> [returnMode (dflt:Floating)] [returnPointer] [returnKeyboard]",
+ "<id> [Floating|AttachToMaster (dflt:Floating)] [<returnPointer>] [<returnKeyboard>]",
remove_master
},
{ "reattach",
delete_prop
},
{ "set-prop",
- "<device> <property> <val> [<val> ...]",
+ "<device> [--type=atom|float|int] [--format=8|16|32] <property> <val> [<val> ...]",
set_prop
},
{NULL, NULL, NULL
}
};
+static const char version_id[] = VERSION;
+
+int
+print_version()
+{
+ XExtensionVersion *version;
+ Display *display;
+
+ printf("xinput version %s\n", version_id);
+
+ display = XOpenDisplay(NULL);
+
+ printf("XI version on server: ");
+
+ if (display == NULL)
+ printf("Failed to open display.\n");
+ else {
+ version = XGetExtensionVersion(display, INAME);
+ if (!version || (version == (XExtensionVersion*) NoSuchExtension))
+ printf(" Extension not supported.\n");
+ else {
+ printf("%d.%d\n", version->major_version,
+ version->minor_version);
+ XFree(version);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
int
xinput_version(Display *display)
{
}
#ifdef HAVE_XI2
-int
-xi2_find_device_id(Display *display, char *name)
+Bool is_pointer(int use)
+{
+ return use == XIMasterPointer || use == XISlavePointer;
+}
+
+Bool is_keyboard(int use)
+{
+ return use == XIMasterKeyboard || use == XISlaveKeyboard;
+}
+
+Bool device_matches(XIDeviceInfo *info, char *name)
+{
+ if (strcmp(info->name, name) == 0) {
+ return True;
+ }
+
+ if (strncmp(name, "pointer:", strlen("pointer:")) == 0 &&
+ strcmp(info->name, name + strlen("pointer:")) == 0 &&
+ is_pointer(info->use)) {
+ return True;
+ }
+
+ if (strncmp(name, "keyboard:", strlen("keyboard:")) == 0 &&
+ strcmp(info->name, name + strlen("keyboard:")) == 0 &&
+ is_keyboard(info->use)) {
+ return True;
+ }
+
+ return False;
+}
+
+XIDeviceInfo*
+xi2_find_device_info(Display *display, char *name)
{
XIDeviceInfo *info;
+ XIDeviceInfo *found = NULL;
int ndevices;
Bool is_id = True;
int i, id = -1;
if (is_id) {
id = atoi(name);
- } else
+ }
+
+ info = XIQueryDevice(display, XIAllDevices, &ndevices);
+ for(i = 0; i < ndevices; i++)
{
- info = XIQueryDevice(display, AllDevices, &ndevices);
- for(i = 0; i < ndevices; i++)
- {
- if ((is_id && info[i].deviceid == id) ||
- (!is_id && strcmp(info[i].name, name) == 0))
- {
- id = info[i].deviceid;
- break;
+ if (is_id ? info[i].deviceid == id : device_matches (&info[i], name)) {
+ if (found) {
+ fprintf(stderr,
+ "Warning: There are multiple devices matching '%s'.\n"
+ "To ensure the correct one is selected, please use "
+ "the device ID, or prefix the\ndevice name with "
+ "'pointer:' or 'keyboard:' as appropriate.\n\n", name);
+ XIFreeDeviceInfo(info);
+ return NULL;
+ } else {
+ found = &info[i];
}
}
-
- XIFreeDeviceInfo(info);
}
- return id;;
+
+ return found;
}
#endif
Display *display;
entry *driver = drivers;
char *func;
+ int event, error;
if (argc < 2) {
usage();
return EXIT_FAILURE;
}
+ func = argv[1];
+ while((*func) == '-') func++;
+
+ if (strcmp("version", func) == 0) {
+ return print_version(argv[0]);
+ }
+
display = XOpenDisplay(NULL);
if (display == NULL) {
return EXIT_FAILURE;
}
- func = argv[1];
- while((*func) == '-') func++;
+ if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) {
+ printf("X Input extension not available.\n");
+ return EXIT_FAILURE;
+ }
if (!xinput_version(display)) {
fprintf(stderr, "%s extension not available\n", INAME);