From: Peter Hutterer Date: Thu, 7 May 2009 03:06:05 +0000 (+1000) Subject: Merge branch 'master' into xi2 X-Git-Url: https://diplodocus.org/git/xorg-xinput/commitdiff_plain/a783c19f94e6fed28aeaf0550558cd0b63402b9c?ds=inline;hp=-c Merge branch 'master' into xi2 Conflicts: src/property.c src/xinput.c src/xinput.h --- a783c19f94e6fed28aeaf0550558cd0b63402b9c diff --combined configure.ac index f2ad4f1,e973c22..8314a6b --- a/configure.ac +++ b/configure.ac @@@ -2,7 -2,7 +2,7 @@@ dnl Copyright 2007 Peter Hutterer = 1.2] [inputproto >= 1.5]) -LIBS="$XINPUT_LIBS $LIBS" -AC_CHECK_FUNC(XSetClientPointer,AC_DEFINE(HAVE_XI2,1,[XInput Version 2 Enabled])) -AM_CONDITIONAL(HAVE_XI2, [test "x$ac_cv_func_XSetClientPointer" = "xyes"] ) +# XI2 support +PKG_CHECK_MODULES(XI2, [xi >= 1.2.99], + HAVE_XI2="yes"; AC_DEFINE(HAVE_XI2, 1, "foo"), + HAVE_XI2="no"); +AM_CONDITIONAL(HAVE_XI2, [ test "$HAVE_XI2" = "yes" ]) -XINPUT_CFLAGS="$CWARNFLAGS $XINPUT_CFLAGS" AC_SUBST(XINPUT_CFLAGS) AC_SUBST(XINPUT_LIBS) AC_SUBST(HAVE_XI2) diff --combined src/list.c index 52e3961,bd71a5c..24edc70 --- a/src/list.c +++ b/src/list.c @@@ -26,7 -26,7 +26,7 @@@ #include /* for XI_Device***ChangedNotify */ static void - print_info(XDeviceInfo *info, Bool shortformat) + print_info(Display* dpy, XDeviceInfo *info, Bool shortformat) { int i,j; XAnyClassPtr any; @@@ -34,6 -34,9 +34,6 @@@ XButtonInfoPtr b; XValuatorInfoPtr v; XAxisInfoPtr a; -#if HAVE_XI2 - XAttachInfoPtr att; -#endif printf("\"%s\"\tid=%ld\t[", info->name, info->id); @@@ -62,6 -65,9 +62,9 @@@ if (shortformat) return; + if(info->type != None) + printf("\tType is %s\n", XGetAtomName(dpy, info->type)); + if (info->num_classes > 0) { any = (XAnyClassPtr) (info->inputclassinfo); for (i=0; inum_classes; i++) { @@@ -92,6 -98,12 +95,6 @@@ 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"); } @@@ -100,11 -112,12 +103,11 @@@ } } -int -list(Display *display, - int argc, - char *argv[], - char *name, - char *desc) +static int list_xi1(Display *display, + int argc, + char *argv[], + char *name, + char *desc) { XDeviceInfo *info; int loop; @@@ -116,12 -129,44 +119,12 @@@ if (argc == 0 || shortformat || daemon) { int num_devices; - XEvent ev; - -#if HAVE_XI2 - if (daemon) - { - XiSelectEvent(display, DefaultRootWindow(display), NULL, - XI_DeviceHierarchyChangedMask | - XI_DeviceClassesChangedMask); - } -#endif do { info = XListInputDevices(display, &num_devices); for(loop=0; loopevtype == XI_DeviceHierarchyChangedNotify) - { - printf("Hierarchy change.\n"); - } else if (gev->evtype == XI_DeviceClassesChangedNotify) - { - printf("Device classes changed.\n"); - free(((XDeviceClassesChangedEvent*)&ev)->inputclassinfo); - } - break; - } - } -#endif } while(daemon); } else { int ret = EXIT_SUCCESS; @@@ -133,7 -178,7 +136,7 @@@ fprintf(stderr, "unable to find device %s\n", argv[loop]); ret = EXIT_FAILURE; } else { - print_info(info, shortformat); + print_info(display, info, shortformat); } } return ret; @@@ -141,150 -186,4 +144,150 @@@ return EXIT_SUCCESS; } +#ifdef HAVE_XI2 +/* also used from test_xi2.c */ +void +print_classes_xi2(Display* display, XIAnyClassInfo **classes, + int num_classes) +{ + int i; + + printf("\tReporting %d classes:\n", num_classes); + for (i = 0; i < num_classes; i++) + { + switch(classes[i]->type) + { + case ButtonClass: + { + XIButtonClassInfo *b = (XIButtonClassInfo*)classes[i]; + printf("\t\tButtons supported: %d\n", b->num_buttons); + + } + break; + case KeyClass: + { + XIKeyClassInfo *k = (XIKeyClassInfo*)classes[i]; + printf("\t\tKeycodes supported: %d\n", k->num_keycodes); + } + break; + case ValuatorClass: + { + XIValuatorClassInfo *v = (XIValuatorClassInfo*)classes[i]; + printf("\t\tDetail for Valuator %d:\n", v->number); + printf("\t\t Name: %s\n", XGetAtomName(display, v->name)); + 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"); + } + break; + } + } + + printf("\n"); +} + +static void +print_info_xi2(Display* display, XIDeviceInfo *dev, Bool shortformat) +{ + printf("%-40s\tid=%d\t[", dev->name, dev->deviceid); + switch(dev->use) + { + case MasterPointer: + printf("master pointer (%d)]\n", dev->attachment); + break; + case MasterKeyboard: + printf("master keyboard (%d)]\n", dev->attachment); + break; + case SlavePointer: + printf("slave pointer (%d)]\n", dev->attachment); + break; + case SlaveKeyboard: + printf("slave keyboard (%d)]\n", dev->attachment); + break; + case FloatingSlave: + 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); +} + + +int +list_xi2(Display *display, + int argc, + char *argv[], + char *name, + char *desc) +{ + int major = XI_2_Major, + minor = XI_2_Minor; + int ndevices; + int i, j, shortformat; + XIDeviceInfo *info, *dev; + + shortformat = (argc == 1 && strcmp(argv[0], "--short") == 0); + + 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, AllDevices, &ndevices); + dev = info; + + for(i = 0; i < ndevices; i++) + { + dev = &info[i]; + if (dev->use == MasterPointer || dev->use == MasterKeyboard) + { + if (dev->use == MasterPointer) + printf("⎡ "); + else + printf("⎣ "); + + print_info_xi2(display, dev, shortformat); + for (j = 0; j < ndevices; j++) + { + XIDeviceInfo* sd = &info[j]; + + if ((sd->use == SlavePointer || sd->use == SlaveKeyboard) && + (sd->attachment == dev->deviceid)) + { + printf("%s ↳ ", dev->use == MasterPointer ? "⎜" : " "); + print_info_xi2(display, sd, shortformat); + } + } + } + } + + + XIFreeDeviceInfo(info); + return EXIT_SUCCESS; +} +#endif + +int +list(Display *display, + int argc, + char *argv[], + char *name, + char *desc) +{ +#ifdef HAVE_XI2 + if (xinput_version(display) == XI_2_Major) + return list_xi2(display, argc, argv, name, desc); +#endif + return list_xi1(display, argc, argv, name, desc); +} + /* end of list.c */ diff --combined src/property.c index f30b01b,db46059..b5f1107 --- a/src/property.c +++ b/src/property.c @@@ -34,6 -34,23 +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) { @@@ -42,7 -59,7 +59,7 @@@ int act_format; unsigned long nitems, bytes_after; unsigned char *data, *ptr; - int j, done = False; + int j, done = False, size; name = XGetAtomName(dpy, property); printf("\t%s (%ld):\t", name, property); @@@ -51,10 -68,17 +68,17 @@@ AnyPropertyType, &act_type, &act_format, &nitems, &bytes_after, &data) == Success) { - int float_atom = XInternAtom(dpy, "FLOAT", False); + Atom float_atom = XInternAtom(dpy, "FLOAT", True); ptr = data; + switch(act_format) + { + case 8: size = sizeof(char); break; + case 16: size = sizeof(short); break; + case 32: size = sizeof(long); break; + } + for (j = 0; j < nitems; j++) { switch(act_type) @@@ -63,10 -87,10 +87,10 @@@ switch(act_format) { case 8: - printf("%d", *((int8_t*)ptr)); + printf("%d", *((char*)ptr)); break; case 16: - printf("%d", *((int16_t*)ptr)); + printf("%d", *((short*)ptr)); break; case 32: printf("%ld", *((long*)ptr)); @@@ -74,17 -98,18 +98,18 @@@ } break; case XA_STRING: + if (act_format != 8) { - int len = 0; - unsigned char *p = ptr; - while(len < nitems) - { - printf("'%s' ", &p[len]); - len += (strlen(&p[len]) + 1); - } + 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: printf("\"%s\"", XGetAtomName(dpy, *(Atom*)ptr)); break; @@@ -101,12 -126,12 +126,12 @@@ break; } - ptr += act_format/8; + ptr += size; - if (j < nitems - 1) - printf(", "); if (done == True) break; + if (j < nitems - 1) + printf(", "); } printf("\n"); XFree(data); @@@ -172,7 -197,6 +197,6 @@@ set_int_prop(Display *dpy, int argc, ch Atom prop; char *name; int i; - Bool is_atom = True; char *data; int format, nelements = 0; @@@ -198,17 -222,7 +222,7 @@@ 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); nelements = argc - 3; format = atoi(argv[2]); @@@ -218,16 -232,16 +232,16 @@@ return EXIT_FAILURE; } - data = calloc(nelements, format/8); + data = calloc(nelements, sizeof(long)); for (i = 0; i < nelements; i++) { switch(format) { case 8: - *(((int8_t*)data) + i) = atoi(argv[3 + i]); + *(((char*)data) + i) = atoi(argv[3 + i]); break; case 16: - *(((int16_t*)data) + i) = atoi(argv[3 + i]); + *(((short*)data) + i) = atoi(argv[3 + i]); break; case 32: *(((long*)data) + i) = atoi(argv[3 + i]); @@@ -251,8 -265,7 +265,7 @@@ set_float_prop(Display *dpy, int argc, Atom prop, float_atom; char *name; int i; - Bool is_atom = True; - float *data; + long *data; int nelements = 0; char* endptr; @@@ -278,17 -291,7 +291,7 @@@ 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); nelements = argc - 2; @@@ -306,10 -309,10 +309,10 @@@ return EXIT_FAILURE; } - data = calloc(nelements, 4); + data = calloc(nelements, sizeof(long)); for (i = 0; i < nelements; i++) { - *(data + i) = strtod(argv[2 + i], &endptr); + *((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; @@@ -376,8 -379,6 +379,6 @@@ int delete_prop(Display *dpy, int argc XDevice *dev; XDeviceInfo *info; char *name; - int i; - Bool is_atom = True; Atom prop; info = find_device_info(dpy, argv[0], False); @@@ -396,17 -397,7 +397,7 @@@ 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); @@@ -422,7 -413,7 +413,7 @@@ set_atom_prop(Display *dpy, int argc, c Atom prop; char *name; int i, j; - Bool is_atom = True; + Bool is_atom; Atom *data; int nelements = 0; @@@ -448,17 -439,7 +439,7 @@@ 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); nelements = argc - 2; data = calloc(nelements, sizeof(Atom)); @@@ -490,4 -471,119 +471,119 @@@ return EXIT_SUCCESS; } + int + set_prop(Display *dpy, int argc, char **argv, char *n, char *desc) + { + XDeviceInfo *info; + XDevice *dev; + Atom prop; + Atom type; + char *name; + int i; + Atom float_atom; + int format, nelements = 0; + unsigned long act_nitems, bytes_after; + char *endptr; + union { + unsigned char *c; + short *s; + long *l; + Atom *a; + } data; + + 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]; + + prop = parse_atom(dpy, name); + + if (prop == None) { + fprintf(stderr, "invalid property %s\n", name); + return EXIT_FAILURE; + } + + float_atom = XInternAtom(dpy, "FLOAT", False); + + nelements = argc - 2; + if (XGetDeviceProperty(dpy, dev, prop, 0, 0, False, AnyPropertyType, + &type, &format, &act_nitems, &bytes_after, &data.c) + != Success) { + fprintf(stderr, "failed to get property type and format for %s\n", name); + return EXIT_FAILURE; + } + + XFree(data.c); + + if (type == None) { + fprintf(stderr, "property %s doesn't exist\n", name); + return EXIT_FAILURE; + } + + data.c = calloc(nelements, sizeof(long)); + + for (i = 0; i < nelements; i++) + { + 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, type, format, PropModeReplace, + data.c, nelements); + free(data.c); + XCloseDevice(dpy, dev); + return EXIT_SUCCESS; + } diff --combined src/xinput.c index cc85aff,f584459..da54b48 --- a/src/xinput.c +++ b/src/xinput.c @@@ -106,10 -106,6 +106,10 @@@ static entry drivers[] " ", set_clientpointer }, + { "test-xi2", + "", + test_xi2, + }, #endif { "list-props", " [ ...]", @@@ -135,27 -131,33 +135,31 @@@ " ", delete_prop }, + { "set-prop", + " [ ...]", + set_prop + }, {NULL, NULL, NULL } }; -static Bool -is_xinput_present(Display *display) +int +xinput_version(Display *display) { XExtensionVersion *version; - Bool present; + 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* @@@ -193,7 -195,7 +197,7 @@@ find_device_info(Display *display "Warning: There are multiple devices named \"%s\".\n" "To ensure the correct one is selected, please use " "the device ID instead.\n\n", name); - return NULL; + return NULL; } else { found = &devices[loop]; } @@@ -202,43 -204,6 +206,43 @@@ return found; } +#ifdef HAVE_XI2 +int +xi2_find_device_id(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); + } else + { + 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; + } + } + + XIFreeDeviceInfo(info); + } + return id;; +} +#endif + static void usage(void) { @@@ -275,7 -240,7 +279,7 @@@ main(int argc, char * argv[] func = argv[1]; while((*func) == '-') func++; - if (!is_xinput_present(display)) { + if (!xinput_version(display)) { fprintf(stderr, "%s extension not available\n", INAME); return EXIT_FAILURE; } diff --combined src/xinput.h index 4b68090,c4a6f8f..c7269b9 --- a/src/xinput.h +++ b/src/xinput.h @@@ -27,9 -27,6 +27,9 @@@ #include #include +#ifdef HAVE_XI2 +#include +#endif #include #include #include @@@ -41,47 -38,34 +41,39 @@@ #define EXIT_FAILURE 0 #endif - XDeviceInfo* - find_device_info( - Display *display, - char *name, - Bool only_extended - ); - int - xi2_find_device_id(Display *display, char *name); + + XDeviceInfo* find_device_info( Display *display, char *name, Bool only_extended); ++int xi2_find_device_id(Display *display, char *name); +int xinput_version(Display* display); - #define DECLARE(name) \ - int (name) ( \ - Display* display, \ - int argc, \ - char *argv[], \ - char *prog_name, \ - char *prog_desc \ - ) + 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); + - DECLARE(get_feedbacks); - DECLARE(set_ptr_feedback); - DECLARE(get_button_map); - DECLARE(set_button_map); - DECLARE(set_pointer); - DECLARE(set_mode); - DECLARE(list); - DECLARE(test); - DECLARE(version); - DECLARE(set_integer_feedback); - DECLARE(query_state); - DECLARE(create_master); - DECLARE(remove_master); - DECLARE(change_attachment); - DECLARE(float_device); - DECLARE(set_clientpointer); - DECLARE(test_xi2); - DECLARE(list_props); - DECLARE(set_int_prop); - DECLARE(set_float_prop); - DECLARE(set_atom_prop); - DECLARE(watch_props); - DECLARE(delete_prop); /* end of xinput.h */