X-Git-Url: https://diplodocus.org/git/xorg-xinput/blobdiff_plain/13e9758b2ebd5d545c08903aab0eccd423851a30..refs/heads/master:/src/property.c?ds=inline diff --git a/src/property.c b/src/property.c index e8ce611..e3baef3 100644 --- a/src/property.c +++ b/src/property.c @@ -1,28 +1,25 @@ /* - * Copyright 2007 Peter Hutterer + * Copyright © 2007 Peter Hutterer + * Copyright © 2009 Red Hat, Inc. * - * 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. + * 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 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. + * 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 @@ -59,10 +56,11 @@ print_property(Display *dpy, XDevice* dev, Atom property) int act_format; unsigned long nitems, bytes_after; unsigned char *data, *ptr; - int j, done = False, size; + int j, done = False, size = 0; name = XGetAtomName(dpy, property); printf("\t%s (%ld):\t", name, property); + XFree(name); if (XGetDeviceProperty(dpy, dev, property, 0, 1000, False, AnyPropertyType, &act_type, &act_format, @@ -100,6 +98,20 @@ print_property(Display *dpy, XDevice* dev, Atom property) break; } break; + case XA_CARDINAL: + switch(act_format) + { + case 8: + printf("%u", *((unsigned char*)ptr)); + break; + case 16: + printf("%u", *((unsigned short*)ptr)); + break; + case 32: + printf("%lu", *((unsigned long*)ptr)); + break; + } + break; case XA_STRING: if (act_format != 8) { @@ -116,9 +128,9 @@ print_property(Display *dpy, XDevice* dev, Atom property) case XA_ATOM: { Atom a = *(Atom*)ptr; - printf("\"%s\" (%d)", - (a) ? XGetAtomName(dpy, a) : "None", - (int)a); + name = (a) ? XGetAtomName(dpy, a) : NULL; + printf("\"%s\" (%d)", name ? name : "None", (int)a); + XFree(name); break; } default: @@ -128,8 +140,9 @@ print_property(Display *dpy, XDevice* dev, Atom property) break; } - printf("\t... of unknown type %s\n", - XGetAtomName(dpy, act_type)); + name = XGetAtomName(dpy, act_type); + printf("\t... of unknown type '%s'\n", name); + XFree(name); done = True; break; } @@ -156,6 +169,7 @@ list_props_xi1(Display *dpy, int argc, char** argv, char* name, char *desc) int i; int nprops; Atom *props; + int rc = EXIT_SUCCESS; if (argc == 0) { @@ -168,7 +182,8 @@ list_props_xi1(Display *dpy, int argc, char** argv, char* name, char *desc) info = find_device_info(dpy, argv[i], False); if (!info) { - fprintf(stderr, "unable to find device %s\n", argv[i]); + fprintf(stderr, "unable to find device '%s'\n", argv[i]); + rc = EXIT_FAILURE; continue; } @@ -176,6 +191,7 @@ list_props_xi1(Display *dpy, int argc, char** argv, char* name, char *desc) if (!dev) { fprintf(stderr, "unable to open device '%s'\n", info->name); + rc = EXIT_FAILURE; continue; } @@ -195,145 +211,7 @@ list_props_xi1(Display *dpy, int argc, char** argv, char* name, char *desc) 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; - 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]; - - prop = parse_atom(dpy, name); - - 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, sizeof(long)); - for (i = 0; i < nelements; i++) - { - 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; - } - } - - XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, format, PropModeReplace, - (unsigned char*)data, nelements); - - free(data); - XCloseDevice(dpy, dev); - return EXIT_SUCCESS; -} - -int -set_float_prop(Display *dpy, int argc, char** argv, char* n, char *desc) -{ - XDeviceInfo *info; - XDevice *dev; - Atom prop, float_atom; - char *name; - int i; - long *data; - int nelements = 0; - char* endptr; - - if (argc < 2) - { - 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); - - nelements = argc - 2; - - float_atom = XInternAtom(dpy, "FLOAT", False); - - if (float_atom == (Atom)0) - { - fprintf(stderr, "no FLOAT atom present in server\n"); - return EXIT_FAILURE; - } - - if (sizeof(float) != 4) - { - fprintf(stderr, "sane FP required\n"); - return EXIT_FAILURE; - } - - data = 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; - } - } - - XChangeDeviceProperty(dpy, dev, prop, float_atom, 32, PropModeReplace, - (unsigned char*)data, nelements); - - free(data); - XCloseDevice(dpy, dev); - return EXIT_SUCCESS; + return rc; } @@ -353,7 +231,7 @@ int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc) info = find_device_info(dpy, argv[0], False); if (!info) { - fprintf(stderr, "unable to find device %s\n", argv[0]); + fprintf(stderr, "unable to find device '%s'\n", argv[0]); return EXIT_FAILURE; } @@ -377,6 +255,7 @@ int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc) name = XGetAtomName(dpy, dpev->atom); printf("Property '%s' changed.\n", name); + XFree(name); print_property(dpy, dev, dpev->atom); } @@ -391,43 +270,7 @@ delete_prop_xi1(Display *dpy, int argc, char** argv, char* n, char *desc) char *name; Atom prop; - 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; - } - - name = argv[1]; - - prop = parse_atom(dpy, name); - - XDeleteDeviceProperty(dpy, dev, prop); - - XCloseDevice(dpy, dev); - return EXIT_SUCCESS; -} - -int -set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc) -{ - XDeviceInfo *info; - XDevice *dev; - Atom prop; - char *name; - int i, j; - Bool is_atom; - Atom *data; - int nelements = 0; - - if (argc < 3) + if (argc < 2) { fprintf(stderr, "Usage: xinput %s %s\n", n, desc); return EXIT_FAILURE; @@ -436,14 +279,14 @@ set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc) info = find_device_info(dpy, argv[0], False); if (!info) { - fprintf(stderr, "unable to find device %s\n", argv[0]); + 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]); + fprintf(stderr, "unable to open device '%s'\n", info->name); return EXIT_FAILURE; } @@ -451,47 +294,23 @@ set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc) prop = parse_atom(dpy, name); - 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 (!is_atom) - data[i] = XInternAtom(dpy, name, False); - else - { - data[i] = atoi(name); - XFree(XGetAtomName(dpy, data[i])); - } - } - - XChangeDeviceProperty(dpy, dev, prop, XA_ATOM, 32, PropModeReplace, - (unsigned char*)data, nelements); + XDeleteDeviceProperty(dpy, dev, prop); - free(data); XCloseDevice(dpy, dev); return EXIT_SUCCESS; } static int -set_prop_xi1(Display *dpy, int argc, char **argv, char *n, char *desc) +do_set_prop_xi1(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc) { XDeviceInfo *info; XDevice *dev; Atom prop; - Atom type; + Atom old_type; char *name; int i; Atom float_atom; - int format, nelements = 0; + int old_format, nelements = 0; unsigned long act_nitems, bytes_after; char *endptr; union { @@ -510,14 +329,14 @@ set_prop_xi1(Display *dpy, int argc, char **argv, char *n, char *desc) info = find_device_info(dpy, argv[0], False); if (!info) { - fprintf(stderr, "unable to find device %s\n", argv[0]); + 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]); + fprintf(stderr, "unable to open device '%s'\n", argv[0]); return EXIT_FAILURE; } @@ -526,24 +345,33 @@ set_prop_xi1(Display *dpy, int argc, char **argv, char *n, char *desc) prop = parse_atom(dpy, name); if (prop == None) { - fprintf(stderr, "invalid property %s\n", name); + 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; - } + 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; + } - XFree(data.c); + XFree(data.c); + } if (type == None) { - fprintf(stderr, "property %s doesn't exist\n", name); + fprintf(stderr, "property '%s' doesn't exist, you need to specify " + "its type and format\n", name); return EXIT_FAILURE; } @@ -551,7 +379,7 @@ set_prop_xi1(Display *dpy, int argc, char **argv, char *n, char *desc) for (i = 0; i < nelements; i++) { - if (type == XA_INTEGER) { + if (type == XA_INTEGER || type == XA_CARDINAL) { switch (format) { case 8: @@ -564,29 +392,29 @@ set_prop_xi1(Display *dpy, int argc, char **argv, char *n, char *desc) data.l[i] = atoi(argv[2 + i]); break; default: - fprintf(stderr, "unexpected size for property %s", name); + 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", + 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]); + 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", + 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); + fprintf(stderr, "unexpected type for property '%s'\n", name); return EXIT_FAILURE; } } @@ -611,6 +439,7 @@ print_property_xi2(Display *dpy, int deviceid, Atom property) name = XGetAtomName(dpy, property); printf("\t%s (%ld):\t", name, property); + XFree(name); if (XIGetProperty(dpy, deviceid, property, 0, 1000, False, AnyPropertyType, &act_type, &act_format, @@ -620,6 +449,9 @@ print_property_xi2(Display *dpy, int deviceid, Atom property) ptr = data; + if (nitems == 0) + printf(""); + for (j = 0; j < nitems; j++) { switch(act_type) @@ -638,6 +470,20 @@ print_property_xi2(Display *dpy, int deviceid, Atom property) break; } break; + case XA_CARDINAL: + switch(act_format) + { + case 8: + printf("%u", *((uint8_t*)ptr)); + break; + case 16: + printf("%u", *((uint16_t*)ptr)); + break; + case 32: + printf("%u", *((uint32_t*)ptr)); + break; + } + break; case XA_STRING: if (act_format != 8) { @@ -653,10 +499,10 @@ print_property_xi2(Display *dpy, int deviceid, Atom property) break; case XA_ATOM: { - Atom a = *(Atom*)ptr; - printf("\"%s\" (%d)", - (a) ? XGetAtomName(dpy, a) : "None", - (int)a); + Atom a = *(uint32_t*)ptr; + name = (a) ? XGetAtomName(dpy, a) : NULL; + printf("\"%s\" (%ld)", name ? name : "None", a); + XFree(name); break; } break; @@ -667,8 +513,9 @@ print_property_xi2(Display *dpy, int deviceid, Atom property) break; } - printf("\t... of unknown type %s\n", - XGetAtomName(dpy, act_type)); + name = XGetAtomName(dpy, act_type); + printf("\t... of unknown type %s\n", name); + XFree(name); done = True; break; } @@ -694,6 +541,7 @@ list_props_xi2(Display *dpy, int argc, char** argv, char* name, char *desc) int i; int nprops; Atom *props; + int rc = EXIT_SUCCESS; if (argc == 0) { @@ -707,6 +555,7 @@ list_props_xi2(Display *dpy, int argc, char** argv, char* name, char *desc) if (!info) { fprintf(stderr, "unable to find device %s\n", argv[i]); + rc = EXIT_FAILURE; continue; } @@ -725,7 +574,7 @@ list_props_xi2(Display *dpy, int argc, char** argv, char* name, char *desc) XFree(props); } - return EXIT_SUCCESS; + return rc; } static int @@ -735,6 +584,12 @@ delete_prop_xi2(Display *dpy, int argc, char** argv, char* n, char *desc) char *name; Atom prop; + if (argc < 2) + { + fprintf(stderr, "Usage: xinput %s %s\n", n, desc); + return EXIT_FAILURE; + } + info = xi2_find_device_info(dpy, argv[0]); if (!info) { @@ -752,34 +607,35 @@ delete_prop_xi2(Display *dpy, int argc, char** argv, char* n, char *desc) } static int -set_prop_xi2(Display *dpy, int argc, char **argv, char *n, char *desc) +do_set_prop_xi2(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc) { XIDeviceInfo *info; Atom prop; - Atom type; + Atom old_type; char *name; int i; Atom float_atom; - int format, nelements = 0; + int old_format, nelements = 0; unsigned long act_nitems, bytes_after; char *endptr; union { unsigned char *c; int16_t *s; int32_t *l; - } data; + } data = { NULL }; + int rc = EXIT_FAILURE; if (argc < 3) { fprintf(stderr, "Usage: xinput %s %s\n", n, desc); - return EXIT_FAILURE; + goto out; } info = xi2_find_device_info(dpy, argv[0]); if (!info) { fprintf(stderr, "unable to find device %s\n", argv[0]); - return EXIT_FAILURE; + goto out; } name = argv[1]; @@ -787,32 +643,41 @@ set_prop_xi2(Display *dpy, int argc, char **argv, char *n, char *desc) prop = parse_atom(dpy, name); if (prop == None) { - fprintf(stderr, "invalid property %s\n", name); - return EXIT_FAILURE; + fprintf(stderr, "invalid property '%s'\n", name); + goto out; } 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; - } + 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); + goto out; + } else { + if (type == None) + type = old_type; + if (format == 0) + format = old_format; + } - XFree(data.c); + XFree(data.c); + } if (type == None) { - fprintf(stderr, "property %s doesn't exist\n", name); - return EXIT_FAILURE; + fprintf(stderr, "property '%s' doesn't exist, you need to specify " + "its type and format\n", name); + goto out; } data.c = calloc(nelements, sizeof(int32_t)); for (i = 0; i < nelements; i++) { - if (type == XA_INTEGER) { + if (type == XA_INTEGER || type == XA_CARDINAL) { switch (format) { case 8: @@ -826,43 +691,45 @@ set_prop_xi2(Display *dpy, int argc, char **argv, char *n, char *desc) break; default: fprintf(stderr, "unexpected size for property %s", name); - return EXIT_FAILURE; + goto out; } } else if (type == float_atom) { if (format != 32) { - fprintf(stderr, "unexpected format %d for property %s\n", + fprintf(stderr, "unexpected format %d for property '%s'\n", format, name); - return EXIT_FAILURE; + goto out; } *(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; + goto out; } } else if (type == XA_ATOM) { if (format != 32) { - fprintf(stderr, "unexpected format %d for property %s\n", + fprintf(stderr, "unexpected format %d for property '%s'\n", format, name); - return EXIT_FAILURE; + goto out; } data.l[i] = parse_atom(dpy, argv[2 + i]); } else { - fprintf(stderr, "unexpected type for property %s\n", name); - return EXIT_FAILURE; + fprintf(stderr, "unexpected type for property '%s'\n", name); + goto out; } } XIChangeProperty(dpy, info->deviceid, prop, type, format, PropModeReplace, data.c, nelements); + rc = EXIT_SUCCESS; +out: free(data.c); - return EXIT_SUCCESS; + return rc; } #endif int list_props(Display *display, int argc, char *argv[], char *name, char *desc) { -#ifdef HAVE_XI2 +#if HAVE_XI2 if (xinput_version(display) == XI_2_Major) return list_props_xi2(display, argc, argv, name, desc); #endif @@ -873,7 +740,7 @@ int list_props(Display *display, int argc, char *argv[], char *name, int delete_prop(Display *display, int argc, char *argv[], char *name, char *desc) { -#ifdef HAVE_XI2 +#if HAVE_XI2 if (xinput_version(display) == XI_2_Major) return delete_prop_xi2(display, argc, argv, name, desc); #endif @@ -881,12 +748,132 @@ int delete_prop(Display *display, int argc, char *argv[], char *name, } -int set_prop(Display *display, int argc, char *argv[], char *name, - char *desc) +static int +do_set_prop(Display *display, Atom type, int format, int argc, char *argv[], char *name, char *desc) { -#ifdef HAVE_XI2 +#if HAVE_XI2 if (xinput_version(display) == XI_2_Major) - return set_prop_xi2(display, argc, argv, name, desc); + return do_set_prop_xi2(display, type, format, argc, argv, name, desc); #endif - return set_prop_xi1(display, argc, argv, name, desc); + 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; + } + + format = atoi(argv[2]); + if (format != 8 && format != 16 && format != 32) + { + fprintf(stderr, "Invalid format %d\n", format); + return EXIT_FAILURE; + } + + 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); +} + +int disable(Display *display, int argc, char *argv[], char *name, char *desc) +{ + char *new_argv[3] = { NULL, "Device Enabled", "0" }; + + if (argc != 1) { + fprintf(stderr, "Usage: xinput %s %s\n", name, desc); + return EXIT_FAILURE; + } + + new_argv[0] = argv[0]; + + return set_prop(display, 3, new_argv, name, desc); +} + +int enable(Display *display, int argc, char *argv[], char *name, char *desc) +{ + char *new_argv[3] = { NULL, "Device Enabled", "1" }; + + if (argc != 1) { + fprintf(stderr, "Usage: xinput %s %s\n", name, desc); + return EXIT_FAILURE; + } + + new_argv[0] = argv[0]; + + return set_prop(display, 3, new_argv, name, desc); }