diff options
-rw-r--r-- | man/xinput.man | 6 | ||||
-rw-r--r-- | src/property.c | 115 | ||||
-rw-r--r-- | src/xinput.c | 4 | ||||
-rw-r--r-- | src/xinput.h | 11 |
4 files changed, 136 insertions, 0 deletions
diff --git a/man/xinput.man b/man/xinput.man index eeee7b9..104cafb 100644 --- a/man/xinput.man +++ b/man/xinput.man @@ -69,6 +69,12 @@ are 8, 16, or 32, depending on the property. Sets a float property for the device. .PP .TP 8 +.B xinput set-prop \fIdevice_name\fP \fIproperty\fP \fIvalue\fP +Set the property to the given value(s). The format and type of the property +are left as-is and the arguments are interpreted according to the property +type. This argument can only be used to modify existing properties. +.PP +.TP 8 .B xinput watch-props \fIdevice_name\fP Prints to standard out when property changes occur. .PP diff --git a/src/property.c b/src/property.c index 2ac4441..e019765 100644 --- a/src/property.c +++ b/src/property.c @@ -462,4 +462,119 @@ 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) +{ + 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 --git a/src/xinput.c b/src/xinput.c index b319326..f584459 100644 --- a/src/xinput.c +++ b/src/xinput.c @@ -131,6 +131,10 @@ static entry drivers[] = "<device> <property>", delete_prop }, + { "set-prop", + "<device> <property> <val> [<val> ...]", + set_prop + }, {NULL, NULL, NULL } }; diff --git a/src/xinput.h b/src/xinput.h index 3c36497..24c0417 100644 --- a/src/xinput.h +++ b/src/xinput.h @@ -289,4 +289,15 @@ delete_prop( #endif ); +int +set_prop( +#if NeedFunctionPrototypes + Display* display, + int argc, + char *argv[], + char *prog_name, + char *prog_desc +#endif +); + /* end of xinput.h */ |