summaryrefslogtreecommitdiff
path: root/app/xinput/src
diff options
context:
space:
mode:
Diffstat (limited to 'app/xinput/src')
-rw-r--r--app/xinput/src/Makefile.am5
-rw-r--r--app/xinput/src/Makefile.in17
-rw-r--r--app/xinput/src/hierarchy.c134
-rw-r--r--app/xinput/src/list.c260
-rw-r--r--app/xinput/src/property.c684
-rw-r--r--app/xinput/src/setcp.c13
-rw-r--r--app/xinput/src/test_xi2.c381
-rw-r--r--app/xinput/src/version.c43
-rw-r--r--app/xinput/src/xinput.c130
-rw-r--r--app/xinput/src/xinput.h289
10 files changed, 1293 insertions, 663 deletions
diff --git a/app/xinput/src/Makefile.am b/app/xinput/src/Makefile.am
index 1efddb888..ba0d325ac 100644
--- a/app/xinput/src/Makefile.am
+++ b/app/xinput/src/Makefile.am
@@ -26,8 +26,8 @@ xinput_LDADD = $(XINPUT_LIBS)
if HAVE_XI2
- xinput2_files = hierarchy.c setcp.c
-endif # HAVE_XI2
+xinput2_files = hierarchy.c setcp.c test_xi2.c
+endif
xinput_SOURCES = \
buttonmap.c \
@@ -39,7 +39,6 @@ xinput_SOURCES = \
state.c \
property.c \
test.c \
- version.c \
xinput.c \
xinput.h \
$(xinput2_files)
diff --git a/app/xinput/src/Makefile.in b/app/xinput/src/Makefile.in
index 040d73972..4ba411ca1 100644
--- a/app/xinput/src/Makefile.in
+++ b/app/xinput/src/Makefile.in
@@ -71,14 +71,14 @@ am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am__xinput_SOURCES_DIST = buttonmap.c feedback.c list.c setint.c \
- setmode.c setptr.c state.c property.c test.c version.c \
- xinput.c xinput.h hierarchy.c setcp.c
-@HAVE_XI2_TRUE@am__objects_1 = hierarchy.$(OBJEXT) setcp.$(OBJEXT)
+ setmode.c setptr.c state.c property.c test.c xinput.c xinput.h \
+ hierarchy.c setcp.c test_xi2.c
+@HAVE_XI2_TRUE@am__objects_1 = hierarchy.$(OBJEXT) setcp.$(OBJEXT) \
+@HAVE_XI2_TRUE@ test_xi2.$(OBJEXT)
am_xinput_OBJECTS = buttonmap.$(OBJEXT) feedback.$(OBJEXT) \
list.$(OBJEXT) setint.$(OBJEXT) setmode.$(OBJEXT) \
setptr.$(OBJEXT) state.$(OBJEXT) property.$(OBJEXT) \
- test.$(OBJEXT) version.$(OBJEXT) xinput.$(OBJEXT) \
- $(am__objects_1)
+ test.$(OBJEXT) xinput.$(OBJEXT) $(am__objects_1)
xinput_OBJECTS = $(am_xinput_OBJECTS)
am__DEPENDENCIES_1 =
xinput_DEPENDENCIES = $(am__DEPENDENCIES_1)
@@ -158,6 +158,8 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
+XI2_CFLAGS = @XI2_CFLAGS@
+XI2_LIBS = @XI2_LIBS@
XINPUT_CFLAGS = @XINPUT_CFLAGS@
XINPUT_LIBS = @XINPUT_LIBS@
ac_ct_CC = @ac_ct_CC@
@@ -206,7 +208,7 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
AM_CFLAGS = $(XINPUT_CFLAGS)
xinput_LDADD = $(XINPUT_LIBS)
-@HAVE_XI2_TRUE@xinput2_files = hierarchy.c setcp.c
+@HAVE_XI2_TRUE@xinput2_files = hierarchy.c setcp.c test_xi2.c
xinput_SOURCES = \
buttonmap.c \
feedback.c \
@@ -217,7 +219,6 @@ xinput_SOURCES = \
state.c \
property.c \
test.c \
- version.c \
xinput.c \
xinput.h \
$(xinput2_files)
@@ -299,7 +300,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setptr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_xi2.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xinput.Po@am__quote@
.c.o:
diff --git a/app/xinput/src/hierarchy.c b/app/xinput/src/hierarchy.c
index 869c3fd8e..7f35c3988 100644
--- a/app/xinput/src/hierarchy.c
+++ b/app/xinput/src/hierarchy.c
@@ -40,7 +40,7 @@
int
create_master(Display* dpy, int argc, char** argv, char* name, char *desc)
{
- XCreateMasterInfo c;
+ XIAddMasterInfo c;
if (argc == 0)
{
@@ -48,12 +48,12 @@ create_master(Display* dpy, int argc, char** argv, char* name, char *desc)
return EXIT_FAILURE;
}
- c.type = CH_CreateMasterDevice;
+ c.type = XIAddMaster;
c.name = argv[0];
- c.sendCore = (argc >= 2) ? atoi(argv[1]) : 1;
+ c.send_core = (argc >= 2) ? atoi(argv[1]) : 1;
c.enable = (argc >= 3) ? atoi(argv[2]) : 1;
- return XChangeDeviceHierarchy(dpy, (XAnyHierarchyChangeInfo*)&c, 1);
+ return XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
}
/**
@@ -64,9 +64,8 @@ create_master(Display* dpy, int argc, char** argv, char* name, char *desc)
int
remove_master(Display* dpy, int argc, char** argv, char *name, char *desc)
{
- XDeviceInfo *info;
- XRemoveMasterInfo r;
- XDevice* master = NULL, *ptr = NULL, *keybd = NULL;
+ XIRemoveMasterInfo r;
+ XIDeviceInfo *info;
int ret;
if (argc == 0)
@@ -75,45 +74,67 @@ remove_master(Display* dpy, int argc, char** argv, char *name, char *desc)
return EXIT_FAILURE;
}
- info = find_device_info(dpy, argv[0], False);
+ info = xi2_find_device_info(dpy, argv[0]);
if (!info) {
fprintf(stderr, "unable to find device %s\n", argv[0]);
return EXIT_FAILURE;
}
- master = XOpenDevice(dpy, info->id);
- if (!master)
- Error(BadValue, "Unable to open device %s.\n", argv[0]);
-
- r.type = CH_RemoveMasterDevice;
- r.device = master;
+ r.type = XIRemoveMaster;
+ r.deviceid = info->deviceid;
if (argc >= 2)
{
if (!strcmp(argv[1], "Floating"))
- r.returnMode = Floating;
+ r.return_mode = XIFloating;
else if (!strcmp(argv[1], "AttachToMaster"))
- r.returnMode = AttachToMaster;
+ r.return_mode = XIAttachToMaster;
else
- Error(BadValue, "Invalid returnMode.\n");
+ Error(BadValue, "Invalid return_mode.\n");
} else
- r.returnMode = Floating;
+ r.return_mode = XIFloating;
- if (r.returnMode == AttachToMaster)
+ if (r.return_mode == XIAttachToMaster)
{
- ptr = XOpenDevice(dpy, atoi(argv[2]));
- keybd = XOpenDevice(dpy, atoi(argv[3]));
- if (!ptr || !keybd)
- Error(BadValue, "Invalid fallback master.\n");
- r.returnPointer = ptr;
- r.returnKeyboard = keybd;
+ r.return_pointer = 0;
+ if (argc >= 3) {
+ info = xi2_find_device_info(dpy, argv[2]);
+ if (!info) {
+ fprintf(stderr, "unable to find device %s\n", argv[2]);
+ return EXIT_FAILURE;
+ }
+
+ r.return_pointer = info->deviceid;
+ }
+
+ r.return_keyboard = 0;
+ if (argc >= 4) {
+ info = xi2_find_device_info(dpy, argv[3]);
+ if (!info) {
+ fprintf(stderr, "unable to find device %s\n", argv[3]);
+ return EXIT_FAILURE;
+ }
+
+ r.return_keyboard = info->deviceid;
+ }
+
+ if (!r.return_pointer || !r.return_keyboard) {
+ int i, ndevices;
+ info = XIQueryDevice(dpy, XIAllMasterDevices, &ndevices);
+ for(i = 0; i < ndevices; i++) {
+ if (info[i].use == XIMasterPointer && !r.return_pointer)
+ r.return_pointer = info[i].deviceid;
+ if (info[i].use == XIMasterKeyboard && !r.return_keyboard)
+ r.return_keyboard = info[i].deviceid;
+ if (r.return_pointer && r.return_keyboard)
+ break;
+ }
+
+ XIFreeDeviceInfo(info);
+ }
}
- ret = XChangeDeviceHierarchy(dpy, (XAnyHierarchyChangeInfo*)&r, 1);
- if (ptr)
- XCloseDevice(dpy, ptr);
- if (keybd)
- XCloseDevice(dpy, keybd);
+ ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&r, 1);
return ret;
}
@@ -123,9 +144,8 @@ remove_master(Display* dpy, int argc, char** argv, char *name, char *desc)
int
change_attachment(Display* dpy, int argc, char** argv, char *name, char* desc)
{
- XDeviceInfo *info_sd, *info_md;
- XChangeAttachmentInfo c;
- XDevice *slave, *master;
+ XIDeviceInfo *sd_info, *md_info;
+ XIAttachSlaveInfo c;
int ret;
if (argc < 2)
@@ -134,36 +154,24 @@ change_attachment(Display* dpy, int argc, char** argv, char *name, char* desc)
return EXIT_FAILURE;
}
- info_sd = find_device_info(dpy, argv[0], True);
- info_md = find_device_info(dpy, argv[1], False);
+ sd_info = xi2_find_device_info(dpy, argv[0]);
+ md_info= xi2_find_device_info(dpy, argv[1]);
- if (!info_sd) {
+ if (!sd_info) {
fprintf(stderr, "unable to find device %s\n", argv[0]);
return EXIT_FAILURE;
}
- if (!info_md) {
+ if (!md_info) {
fprintf(stderr, "unable to find device %s\n", argv[1]);
return EXIT_FAILURE;
}
- slave = XOpenDevice(dpy, info_sd->id);
- master = XOpenDevice(dpy, info_md->id);
-
- if (!slave)
- Error(BadValue, "Invalid slave device given %d\n", atoi(argv[0]));
-
- if (!master)
- Error(BadValue, "Invalid master device given %d\n", atoi(argv[1]));
+ c.type = XIAttachSlave;
+ c.deviceid = sd_info->deviceid;
+ c.new_master = md_info->deviceid;
- c.type = CH_ChangeAttachment;
- c.changeMode = AttachToMaster;
- c.device = slave;
- c.newMaster = master;
-
- ret = XChangeDeviceHierarchy(dpy, (XAnyHierarchyChangeInfo*)&c, 1);
- XCloseDevice(dpy, slave);
- XCloseDevice(dpy, master);
+ ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
return ret;
}
@@ -173,9 +181,8 @@ change_attachment(Display* dpy, int argc, char** argv, char *name, char* desc)
int
float_device(Display* dpy, int argc, char** argv, char* name, char* desc)
{
- XDeviceInfo *info;
- XChangeAttachmentInfo c;
- XDevice *slave;
+ XIDeviceInfo *info;
+ XIDetachSlaveInfo c;
int ret;
if (argc < 1)
@@ -184,24 +191,17 @@ float_device(Display* dpy, int argc, char** argv, char* name, char* desc)
return EXIT_FAILURE;
}
- info = find_device_info(dpy, argv[0], True);
+ info = xi2_find_device_info(dpy, argv[0]);
if (!info) {
fprintf(stderr, "unable to find device %s\n", argv[0]);
return EXIT_FAILURE;
}
- slave = XOpenDevice(dpy, info->id);
-
- if (!slave)
- return BadValue;
-
- c.type = CH_ChangeAttachment;
- c.changeMode = Floating;
- c.device = slave;
+ c.type = XIDetachSlave;
+ c.deviceid = info->deviceid;
- ret = XChangeDeviceHierarchy(dpy, (XAnyHierarchyChangeInfo*)&c, 1);
- XCloseDevice(dpy, slave);
+ ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
return ret;
}
diff --git a/app/xinput/src/list.c b/app/xinput/src/list.c
index bd71a5ccc..ecf1f4ba5 100644
--- a/app/xinput/src/list.c
+++ b/app/xinput/src/list.c
@@ -34,9 +34,6 @@ print_info(Display* dpy, XDeviceInfo *info, Bool shortformat)
XButtonInfoPtr b;
XValuatorInfoPtr v;
XAxisInfoPtr a;
-#if HAVE_XI2
- XAttachInfoPtr att;
-#endif
printf("\"%s\"\tid=%ld\t[", info->name, info->id);
@@ -98,12 +95,6 @@ print_info(Display* dpy, XDeviceInfo *info, Bool shortformat)
printf ("\t\tResolution is %d\n", a->resolution);
}
break;
-#if HAVE_XI2
- case AttachClass:
- att = (XAttachInfoPtr)any;
- printf("\tAttached to %d\n", att->attached);
- break;
-#endif
default:
printf ("unknown class\n");
}
@@ -112,78 +103,221 @@ print_info(Display* dpy, XDeviceInfo *info, Bool shortformat)
}
}
-int
-list(Display *display,
- int argc,
- char *argv[],
- char *name,
- char *desc)
+static int list_xi1(Display *display,
+ int shortformat)
{
XDeviceInfo *info;
int loop;
- int shortformat = False;
- int daemon = False;
+ int num_devices;
- shortformat = (argc == 1 && strcmp(argv[0], "--short") == 0);
- daemon = (argc == 1 && strcmp(argv[0], "--loop") == 0);
+ info = XListInputDevices(display, &num_devices);
+ for(loop=0; loop<num_devices; loop++) {
+ print_info(display, info+loop, shortformat);
+ }
+ return EXIT_SUCCESS;
+}
- if (argc == 0 || shortformat || daemon) {
- int num_devices;
- XEvent ev;
+#ifdef HAVE_XI2
+/* also used from test_xi2.c */
+void
+print_classes_xi2(Display* display, XIAnyClassInfo **classes,
+ int num_classes)
+{
+ int i, j;
-#if HAVE_XI2
- if (daemon)
+ printf("\tReporting %d classes:\n", num_classes);
+ for (i = 0; i < num_classes; i++)
+ {
+ printf("\t\tClass originated from: %d\n", classes[i]->sourceid);
+ switch(classes[i]->type)
{
- XiSelectEvent(display, DefaultRootWindow(display), NULL,
- XI_DeviceHierarchyChangedMask |
- XI_DeviceClassesChangedMask);
+ case XIButtonClass:
+ {
+ XIButtonClassInfo *b = (XIButtonClassInfo*)classes[i];
+ char *name;
+ printf("\t\tButtons supported: %d\n", b->num_buttons);
+ printf("\t\tButton labels:");
+ for (j = 0; j < b->num_buttons; j++)
+ {
+ name = (b->labels[j]) ? XGetAtomName(display, b->labels[j]) : NULL;
+ printf(" %s", (name) ? name : "None");
+ XFree(name);
+ }
+ printf("\n");
+ printf("\t\tButton state:");
+ for (j = 0; j < b->state.mask_len * 8; j++)
+ if (XIMaskIsSet(b->state.mask, j))
+ printf(" %d", j);
+ printf("\n");
+
+ }
+ break;
+ case XIKeyClass:
+ {
+ XIKeyClassInfo *k = (XIKeyClassInfo*)classes[i];
+ printf("\t\tKeycodes supported: %d\n", k->num_keycodes);
+ }
+ break;
+ case XIValuatorClass:
+ {
+ XIValuatorClassInfo *v = (XIValuatorClassInfo*)classes[i];
+ char *name = v->label ? XGetAtomName(display, v->label) : NULL;
+
+ printf("\t\tDetail for Valuator %d:\n", v->number);
+ printf("\t\t Label: %s\n", (name) ? name : "None");
+ printf("\t\t Range: %f - %f\n", v->min, v->max);
+ printf("\t\t Resolution: %d units/m\n", v->resolution);
+ printf("\t\t Mode: %s\n", v->mode == Absolute ? "absolute" :
+ "relative");
+ if (v->mode == Absolute)
+ printf("\t\t Current value: %f\n", v->value);
+ XFree(name);
+ }
+ break;
}
-#endif
+ }
- do {
- info = XListInputDevices(display, &num_devices);
- for(loop=0; loop<num_devices; loop++) {
- print_info(display, info+loop, shortformat);
- }
+ printf("\n");
+}
-#if HAVE_XI2
- /* just wait for the next generic event to come along */
- while (daemon && !XNextEvent(display, &ev))
+static void
+print_info_xi2(Display* display, XIDeviceInfo *dev, Bool shortformat)
+{
+ printf("%-40s\tid=%d\t[", dev->name, dev->deviceid);
+ switch(dev->use)
+ {
+ case XIMasterPointer:
+ printf("master pointer (%d)]\n", dev->attachment);
+ break;
+ case XIMasterKeyboard:
+ printf("master keyboard (%d)]\n", dev->attachment);
+ break;
+ case XISlavePointer:
+ printf("slave pointer (%d)]\n", dev->attachment);
+ break;
+ case XISlaveKeyboard:
+ printf("slave keyboard (%d)]\n", dev->attachment);
+ break;
+ case XIFloatingSlave:
+ printf("floating slave]\n");
+ break;
+ }
+
+ if (shortformat)
+ return;
+
+ if (!dev->enabled)
+ printf("\tThis device is disabled\n");
+
+ print_classes_xi2(display, dev->classes, dev->num_classes);
+}
+
+
+static int
+list_xi2(Display *display,
+ int shortformat)
+{
+ int major = XI_2_Major,
+ minor = XI_2_Minor;
+ int ndevices;
+ int i, j;
+ XIDeviceInfo *info, *dev;
+
+ if (XIQueryVersion(display, &major, &minor) != Success ||
+ (major * 1000 + minor) < (XI_2_Major * 1000 + XI_2_Minor))
+ {
+ fprintf(stderr, "XI2 not supported.\n");
+ return EXIT_FAILURE;
+ }
+
+ info = XIQueryDevice(display, XIAllDevices, &ndevices);
+
+ for(i = 0; i < ndevices; i++)
+ {
+ dev = &info[i];
+ if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
+ {
+ if (dev->use == XIMasterPointer)
+ printf("⎡ ");
+ else
+ printf("⎣ ");
+
+ print_info_xi2(display, dev, shortformat);
+ for (j = 0; j < ndevices; j++)
{
- if (ev.type == GenericEvent)
+ XIDeviceInfo* sd = &info[j];
+
+ if ((sd->use == XISlavePointer || sd->use == XISlaveKeyboard) &&
+ (sd->attachment == dev->deviceid))
{
- XGenericEvent* gev = (XGenericEvent*)&ev;
- /* we just assume that extension is IReqCode, pretty save
- since we don't register for other events. */
- if (gev->evtype == XI_DeviceHierarchyChangedNotify)
- {
- printf("Hierarchy change.\n");
- } else if (gev->evtype == XI_DeviceClassesChangedNotify)
- {
- printf("Device classes changed.\n");
- free(((XDeviceClassesChangedEvent*)&ev)->inputclassinfo);
- }
- break;
+ printf("%s ↳ ", dev->use == XIMasterPointer ? "⎜" : " ");
+ print_info_xi2(display, sd, shortformat);
}
}
+ }
+ }
+
+ for (i = 0; i < ndevices; i++)
+ {
+ dev = &info[i];
+ if (dev->use == XIFloatingSlave)
+ {
+ printf("∼ ");
+ print_info_xi2(display, dev, shortformat);
+ }
+ }
+
+
+ XIFreeDeviceInfo(info);
+ return EXIT_SUCCESS;
+}
#endif
- } while(daemon);
- } else {
- int ret = EXIT_SUCCESS;
- for(loop=0; loop<argc; loop++) {
- info = find_device_info(display, argv[loop], False);
+int
+list(Display *display,
+ int argc,
+ char *argv[],
+ char *name,
+ char *desc)
+{
+ int shortformat = (argc >= 1 && strcmp(argv[0], "--short") == 0);
+ int longformat = (argc >= 1 && strcmp(argv[0], "--long") == 0);
+ int arg_dev = shortformat || longformat;
- if (!info) {
- fprintf(stderr, "unable to find device %s\n", argv[loop]);
- ret = EXIT_FAILURE;
- } else {
- print_info(display, info, shortformat);
- }
- }
- return ret;
+ if (argc > arg_dev)
+ {
+#ifdef HAVE_XI2
+ if (xinput_version(display) == XI_2_Major)
+ {
+ XIDeviceInfo *info = xi2_find_device_info(display, argv[arg_dev]);
+
+ if (!info) {
+ fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
+ return EXIT_FAILURE;
+ } else {
+ print_info_xi2(display, info, shortformat);
+ return EXIT_SUCCESS;
+ }
+ } else
+#endif
+ {
+ XDeviceInfo *info = find_device_info(display, argv[arg_dev], False);
+
+ if (!info) {
+ fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
+ return EXIT_FAILURE;
+ } else {
+ print_info(display, info, shortformat);
+ return EXIT_SUCCESS;
+ }
+ }
+ } else {
+#ifdef HAVE_XI2
+ if (xinput_version(display) == XI_2_Major)
+ return list_xi2(display, !longformat);
+#endif
+ return list_xi1(display, !longformat);
}
- return EXIT_SUCCESS;
}
/* end of list.c */
diff --git a/app/xinput/src/property.c b/app/xinput/src/property.c
index 60565ed5e..6cd8e7af1 100644
--- a/app/xinput/src/property.c
+++ b/app/xinput/src/property.c
@@ -34,6 +34,23 @@
#include "xinput.h"
+static Atom parse_atom(Display *dpy, char *name) {
+ Bool is_atom = True;
+ int i;
+
+ for (i = 0; name[i] != '\0'; i++) {
+ if (!isdigit(name[i])) {
+ is_atom = False;
+ break;
+ }
+ }
+
+ if (is_atom)
+ return atoi(name);
+ else
+ return XInternAtom(dpy, name, False);
+}
+
static void
print_property(Display *dpy, XDevice* dev, Atom property)
{
@@ -55,6 +72,9 @@ print_property(Display *dpy, XDevice* dev, Atom property)
ptr = data;
+ if (nitems == 0)
+ printf("<no items>");
+
switch(act_format)
{
case 8: size = sizeof(char); break;
@@ -94,8 +114,13 @@ print_property(Display *dpy, XDevice* dev, Atom property)
the terminating 0 */
break;
case XA_ATOM:
- printf("\"%s\"", XGetAtomName(dpy, *(Atom*)ptr));
- break;
+ {
+ Atom a = *(Atom*)ptr;
+ printf("\"%s\" (%d)",
+ (a) ? XGetAtomName(dpy, a) : "None",
+ (int)a);
+ break;
+ }
default:
if (float_atom != None && act_type == float_atom)
{
@@ -111,10 +136,10 @@ print_property(Display *dpy, XDevice* dev, Atom property)
ptr += size;
- if (j < nitems - 1)
- printf(", ");
if (done == True)
break;
+ if (j < nitems - 1)
+ printf(", ");
}
printf("\n");
XFree(data);
@@ -123,7 +148,8 @@ print_property(Display *dpy, XDevice* dev, Atom property)
}
-int list_props(Display *dpy, int argc, char** argv, char* name, char *desc)
+static int
+list_props_xi1(Display *dpy, int argc, char** argv, char* name, char *desc)
{
XDeviceInfo *info;
XDevice *dev;
@@ -172,23 +198,19 @@ int list_props(Display *dpy, int argc, char** argv, char* name, char *desc)
return EXIT_SUCCESS;
}
-int
-set_int_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
+
+int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc)
{
- XDeviceInfo *info;
XDevice *dev;
- Atom prop;
+ XDeviceInfo *info;
+ XEvent ev;
+ XDevicePropertyNotifyEvent *dpev;
char *name;
- int i;
- Bool is_atom = True;
- char *data;
- int format, nelements = 0;
+ int type_prop;
+ XEventClass cls_prop;
- if (argc < 3)
- {
- fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
+ if (list_props(dpy, argc, argv, n, desc) != EXIT_SUCCESS)
return EXIT_FAILURE;
- }
info = find_device_info(dpy, argv[0], False);
if (!info)
@@ -200,71 +222,82 @@ set_int_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
dev = XOpenDevice(dpy, info->id);
if (!dev)
{
- fprintf(stderr, "unable to open device %s\n", argv[0]);
+ fprintf(stderr, "unable to open device '%s'\n", info->name);
return EXIT_FAILURE;
}
- name = argv[1];
+ DevicePropertyNotify(dev, type_prop, cls_prop);
+ XSelectExtensionEvent(dpy, DefaultRootWindow(dpy), &cls_prop, 1);
- for(i = 0; i < strlen(name); i++) {
- if (!isdigit(name[i])) {
- is_atom = False;
- break;
- }
+ while(1)
+ {
+ XNextEvent(dpy, &ev);
+
+ dpev = (XDevicePropertyNotifyEvent*)&ev;
+ if (dpev->type != type_prop)
+ continue;
+
+ name = XGetAtomName(dpy, dpev->atom);
+ printf("Property '%s' changed.\n", name);
+ print_property(dpy, dev, dpev->atom);
}
- if (!is_atom)
- prop = XInternAtom(dpy, name, False);
- else
- prop = atoi(name);
+ XCloseDevice(dpy, dev);
+}
- nelements = argc - 3;
- format = atoi(argv[2]);
- if (format != 8 && format != 16 && format != 32)
+static int
+delete_prop_xi1(Display *dpy, int argc, char** argv, char* n, char *desc)
+{
+ XDevice *dev;
+ XDeviceInfo *info;
+ char *name;
+ Atom prop;
+
+ info = find_device_info(dpy, argv[0], False);
+ if (!info)
{
- fprintf(stderr, "Invalid format %d\n", format);
+ fprintf(stderr, "unable to find device %s\n", argv[0]);
return EXIT_FAILURE;
}
- data = calloc(nelements, sizeof(long));
- for (i = 0; i < nelements; i++)
+ dev = XOpenDevice(dpy, info->id);
+ if (!dev)
{
- switch(format)
- {
- case 8:
- *(((char*)data) + i) = atoi(argv[3 + i]);
- break;
- case 16:
- *(((short*)data) + i) = atoi(argv[3 + i]);
- break;
- case 32:
- *(((long*)data) + i) = atoi(argv[3 + i]);
- break;
- }
+ fprintf(stderr, "unable to open device '%s'\n", info->name);
+ return EXIT_FAILURE;
}
- XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, format, PropModeReplace,
- (unsigned char*)data, nelements);
+ name = argv[1];
+
+ prop = parse_atom(dpy, name);
+
+ XDeleteDeviceProperty(dpy, dev, prop);
- free(data);
XCloseDevice(dpy, dev);
return EXIT_SUCCESS;
}
-int
-set_float_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
+static int
+do_set_prop_xi1(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc)
{
- XDeviceInfo *info;
- XDevice *dev;
- Atom prop, float_atom;
- char *name;
- int i;
- Bool is_atom = True;
- long *data;
- int nelements = 0;
- char* endptr;
+ XDeviceInfo *info;
+ XDevice *dev;
+ Atom prop;
+ Atom old_type;
+ char *name;
+ int i;
+ Atom float_atom;
+ int old_format, nelements = 0;
+ unsigned long act_nitems, bytes_after;
+ char *endptr;
+ union {
+ unsigned char *c;
+ short *s;
+ long *l;
+ Atom *a;
+ } data;
- if (argc < 2)
+ if (argc < 3)
{
fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
return EXIT_FAILURE;
@@ -286,153 +319,263 @@ set_float_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
name = argv[1];
- for(i = 0; i < strlen(name); i++) {
- if (!isdigit(name[i])) {
- is_atom = False;
- break;
- }
+ prop = parse_atom(dpy, name);
+
+ if (prop == None) {
+ fprintf(stderr, "invalid property %s\n", name);
+ return EXIT_FAILURE;
}
- if (!is_atom)
- prop = XInternAtom(dpy, name, False);
- else
- prop = atoi(name);
+ float_atom = XInternAtom(dpy, "FLOAT", False);
nelements = argc - 2;
+ if (type == None || format == 0) {
+ if (XGetDeviceProperty(dpy, dev, prop, 0, 0, False, AnyPropertyType,
+ &old_type, &old_format, &act_nitems,
+ &bytes_after, &data.c) != Success) {
+ fprintf(stderr, "failed to get property type and format for %s\n",
+ name);
+ return EXIT_FAILURE;
+ } else {
+ if (type == None)
+ type = old_type;
+ if (format == 0)
+ format = old_format;
+ }
- float_atom = XInternAtom(dpy, "FLOAT", False);
-
- if (float_atom == (Atom)0)
- {
- fprintf(stderr, "no FLOAT atom present in server\n");
- return EXIT_FAILURE;
+ XFree(data.c);
}
- if (sizeof(float) != 4)
- {
- fprintf(stderr, "sane FP required\n");
- return EXIT_FAILURE;
+ if (type == None) {
+ fprintf(stderr, "property %s doesn't exist, you need to specify "
+ "its type and format\n", name);
+ return EXIT_FAILURE;
}
- data = calloc(nelements, sizeof(long));
+ data.c = calloc(nelements, sizeof(long));
+
for (i = 0; i < nelements; i++)
{
- *((float*)(data + i)) = strtod(argv[2 + i], &endptr);
- if(endptr == argv[2 + i]){
- fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
- return EXIT_FAILURE;
- }
+ if (type == XA_INTEGER) {
+ switch (format)
+ {
+ case 8:
+ data.c[i] = atoi(argv[2 + i]);
+ break;
+ case 16:
+ data.s[i] = atoi(argv[2 + i]);
+ break;
+ case 32:
+ data.l[i] = atoi(argv[2 + i]);
+ break;
+ default:
+ fprintf(stderr, "unexpected size for property %s", name);
+ return EXIT_FAILURE;
+ }
+ } else if (type == float_atom) {
+ if (format != 32) {
+ fprintf(stderr, "unexpected format %d for property %s\n",
+ format, name);
+ return EXIT_FAILURE;
+ }
+ *(float *)(data.l + i) = strtod(argv[2 + i], &endptr);
+ if (endptr == argv[2 + i]) {
+ fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
+ return EXIT_FAILURE;
+ }
+ } else if (type == XA_ATOM) {
+ if (format != 32) {
+ fprintf(stderr, "unexpected format %d for property %s\n",
+ format, name);
+ return EXIT_FAILURE;
+ }
+ data.a[i] = parse_atom(dpy, argv[2 + i]);
+ } else {
+ fprintf(stderr, "unexpected type for property %s\n", name);
+ return EXIT_FAILURE;
+ }
}
- XChangeDeviceProperty(dpy, dev, prop, float_atom, 32, PropModeReplace,
- (unsigned char*)data, nelements);
-
- free(data);
+ XChangeDeviceProperty(dpy, dev, prop, type, format, PropModeReplace,
+ data.c, nelements);
+ free(data.c);
XCloseDevice(dpy, dev);
return EXIT_SUCCESS;
}
-
-int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc)
+#if HAVE_XI2
+static void
+print_property_xi2(Display *dpy, int deviceid, Atom property)
{
- XDevice *dev;
- XDeviceInfo *info;
- XEvent ev;
- XDevicePropertyNotifyEvent *dpev;
- char *name;
- int type_prop;
- XEventClass cls_prop;
+ Atom act_type;
+ char *name;
+ int act_format;
+ unsigned long nitems, bytes_after;
+ unsigned char *data, *ptr;
+ int j, done = False;
- if (list_props(dpy, argc, argv, n, desc) != EXIT_SUCCESS)
- return EXIT_FAILURE;
+ name = XGetAtomName(dpy, property);
+ printf("\t%s (%ld):\t", name, property);
- info = find_device_info(dpy, argv[0], False);
- if (!info)
+ if (XIGetProperty(dpy, deviceid, property, 0, 1000, False,
+ AnyPropertyType, &act_type, &act_format,
+ &nitems, &bytes_after, &data) == Success)
{
- fprintf(stderr, "unable to find device %s\n", argv[0]);
- return EXIT_FAILURE;
- }
+ Atom float_atom = XInternAtom(dpy, "FLOAT", True);
- dev = XOpenDevice(dpy, info->id);
- if (!dev)
+ ptr = data;
+
+ if (nitems == 0)
+ printf("<no items>");
+
+ for (j = 0; j < nitems; j++)
+ {
+ switch(act_type)
+ {
+ case XA_INTEGER:
+ switch(act_format)
+ {
+ case 8:
+ printf("%d", *((int8_t*)ptr));
+ break;
+ case 16:
+ printf("%d", *((int16_t*)ptr));
+ break;
+ case 32:
+ printf("%d", *((int32_t*)ptr));
+ break;
+ }
+ break;
+ case XA_STRING:
+ if (act_format != 8)
+ {
+ printf("Unknown string format.\n");
+ done = True;
+ break;
+ }
+ printf("\"%s\"", ptr);
+ j += strlen((char*)ptr); /* The loop's j++ jumps over the
+ terminating 0 */
+ ptr += strlen((char*)ptr); /* ptr += size below jumps over
+ the terminating 0 */
+ break;
+ case XA_ATOM:
+ {
+ Atom a = *(Atom*)ptr;
+ printf("\"%s\" (%d)",
+ (a) ? XGetAtomName(dpy, a) : "None",
+ (int)a);
+ break;
+ }
+ break;
+ default:
+ if (float_atom != None && act_type == float_atom)
+ {
+ printf("%f", *((float*)ptr));
+ break;
+ }
+
+ printf("\t... of unknown type %s\n",
+ XGetAtomName(dpy, act_type));
+ done = True;
+ break;
+ }
+
+ ptr += act_format/8;
+
+ if (done == True)
+ break;
+ if (j < nitems - 1)
+ printf(", ");
+ }
+ printf("\n");
+ XFree(data);
+ } else
+ printf("\tFetch failure\n");
+
+}
+
+static int
+list_props_xi2(Display *dpy, int argc, char** argv, char* name, char *desc)
+{
+ XIDeviceInfo *info;
+ int i;
+ int nprops;
+ Atom *props;
+
+ if (argc == 0)
{
- fprintf(stderr, "unable to open device '%s'\n", info->name);
+ fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
return EXIT_FAILURE;
}
- DevicePropertyNotify(dev, type_prop, cls_prop);
- XSelectExtensionEvent(dpy, DefaultRootWindow(dpy), &cls_prop, 1);
-
- while(1)
+ for (i = 0; i < argc; i++)
{
- XNextEvent(dpy, &ev);
+ info = xi2_find_device_info(dpy, argv[i]);
+ if (!info)
+ {
+ fprintf(stderr, "unable to find device %s\n", argv[i]);
+ continue;
+ }
- dpev = (XDevicePropertyNotifyEvent*)&ev;
- if (dpev->type != type_prop)
+ props = XIListProperties(dpy, info->deviceid, &nprops);
+ if (!nprops)
+ {
+ printf("Device '%s' does not report any properties.\n", info->name);
continue;
+ }
- name = XGetAtomName(dpy, dpev->atom);
- printf("Property '%s' changed.\n", name);
- print_property(dpy, dev, dpev->atom);
- }
+ printf("Device '%s':\n", info->name);
+ while(nprops--)
+ {
+ print_property_xi2(dpy, info->deviceid, props[nprops]);
+ }
- XCloseDevice(dpy, dev);
+ XFree(props);
+ }
+ return EXIT_SUCCESS;
}
-int delete_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
+static int
+delete_prop_xi2(Display *dpy, int argc, char** argv, char* n, char *desc)
{
- XDevice *dev;
- XDeviceInfo *info;
+ XIDeviceInfo *info;
char *name;
- int i;
- Bool is_atom = True;
Atom prop;
- info = find_device_info(dpy, argv[0], False);
+ info = xi2_find_device_info(dpy, argv[0]);
if (!info)
{
fprintf(stderr, "unable to find device %s\n", argv[0]);
return EXIT_FAILURE;
}
- dev = XOpenDevice(dpy, info->id);
- if (!dev)
- {
- fprintf(stderr, "unable to open device '%s'\n", info->name);
- return EXIT_FAILURE;
- }
-
name = argv[1];
- for(i = 0; i < strlen(name); i++) {
- if (!isdigit(name[i])) {
- is_atom = False;
- break;
- }
- }
-
- if (!is_atom)
- prop = XInternAtom(dpy, name, False);
- else
- prop = atoi(name);
+ prop = parse_atom(dpy, name);
- XDeleteDeviceProperty(dpy, dev, prop);
+ XIDeleteProperty(dpy, info->deviceid, prop);
- XCloseDevice(dpy, dev);
return EXIT_SUCCESS;
}
-int
-set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
+static int
+do_set_prop_xi2(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc)
{
- XDeviceInfo *info;
- XDevice *dev;
- Atom prop;
- char *name;
- int i, j;
- Bool is_atom = True;
- Atom *data;
- int nelements = 0;
+ XIDeviceInfo *info;
+ Atom prop;
+ Atom old_type;
+ char *name;
+ int i;
+ Atom float_atom;
+ int old_format, nelements = 0;
+ unsigned long act_nitems, bytes_after;
+ char *endptr;
+ union {
+ unsigned char *c;
+ int16_t *s;
+ int32_t *l;
+ } data;
if (argc < 3)
{
@@ -440,62 +583,219 @@ set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
return EXIT_FAILURE;
}
- info = find_device_info(dpy, argv[0], False);
+ info = xi2_find_device_info(dpy, argv[0]);
if (!info)
{
fprintf(stderr, "unable to find device %s\n", argv[0]);
return EXIT_FAILURE;
}
- dev = XOpenDevice(dpy, info->id);
- if (!dev)
- {
- fprintf(stderr, "unable to open device %s\n", argv[0]);
+ name = argv[1];
+
+ prop = parse_atom(dpy, name);
+
+ if (prop == None) {
+ fprintf(stderr, "invalid property %s\n", name);
return EXIT_FAILURE;
}
- name = argv[1];
+ float_atom = XInternAtom(dpy, "FLOAT", False);
- for(i = 0; i < strlen(name); i++) {
- if (!isdigit(name[i])) {
- is_atom = False;
- break;
- }
+ nelements = argc - 2;
+ if (type == None || format == 0) {
+ if (XIGetProperty(dpy, info->deviceid, prop, 0, 0, False,
+ AnyPropertyType, &old_type, &old_format, &act_nitems,
+ &bytes_after, &data.c) != Success) {
+ fprintf(stderr, "failed to get property type and format for %s\n",
+ name);
+ return EXIT_FAILURE;
+ } else {
+ if (type == None)
+ type = old_type;
+ if (format == 0)
+ format = old_format;
+ }
+
+ XFree(data.c);
}
- if (!is_atom)
- prop = XInternAtom(dpy, name, False);
- else
- prop = atoi(name);
+ if (type == None) {
+ fprintf(stderr, "property %s doesn't exist, you need to specify "
+ "its type and format\n", name);
+ return EXIT_FAILURE;
+ }
+
+ data.c = calloc(nelements, sizeof(int32_t));
- nelements = argc - 2;
- data = calloc(nelements, sizeof(Atom));
for (i = 0; i < nelements; i++)
{
- is_atom = True;
- name = argv[2 + i];
- for(j = 0; j < strlen(name); j++) {
- if (!isdigit(name[j])) {
- is_atom = False;
- break;
+ if (type == XA_INTEGER) {
+ switch (format)
+ {
+ case 8:
+ data.c[i] = atoi(argv[2 + i]);
+ break;
+ case 16:
+ data.s[i] = atoi(argv[2 + i]);
+ break;
+ case 32:
+ data.l[i] = atoi(argv[2 + i]);
+ break;
+ default:
+ fprintf(stderr, "unexpected size for property %s", name);
+ return EXIT_FAILURE;
+ }
+ } else if (type == float_atom) {
+ if (format != 32) {
+ fprintf(stderr, "unexpected format %d for property %s\n",
+ format, name);
+ return EXIT_FAILURE;
+ }
+ *(float *)(data.l + i) = strtod(argv[2 + i], &endptr);
+ if (endptr == argv[2 + i]) {
+ fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
+ return EXIT_FAILURE;
}
+ } else if (type == XA_ATOM) {
+ if (format != 32) {
+ fprintf(stderr, "unexpected format %d for property %s\n",
+ format, name);
+ return EXIT_FAILURE;
+ }
+ data.l[i] = parse_atom(dpy, argv[2 + i]);
+ } else {
+ fprintf(stderr, "unexpected type for property %s\n", name);
+ return EXIT_FAILURE;
}
+ }
- if (!is_atom)
- data[i] = XInternAtom(dpy, name, False);
- else
- {
- data[i] = atoi(name);
- XFree(XGetAtomName(dpy, data[i]));
- }
+ XIChangeProperty(dpy, info->deviceid, prop, type, format, PropModeReplace,
+ data.c, nelements);
+ free(data.c);
+ return EXIT_SUCCESS;
+}
+#endif
+
+int list_props(Display *display, int argc, char *argv[], char *name,
+ char *desc)
+{
+#ifdef HAVE_XI2
+ if (xinput_version(display) == XI_2_Major)
+ return list_props_xi2(display, argc, argv, name, desc);
+#endif
+ return list_props_xi1(display, argc, argv, name, desc);
+
+}
+
+int delete_prop(Display *display, int argc, char *argv[], char *name,
+ char *desc)
+{
+#ifdef HAVE_XI2
+ if (xinput_version(display) == XI_2_Major)
+ return delete_prop_xi2(display, argc, argv, name, desc);
+#endif
+ return delete_prop_xi1(display, argc, argv, name, desc);
+
+}
+
+static int
+do_set_prop(Display *display, Atom type, int format, int argc, char *argv[], char *name, char *desc)
+{
+#ifdef HAVE_XI2
+ if (xinput_version(display) == XI_2_Major)
+ return do_set_prop_xi2(display, type, format, argc, argv, name, desc);
+#endif
+ return do_set_prop_xi1(display, type, format, argc, argv, name, desc);
+}
+
+int
+set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
+{
+ return do_set_prop(dpy, XA_ATOM, 32, argc, argv, n, desc);
+}
+
+int
+set_int_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
+{
+ int i;
+ int format;
+
+ if (argc < 3)
+ {
+ fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
+ return EXIT_FAILURE;
}
- XChangeDeviceProperty(dpy, dev, prop, XA_ATOM, 32, PropModeReplace,
- (unsigned char*)data, nelements);
+ format = atoi(argv[2]);
+ if (format != 8 && format != 16 && format != 32)
+ {
+ fprintf(stderr, "Invalid format %d\n", format);
+ return EXIT_FAILURE;
+ }
- free(data);
- XCloseDevice(dpy, dev);
- return EXIT_SUCCESS;
+ for (i = 3; i < argc; i++)
+ argv[i - 1] = argv[i];
+
+ return do_set_prop(dpy, XA_INTEGER, format, argc - 1, argv, n, desc);
}
+int
+set_float_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
+{
+ Atom float_atom = XInternAtom(dpy, "FLOAT", False);
+
+ if (sizeof(float) != 4)
+ {
+ fprintf(stderr, "sane FP required\n");
+ return EXIT_FAILURE;
+ }
+
+ return do_set_prop(dpy, float_atom, 32, argc, argv, n, desc);
+}
+int set_prop(Display *display, int argc, char *argv[], char *name,
+ char *desc)
+{
+ Atom type = None;
+ int format = 0;
+ int i = 0, j;
+
+ while (i < argc) {
+ char *option = strchr(argv[i], '=');
+ /* skip non-option arguments */
+ if (strncmp(argv[i], "--", 2) || !option) {
+ i++;
+ continue;
+ }
+
+ if (!strncmp(argv[i], "--type=", strlen("--type="))) {
+ if (!strcmp(option + 1, "int")) {
+ type = XA_INTEGER;
+ } else if (!strcmp(option + 1, "float")) {
+ type = XInternAtom(display, "FLOAT", False);
+ format = 32;
+ } else if (!strcmp(option + 1, "atom")) {
+ type = XA_ATOM;
+ format = 32;
+ } else {
+ fprintf(stderr, "unknown property type %s\n", option + 1);
+ return EXIT_FAILURE;
+ }
+ } else if (!strncmp(argv[i], "--format=", strlen("--format="))) {
+ format = atoi(option + 1);
+ if (format != 8 && format != 16 && format != 32) {
+ fprintf(stderr, "invalid property format %s\n", option + 1);
+ return EXIT_FAILURE;
+ }
+ } else {
+ fprintf(stderr, "invalid option %s\n", argv[i]);
+ return EXIT_FAILURE;
+ }
+
+ for (j = i; j + 1 < argc; j++)
+ argv[j] = argv[j + 1];
+ argc--;
+ }
+
+ return do_set_prop(display, type, format, argc, argv, name, desc);
+}
diff --git a/app/xinput/src/setcp.c b/app/xinput/src/setcp.c
index e44bb00fa..7a2864479 100644
--- a/app/xinput/src/setcp.c
+++ b/app/xinput/src/setcp.c
@@ -32,9 +32,8 @@
int
set_clientpointer(Display* dpy, int argc, char** argv, char* name, char *desc)
{
- XDeviceInfo* info;
+ XIDeviceInfo *info;
XID window;
- XDevice* dev = NULL;
char* id;
char* dummy;
@@ -50,19 +49,13 @@ set_clientpointer(Display* dpy, int argc, char** argv, char* name, char *desc)
window = strtol(argv[0], &dummy, (*id == 'x') ? 16 : 10);
- info = find_device_info(dpy, argv[1], False);
+ info = xi2_find_device_info(dpy, argv[1]);
if (!info) {
fprintf(stderr, "unable to find device %s\n", argv[1]);
return EXIT_FAILURE;
}
- dev = XOpenDevice(dpy, info->id);
-
- if (!dev)
- {
- fprintf(stderr, "Cannot open device %s.\n", argv[1]);
- } else
- XSetClientPointer(dpy, window, dev);
+ XISetClientPointer(dpy, window, info->deviceid);
return 0;
}
diff --git a/app/xinput/src/test_xi2.c b/app/xinput/src/test_xi2.c
new file mode 100644
index 000000000..53d984f04
--- /dev/null
+++ b/app/xinput/src/test_xi2.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+
+#include "xinput.h"
+#include <string.h>
+
+extern void print_classes_xi2(Display*, XIAnyClassInfo **classes,
+ int num_classes);
+
+static Window create_win(Display *dpy)
+{
+ Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200,
+ 200, 0, 0, WhitePixel(dpy, 0));
+ Window subwindow = XCreateSimpleWindow(dpy, win, 50, 50, 50, 50, 0, 0,
+ BlackPixel(dpy, 0));
+
+ XMapWindow(dpy, subwindow);
+ XSelectInput(dpy, win, ExposureMask);
+ return win;
+}
+
+static void print_deviceevent(XIDeviceEvent* event)
+{
+ double *val;
+ int i;
+
+ printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
+ printf(" detail: %d\n", event->detail);
+ printf(" flags: %s\n", (event->flags & XIKeyRepeat) ? "repeat" : "");
+
+ printf(" root: %.2f/%.2f\n", event->root_x, event->root_y);
+ printf(" event: %.2f/%.2f\n", event->event_x, event->event_y);
+
+ printf(" buttons:");
+ for (i = 0; i < event->buttons.mask_len * 8; i++)
+ if (XIMaskIsSet(event->buttons.mask, i))
+ printf(" %d", i);
+ printf("\n");
+
+ printf(" modifiers: locked %#x latched %#x base %#x effective: %#x\n",
+ event->mods.locked, event->mods.latched,
+ event->mods.base, event->mods.effective);
+ printf(" group: locked %#x latched %#x base %#x effective: %#x\n",
+ event->group.locked, event->group.latched,
+ event->group.base, event->group.effective);
+ printf(" valuators:");
+
+ val = event->valuators.values;
+ for (i = 0; i < event->valuators.mask_len * 8; i++)
+ if (XIMaskIsSet(event->valuators.mask, i))
+ printf(" %.2f", *val++);
+ printf("\n");
+
+ printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n",
+ event->root, event->event, event->child);
+}
+
+static void print_devicechangedevent(Display *dpy, XIDeviceChangedEvent *event)
+{
+ printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
+ printf(" reason: %s\n", (event->reason == XISlaveSwitch) ? "SlaveSwitch" :
+ "DeviceChanged");
+ print_classes_xi2(dpy, event->classes, event->num_classes);
+}
+
+static void print_hierarchychangedevent(XIHierarchyEvent *event)
+{
+ int i;
+ printf(" Changes happened: %s %s %s %s %s %s %s %s\n",
+ (event->flags & XIMasterAdded) ? "[new master]" : "",
+ (event->flags & XIMasterRemoved) ? "[master removed]" : "",
+ (event->flags & XISlaveAdded) ? "[new slave]" : "",
+ (event->flags & XISlaveRemoved) ? "[slave removed]" : "",
+ (event->flags & XISlaveAttached) ? "[slave attached]" : "",
+ (event->flags & XISlaveDetached) ? "[slave detached]" : "",
+ (event->flags & XIDeviceEnabled) ? "[device enabled]" : "",
+ (event->flags & XIDeviceDisabled) ? "[device disabled]" : "");
+
+ for (i = 0; i < event->num_info; i++)
+ {
+ char *use;
+ switch(event->info[i].use)
+ {
+ case XIMasterPointer: use = "master pointer"; break;
+ case XIMasterKeyboard: use = "master keyboard"; break;
+ case XISlavePointer: use = "slave pointer"; break;
+ case XISlaveKeyboard: use = "slave keyboard"; break;
+ case XIFloatingSlave: use = "floating slave"; break;
+ break;
+ }
+
+ printf(" device %d [%s (%d)] is %s\n",
+ event->info[i].deviceid,
+ use,
+ event->info[i].attachment,
+ (event->info[i].enabled) ? "enabled" : "disabled");
+ if (event->info[i].flags)
+ {
+ printf(" changes: %s %s %s %s %s %s %s %s\n",
+ (event->info[i].flags & XIMasterAdded) ? "[new master]" : "",
+ (event->info[i].flags & XIMasterRemoved) ? "[master removed]" : "",
+ (event->info[i].flags & XISlaveAdded) ? "[new slave]" : "",
+ (event->info[i].flags & XISlaveRemoved) ? "[slave removed]" : "",
+ (event->info[i].flags & XISlaveAttached) ? "[slave attached]" : "",
+ (event->info[i].flags & XISlaveDetached) ? "[slave detached]" : "",
+ (event->info[i].flags & XIDeviceEnabled) ? "[device enabled]" : "",
+ (event->info[i].flags & XIDeviceDisabled) ? "[device disabled]" : "");
+ }
+ }
+}
+
+static void print_rawevent(XIRawEvent *event)
+{
+ int i;
+ double *val, *raw_val;
+
+ printf(" device: %d\n", event->deviceid);
+ printf(" detail: %d\n", event->detail);
+ printf(" valuators:\n");
+
+ val = event->valuators.values;
+ raw_val = event->raw_values;
+ for (i = 0; i < event->valuators.mask_len * 8; i++)
+ if (XIMaskIsSet(event->valuators.mask, i))
+ printf(" %2d: %.2f (%.2f)\n", i, *val++, *raw_val++);
+ printf("\n");
+}
+
+static void print_enterleave(XILeaveEvent* event)
+{
+ char *mode, *detail;
+ int i;
+
+ printf(" device: %d\n", event->deviceid);
+ printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n",
+ event->root, event->event, event->child);
+ switch(event->mode)
+ {
+ case XINotifyNormal: mode = "NotifyNormal"; break;
+ case XINotifyGrab: mode = "NotifyGrab"; break;
+ case XINotifyUngrab: mode = "NotifyUngrab"; break;
+ case XINotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break;
+ case XINotifyPassiveGrab: mode = "NotifyPassiveGrab"; break;
+ case XINotifyPassiveUngrab:mode = "NotifyPassiveUngrab"; break;
+ }
+ switch (event->detail)
+ {
+ case XINotifyAncestor: detail = "NotifyAncestor"; break;
+ case XINotifyVirtual: detail = "NotifyVirtual"; break;
+ case XINotifyInferior: detail = "NotifyInferior"; break;
+ case XINotifyNonlinear: detail = "NotifyNonlinear"; break;
+ case XINotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break;
+ case XINotifyPointer: detail = "NotifyPointer"; break;
+ case XINotifyPointerRoot: detail = "NotifyPointerRoot"; break;
+ case XINotifyDetailNone: detail = "NotifyDetailNone"; break;
+ }
+ printf(" mode: %s (detail %s)\n", mode, detail);
+ printf(" flags: %s %s\n", event->focus ? "[focus]" : "",
+ event->same_screen ? "[same screen]" : "");
+ printf(" buttons:");
+ for (i = 0; i < event->buttons.mask_len * 8; i++)
+ if (XIMaskIsSet(event->buttons.mask, i))
+ printf(" %d", i);
+ printf("\n");
+
+ printf(" modifiers: locked %#x latched %#x base %#x effective: %#x\n",
+ event->mods.locked, event->mods.latched,
+ event->mods.base, event->mods.effective);
+ printf(" group: locked %#x latched %#x base %#x effective: %#x\n",
+ event->group.locked, event->group.latched,
+ event->group.base, event->group.effective);
+
+ printf(" root x/y: %.2f / %.2f\n", event->root_x, event->root_y);
+ printf(" event x/y: %.2f / %.2f\n", event->event_x, event->event_y);
+
+}
+
+static void print_propertyevent(Display *display, XIPropertyEvent* event)
+{
+ char *changed;
+ char *name;
+
+ if (event->what == XIPropertyDeleted)
+ changed = "deleted";
+ else if (event->what == XIPropertyCreated)
+ changed = "created";
+ else
+ changed = "modified";
+ name = XGetAtomName(display, event->property);
+ printf(" property: %ld '%s'\n", event->property, name);
+ printf(" changed: %s\n", changed);
+
+ XFree(name);
+}
+void
+test_sync_grab(Display *display, Window win)
+{
+ int loop = 3;
+ int rc;
+ XIEventMask mask;
+
+ /* Select for motion events */
+ mask.deviceid = XIAllDevices;
+ mask.mask_len = 2;
+ mask.mask = calloc(2, sizeof(char));
+ XISetMask(mask.mask, XI_ButtonPress);
+
+ if ((rc = XIGrabDevice(display, 2, win, CurrentTime, None, GrabModeSync,
+ GrabModeAsync, False, &mask)) != GrabSuccess)
+ {
+ fprintf(stderr, "Grab failed with %d\n", rc);
+ return;
+ }
+ free(mask.mask);
+
+ XSync(display, True);
+ XIAllowEvents(display, 2, SyncPointer, CurrentTime);
+ XFlush(display);
+
+ printf("Holding sync grab for %d button presses.\n", loop);
+
+ while(loop--)
+ {
+ XIEvent ev;
+
+ XNextEvent(display, (XEvent*)&ev);
+ if (ev.type == GenericEvent && ev.extension == xi_opcode )
+ {
+ XIDeviceEvent *event = (XIDeviceEvent*)&ev;
+ print_deviceevent(event);
+ XIAllowEvents(display, 2, SyncPointer, CurrentTime);
+ }
+ }
+
+ XIUngrabDevice(display, 2, CurrentTime);
+ printf("Done\n");
+}
+
+int
+test_xi2(Display *display,
+ int argc,
+ char *argv[],
+ char *name,
+ char *desc)
+{
+ XIEventMask mask;
+ Window win;
+
+ list(display, argc, argv, name, desc);
+ win = create_win(display);
+
+ /* Select for motion events */
+ mask.deviceid = XIAllDevices;
+ mask.mask_len = XIMaskLen(XI_RawMotion);
+ mask.mask = calloc(mask.mask_len, sizeof(char));
+ XISetMask(mask.mask, XI_ButtonPress);
+ XISetMask(mask.mask, XI_ButtonRelease);
+ XISetMask(mask.mask, XI_KeyPress);
+ XISetMask(mask.mask, XI_KeyRelease);
+ XISetMask(mask.mask, XI_Motion);
+ XISetMask(mask.mask, XI_DeviceChanged);
+ XISetMask(mask.mask, XI_Enter);
+ XISetMask(mask.mask, XI_Leave);
+ XISetMask(mask.mask, XI_FocusIn);
+ XISetMask(mask.mask, XI_FocusOut);
+ XISetMask(mask.mask, XI_HierarchyChanged);
+ XISetMask(mask.mask, XI_PropertyEvent);
+ XISelectEvents(display, win, &mask, 1);
+ XMapWindow(display, win);
+ XSync(display, False);
+
+ {
+ XIGrabModifiers modifiers[] = {{0, 0}, {0, 0x10}, {0, 0x1}, {0, 0x11}};
+ int nmods = sizeof(modifiers)/sizeof(modifiers[0]);
+
+ mask.deviceid = 2;
+ memset(mask.mask, 0, 2);
+ XISetMask(mask.mask, XI_KeyPress);
+ XISetMask(mask.mask, XI_KeyRelease);
+ XISetMask(mask.mask, XI_ButtonPress);
+ XISetMask(mask.mask, XI_ButtonRelease);
+ XISetMask(mask.mask, XI_Motion);
+ XIGrabButton(display, 2, 1, win, None, GrabModeAsync, GrabModeAsync,
+ False, &mask, nmods, modifiers);
+ XIGrabKeycode(display, 3, 24 /* q */, win, GrabModeAsync, GrabModeAsync,
+ False, &mask, nmods, modifiers);
+ XIUngrabButton(display, 3, 1, win, nmods - 2, &modifiers[2]);
+ XIUngrabKeycode(display, 3, 24 /* q */, win, nmods - 2, &modifiers[2]);
+ }
+
+ mask.deviceid = XIAllMasterDevices;
+ memset(mask.mask, 0, 2);
+ XISetMask(mask.mask, XI_RawKeyPress);
+ XISetMask(mask.mask, XI_RawKeyRelease);
+ XISetMask(mask.mask, XI_RawButtonPress);
+ XISetMask(mask.mask, XI_RawButtonRelease);
+ XISetMask(mask.mask, XI_RawMotion);
+ XISelectEvents(display, DefaultRootWindow(display), &mask, 1);
+
+ free(mask.mask);
+
+ {
+ XEvent event;
+ XMaskEvent(display, ExposureMask, &event);
+ XSelectInput(display, win, 0);
+ }
+
+ /*
+ test_sync_grab(display, win);
+ */
+
+ while(1)
+ {
+ XEvent ev;
+ XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie;
+ XNextEvent(display, (XEvent*)&ev);
+
+ if (XGetEventData(display, cookie) &&
+ cookie->type == GenericEvent &&
+ cookie->extension == xi_opcode)
+ {
+ printf("EVENT type %d\n", cookie->evtype);
+ switch (cookie->evtype)
+ {
+ case XI_DeviceChanged:
+ print_devicechangedevent(display, cookie->data);
+ break;
+ case XI_HierarchyChanged:
+ print_hierarchychangedevent(cookie->data);
+ break;
+ case XI_RawKeyPress:
+ case XI_RawKeyRelease:
+ case XI_RawButtonPress:
+ case XI_RawButtonRelease:
+ case XI_RawMotion:
+ print_rawevent(cookie->data);
+ break;
+ case XI_Enter:
+ case XI_Leave:
+ case XI_FocusIn:
+ case XI_FocusOut:
+ print_enterleave(cookie->data);
+ break;
+ case XI_PropertyEvent:
+ print_propertyevent(display, cookie->data);
+ break;
+ default:
+ print_deviceevent(cookie->data);
+ break;
+ }
+ }
+
+ XFreeEventData(display, cookie);
+ }
+
+ XDestroyWindow(display, win);
+
+ return EXIT_SUCCESS;
+}
diff --git a/app/xinput/src/version.c b/app/xinput/src/version.c
deleted file mode 100644
index 93a50d8be..000000000
--- a/app/xinput/src/version.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 1996-1997 by Frederic Lepied, France. <Frederic.Lepied@sugix.frmug.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the authors not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. The authors make no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "xinput.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-static const char version_id[] = VERSION;
-
-int
-version(Display *display,
- int argc,
- char *argv[],
- char *name,
- char *desc)
-{
- printf("%s %s\n", name, version_id);
- return EXIT_SUCCESS;
-}
-
-/* end of version.c */
diff --git a/app/xinput/src/xinput.c b/app/xinput/src/xinput.c
index 82dc54a85..149662d20 100644
--- a/app/xinput/src/xinput.c
+++ b/app/xinput/src/xinput.c
@@ -25,12 +25,10 @@
#include <ctype.h>
#include <string.h>
-typedef int (*prog)(
-#if NeedFunctionPrototypes
- Display* display, int argc, char *argv[],
- char *prog_name, char *prog_desc
-#endif
-);
+int xi_opcode;
+
+typedef int (*prog)(Display* display, int argc, char *argv[],
+ char *prog_name, char *prog_desc);
typedef struct
{
@@ -70,7 +68,7 @@ static entry drivers[] =
set_mode
},
{"list",
- "[--loop || --short || <device name>...]",
+ "[--short || --long] [<device name>...]",
list
},
{"query-state",
@@ -81,17 +79,13 @@ static entry drivers[] =
"[-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",
@@ -106,6 +100,10 @@ static entry drivers[] =
"<window> <device>",
set_clientpointer
},
+ { "test-xi2",
+ "<device>",
+ test_xi2,
+ },
#endif
{ "list-props",
"<device> [<device> ...]",
@@ -131,29 +129,62 @@ static entry drivers[] =
"<device> <property>",
delete_prop
},
+ { "set-prop",
+ "<device> [--type=atom|float|int] [--format=8|16|32] <property> <val> [<val> ...]",
+ set_prop
+ },
{NULL, NULL, NULL
}
};
-static Bool
-is_xinput_present(Display *display)
+static const char version_id[] = VERSION;
+
+int
+print_version()
{
XExtensionVersion *version;
- Bool present;
+ 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)
+{
+ XExtensionVersion *version;
+ static int vers = -1;
+
+ if (vers != -1)
+ return vers;
-#if HAVE_XI2
- version = XQueryInputVersion(display, XI_2_Major, XI_2_Minor);
-#else
version = XGetExtensionVersion(display, INAME);
-#endif
if (version && (version != (XExtensionVersion*) NoSuchExtension)) {
- present = version->present;
+ vers = version->major_version;
XFree(version);
- return present;
- } else {
- return False;
}
+
+ return vers;
}
XDeviceInfo*
@@ -200,6 +231,41 @@ find_device_info(Display *display,
return found;
}
+#ifdef HAVE_XI2
+XIDeviceInfo*
+xi2_find_device_info(Display *display, char *name)
+{
+ XIDeviceInfo *info;
+ int ndevices;
+ Bool is_id = True;
+ int i, id = -1;
+
+ for(i = 0; i < strlen(name); i++) {
+ if (!isdigit(name[i])) {
+ is_id = False;
+ break;
+ }
+ }
+
+ if (is_id) {
+ id = atoi(name);
+ }
+
+ info = XIQueryDevice(display, XIAllDevices, &ndevices);
+ for(i = 0; i < ndevices; i++)
+ {
+ if ((is_id && info[i].deviceid == id) ||
+ (!is_id && strcmp(info[i].name, name) == 0))
+ {
+ return &info[i];
+ }
+ }
+
+ XIFreeDeviceInfo(info);
+ return NULL;
+}
+#endif
+
static void
usage(void)
{
@@ -220,12 +286,20 @@ main(int argc, char * argv[])
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) {
@@ -233,10 +307,12 @@ main(int argc, char * argv[])
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 (!is_xinput_present(display)) {
+ if (!xinput_version(display)) {
fprintf(stderr, "%s extension not available\n", INAME);
return EXIT_FAILURE;
}
diff --git a/app/xinput/src/xinput.h b/app/xinput/src/xinput.h
index 3c364973f..d44ce0960 100644
--- a/app/xinput/src/xinput.h
+++ b/app/xinput/src/xinput.h
@@ -27,6 +27,9 @@
#include <X11/Xlib.h>
#include <X11/extensions/XInput.h>
+#ifdef HAVE_XI2
+#include <X11/extensions/XInput2.h>
+#endif
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
@@ -38,255 +41,41 @@
#define EXIT_FAILURE 0
#endif
-XDeviceInfo*
-find_device_info(
-#if NeedFunctionPrototypes
- Display *display,
- char *name,
- Bool only_extended
-#endif
- );
-int
-get_feedbacks(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-set_ptr_feedback(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-get_button_map(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-set_button_map(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-set_pointer(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-set_mode(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-list(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-test(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-version(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-set_integer_feedback(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-query_state(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-create_master(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-remove_master(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-change_attachment(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-float_device(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-set_clientpointer(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-list_props(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-
-int
-set_int_prop(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-set_float_prop(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-set_atom_prop(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-watch_props(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
-
-int
-delete_prop(
-#if NeedFunctionPrototypes
- Display* display,
- int argc,
- char *argv[],
- char *prog_name,
- char *prog_desc
-#endif
-);
+extern int xi_opcode; /* xinput extension op code */
+XDeviceInfo* find_device_info( Display *display, char *name, Bool only_extended);
+#if HAVE_XI2
+XIDeviceInfo* xi2_find_device_info(Display *display, char *name);
+int xinput_version(Display* display);
+#endif
+
+int get_feedbacks( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_ptr_feedback( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int get_button_map( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_button_map( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_pointer( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+
+int set_mode( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int list( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int test( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int version( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_integer_feedback( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int query_state( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+
+/* X Input 1.5 */
+int list_props( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_int_prop( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_float_prop( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_atom_prop( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int watch_props( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int delete_prop( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_prop( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+
+/* X Input 2.0 */
+int create_master( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int remove_master( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int change_attachment( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int float_device( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int set_clientpointer( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+int test_xi2( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
/* end of xinput.h */