summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/xinput.man6
-rw-r--r--src/property.c115
-rw-r--r--src/xinput.c4
-rw-r--r--src/xinput.h11
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 */