From: Peter Hutterer Date: Tue, 8 Jul 2008 08:30:21 +0000 (+0930) Subject: Add list-props, set-int-prop and watch-props parameters. X-Git-Url: https://diplodocus.org/git/xorg-xinput/commitdiff_plain/6ebdca422d12e3326f9ab59767e05eefd24ff85f?ds=sidebyside;hp=98b79fc5b050eea6141ad78cff4e0577f8e75c77 Add list-props, set-int-prop and watch-props parameters. These parameters allow modification and display of input device properties. --- diff --git a/src/Makefile.am b/src/Makefile.am index 6a747ef..6ab00f3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ xinput_LDADD = $(XINPUT_LIBS) if HAVE_XI2 - xinput2_files = hierarchy.c setcp.c + xinput2_files = hierarchy.c setcp.c property.c endif # HAVE_XI2 xinput_SOURCES = \ diff --git a/src/property.c b/src/property.c new file mode 100644 index 0000000..269fecc --- /dev/null +++ b/src/property.c @@ -0,0 +1,295 @@ +/* + * Copyright 2007 Peter Hutterer + * + * 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. + * + * The above copyright notice and this permission notice 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 AUTHOR 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. + * + * Except as contained in this notice, the name of the author shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization + * from the author. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "xinput.h" + +static void +print_property(Display *dpy, XDevice* dev, Atom property) +{ + XIPropertyInfo *propinfo; + Atom act_type; + char *name; + int act_format; + unsigned long nitems, bytes_after; + unsigned char *data, *ptr; + int j; + + propinfo = XQueryDeviceProperty(dpy, dev, property); + if (!propinfo) + return; + + name = XGetAtomName(dpy, property); + printf("\t%s:\t", name); + + if (XGetDeviceProperty(dpy, dev, property, 0, 1000, False, False, + AnyPropertyType, &act_type, &act_format, + &nitems, &bytes_after, &data) == Success) + { + ptr = data; + printf("\t"); + + 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: + printf("\t%s\n", ptr); + break; + case XA_ATOM: + printf("\t%s\n", XGetAtomName(dpy, (Atom)(*ptr))); + break; + default: + printf("\t\t... of unknown type %s\n", + XGetAtomName(dpy, act_type)); + break; + } + + ptr += act_format/8; + + if (j < nitems - 1) + printf(", "); + if (act_type == XA_STRING) + break; + } + printf("\n"); + XFree(data); + } else + printf("\tFetch failure\n"); + + if (propinfo->pending || propinfo->range || propinfo->immutable || propinfo->fromClient) + { + printf("\t\t%s%s%s%s", ((propinfo->pending) ? "[pending]" : ""), + ((propinfo->range) ? "[range]" : ""), + ((propinfo->immutable) ? "[immutable]" : ""), + ((propinfo->fromClient) ? "[client]" : "")); + printf("\n"); + } + + if (propinfo->num_values) + { + long *values = propinfo->values; + printf("\t\tvalid values: "); + while(values && propinfo->num_values--) + printf("%ld ", *values++); + printf("\n"); + } + + XFree(propinfo); + +} + +int list_props(Display *dpy, int argc, char** argv, char* name, char *desc) +{ + XDeviceInfo *info; + XDevice *dev; + int i; + int nprops; + Atom *props; + + if (argc == 0) + { + fprintf(stderr, "Usage: xinput %s %s\n", name, desc); + return EXIT_FAILURE; + } + + for (i = 0; i < argc; i++) + { + info = find_device_info(dpy, argv[i], False); + if (!info) + { + fprintf(stderr, "unable to find device %s\n", argv[i]); + continue; + } + + dev = XOpenDevice(dpy, info->id); + if (!dev) + { + fprintf(stderr, "unable to open device '%s'\n", info->name); + continue; + } + + props = XListDeviceProperties(dpy, dev, &nprops); + if (!nprops) + { + printf("Device '%s' does not report any properties.\n", info->name); + continue; + } + + printf("Device '%s':\n", info->name); + while(nprops--) + { + print_property(dpy, dev, props[nprops]); + } + + XFree(props); + XCloseDevice(dpy, dev); + } + return EXIT_SUCCESS; +} + +int +set_int_prop(Display *dpy, int argc, char** argv, char* n, char *desc) +{ + XDeviceInfo *info; + XDevice *dev; + Atom prop; + char *name; + int i; + Bool is_atom = True; + char *data; + int format, nelements = 0; + + if (argc < 3) + { + fprintf(stderr, "Usage: xinput %s %s\n", n, desc); + return EXIT_FAILURE; + } + + info = find_device_info(dpy, argv[0], False); + 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]); + 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); + + nelements = argc - 3; + format = atoi(argv[2]); + if (format != 8 && format != 16 && format != 32) + { + fprintf(stderr, "Invalid format %d\n", format); + return EXIT_FAILURE; + } + + data = calloc(nelements, format/8); + for (i = 0; i < nelements; i++) + { + switch(format) + { + case 8: + *(((int8_t*)data) + i) = atoi(argv[3 + i]); + break; + case 16: + *(((int16_t*)data) + i) = atoi(argv[3 + i]); + break; + case 32: + *(((int32_t*)data) + i) = atoi(argv[3 + i]); + break; + } + } + + XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, format, PropModeReplace, + (unsigned char*)data, nelements); + + free(data); + XCloseDevice(dpy, dev); + return EXIT_SUCCESS; +} + + +int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc) +{ + XDevice *dev; + XDeviceInfo *info; + XEvent ev; + XDevicePropertyNotifyEvent *dpev; + char *name; + + if (list_props(dpy, argc, argv, n, desc) != EXIT_SUCCESS) + return EXIT_FAILURE; + + info = find_device_info(dpy, argv[0], False); + 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; + } + + XiSelectEvent(dpy, DefaultRootWindow(dpy), NULL, + XI_DevicePropertyNotifyMask); + + while(1) + { + XNextEvent(dpy, &ev); + + dpev = (XDevicePropertyNotifyEvent*)&ev; + if (dpev->type != GenericEvent && + dpev->type != XI_DevicePropertyNotify) + continue; + name = XGetAtomName(dpy, dpev->atom); + printf("Property '%s' changed.\n", name); + print_property(dpy, dev, dpev->atom); + } + + XCloseDevice(dpy, dev); +} diff --git a/src/xinput.c b/src/xinput.c index 6dd2b25..ac9c65f 100644 --- a/src/xinput.c +++ b/src/xinput.c @@ -102,6 +102,18 @@ static entry drivers[] = " ", set_clientpointer }, + { "list-props", + " [ ...]", + list_props + }, + { "set-int-prop", + " [ ...]", + set_int_prop + }, + { "watch-props", + "", + watch_props + }, #endif {0, 0, 0 } diff --git a/src/xinput.h b/src/xinput.h index cbab391..9b017ba 100644 --- a/src/xinput.h +++ b/src/xinput.h @@ -211,4 +211,38 @@ set_clientpointer( #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 +watch_props( +#if NeedFunctionPrototypes + Display* display, + int argc, + char *argv[], + char *prog_name, + char *prog_desc +#endif +); + /* end of xinput.h */