diff options
| author | Peter Hutterer <peter.hutterer@who-t.net> | 2009-05-07 14:37:58 +1000 |
|---|---|---|
| committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-05-07 14:49:25 +1000 |
| commit | 125074488dc27f484a30a8d076133c73f4d9ef48 (patch) | |
| tree | 37940296839dac26f336cfd31e4bb8d01eddd788 | |
| parent | ff1b12265de1010aa22011c5db829274a8a3dab1 (diff) | |
Add support for XI2 property requests.
If XI2 is available, we use XI2 for list-props, delete-prop and set-prop.
| -rw-r--r-- | src/property.c | 297 |
1 files changed, 293 insertions, 4 deletions
diff --git a/src/property.c b/src/property.c index b5f1107..2b402a9 100644 --- a/src/property.c +++ b/src/property.c @@ -140,7 +140,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; @@ -374,7 +375,8 @@ int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc) XCloseDevice(dpy, dev); } -int delete_prop(Display *dpy, int argc, char** argv, char* n, char *desc) +static int +delete_prop_xi1(Display *dpy, int argc, char** argv, char* n, char *desc) { XDevice *dev; XDeviceInfo *info; @@ -471,8 +473,8 @@ set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc) return EXIT_SUCCESS; } -int -set_prop(Display *dpy, int argc, char **argv, char *n, char *desc) +static int +set_prop_xi1(Display *dpy, int argc, char **argv, char *n, char *desc) { XDeviceInfo *info; XDevice *dev; @@ -587,3 +589,290 @@ set_prop(Display *dpy, int argc, char **argv, char *n, char *desc) XCloseDevice(dpy, dev); return EXIT_SUCCESS; } + +#if HAVE_XI2 +static void +print_property_xi2(Display *dpy, int deviceid, Atom property) +{ + Atom act_type; + char *name; + int act_format; + unsigned long nitems, bytes_after; + unsigned char *data, *ptr; + int j, done = False; + + name = XGetAtomName(dpy, property); + printf("\t%s (%ld):\t", name, property); + + if (XIGetProperty(dpy, deviceid, property, 0, 1000, False, + AnyPropertyType, &act_type, &act_format, + &nitems, &bytes_after, &data) == Success) + { + Atom float_atom = XInternAtom(dpy, "FLOAT", True); + + ptr = data; + + 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: + printf("\"%s\"", XGetAtomName(dpy, *(Atom*)ptr)); + 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, "Usage: xinput %s %s\n", name, desc); + return EXIT_FAILURE; + } + + for (i = 0; i < argc; i++) + { + info = xi2_find_device_info(dpy, argv[i]); + if (!info) + { + fprintf(stderr, "unable to find device %s\n", argv[i]); + continue; + } + + props = XIListProperties(dpy, info->deviceid, &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_xi2(dpy, info->deviceid, props[nprops]); + } + + XFree(props); + } + return EXIT_SUCCESS; +} + +static int +delete_prop_xi2(Display *dpy, int argc, char** argv, char* n, char *desc) +{ + XIDeviceInfo *info; + char *name; + Atom prop; + + info = xi2_find_device_info(dpy, argv[0]); + if (!info) + { + fprintf(stderr, "unable to find device %s\n", argv[0]); + return EXIT_FAILURE; + } + + name = argv[1]; + + prop = parse_atom(dpy, name); + + XIDeleteProperty(dpy, info->deviceid, prop); + + return EXIT_SUCCESS; +} + +static int +set_prop_xi2(Display *dpy, int argc, char **argv, char *n, char *desc) +{ + XIDeviceInfo *info; + 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; + int16_t *s; + int32_t *l; + } data; + + if (argc < 3) + { + fprintf(stderr, "Usage: xinput %s %s\n", n, desc); + return EXIT_FAILURE; + } + + info = xi2_find_device_info(dpy, argv[0]); + if (!info) + { + fprintf(stderr, "unable to find 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 (XIGetProperty(dpy, info->deviceid, 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(int32_t)); + + 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.l[i] = parse_atom(dpy, argv[2 + i]); + } else { + fprintf(stderr, "unexpected type for property %s\n", name); + return EXIT_FAILURE; + } + } + + 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); + +} + +int set_prop(Display *display, int argc, char *argv[], char *name, + char *desc) +{ +#ifdef HAVE_XI2 + if (xinput_version(display) == XI_2_Major) + return set_prop_xi2(display, argc, argv, name, desc); +#endif + return set_prop_xi1(display, argc, argv, name, desc); +} |
