]> diplodocus.org Git - xorg-xinput/blob - src/property.c
xinput 1.4.0
[xorg-xinput] / src / property.c
1 /*
2 * Copyright 2007 Peter Hutterer
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation.
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 * OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of the author shall
22 * not be used in advertising or otherwise to promote the sale, use or
23 * other dealings in this Software without prior written authorization
24 * from the author.
25 *
26 */
27
28 #include <ctype.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <X11/Xatom.h>
33 #include <X11/extensions/XIproto.h>
34
35 #include "xinput.h"
36
37 static void
38 print_property(Display *dpy, XDevice* dev, Atom property)
39 {
40 Atom act_type;
41 char *name;
42 int act_format;
43 unsigned long nitems, bytes_after;
44 unsigned char *data, *ptr;
45 int j;
46
47 name = XGetAtomName(dpy, property);
48 printf("\t%s (%ld):\t", name, property);
49
50 if (XGetDeviceProperty(dpy, dev, property, 0, 1000, False,
51 AnyPropertyType, &act_type, &act_format,
52 &nitems, &bytes_after, &data) == Success)
53 {
54 int float_atom = XInternAtom(dpy, "FLOAT", False);
55
56 ptr = data;
57 printf("\t");
58
59 for (j = 0; j < nitems; j++)
60 {
61 switch(act_type)
62 {
63 case XA_INTEGER:
64 switch(act_format)
65 {
66 case 8:
67 printf("%d", *((int8_t*)ptr));
68 break;
69 case 16:
70 printf("%d", *((int16_t*)ptr));
71 break;
72 case 32:
73 printf("%d", *((int32_t*)ptr));
74 break;
75 }
76 break;
77 case XA_STRING:
78 printf("\t%s", ptr);
79 break;
80 case XA_ATOM:
81 printf("\t%s", XGetAtomName(dpy, *(Atom*)ptr));
82 break;
83 default:
84 if (float_atom != None && act_type == float_atom)
85 {
86 printf("\t%f\n", *((float*)ptr));
87 break;
88 }
89
90 printf("\t\t... of unknown type %s\n",
91 XGetAtomName(dpy, act_type));
92 break;
93 }
94
95 ptr += act_format/8;
96
97 if (j < nitems - 1)
98 printf(", ");
99 if (act_type == XA_STRING)
100 break;
101 }
102 printf("\n");
103 XFree(data);
104 } else
105 printf("\tFetch failure\n");
106
107 }
108
109 int list_props(Display *dpy, int argc, char** argv, char* name, char *desc)
110 {
111 XDeviceInfo *info;
112 XDevice *dev;
113 int i;
114 int nprops;
115 Atom *props;
116
117 if (argc == 0)
118 {
119 fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
120 return EXIT_FAILURE;
121 }
122
123 for (i = 0; i < argc; i++)
124 {
125 info = find_device_info(dpy, argv[i], False);
126 if (!info)
127 {
128 fprintf(stderr, "unable to find device %s\n", argv[i]);
129 continue;
130 }
131
132 dev = XOpenDevice(dpy, info->id);
133 if (!dev)
134 {
135 fprintf(stderr, "unable to open device '%s'\n", info->name);
136 continue;
137 }
138
139 props = XListDeviceProperties(dpy, dev, &nprops);
140 if (!nprops)
141 {
142 printf("Device '%s' does not report any properties.\n", info->name);
143 continue;
144 }
145
146 printf("Device '%s':\n", info->name);
147 while(nprops--)
148 {
149 print_property(dpy, dev, props[nprops]);
150 }
151
152 XFree(props);
153 XCloseDevice(dpy, dev);
154 }
155 return EXIT_SUCCESS;
156 }
157
158 int
159 set_int_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
160 {
161 XDeviceInfo *info;
162 XDevice *dev;
163 Atom prop;
164 char *name;
165 int i;
166 Bool is_atom = True;
167 char *data;
168 int format, nelements = 0;
169
170 if (argc < 3)
171 {
172 fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
173 return EXIT_FAILURE;
174 }
175
176 info = find_device_info(dpy, argv[0], False);
177 if (!info)
178 {
179 fprintf(stderr, "unable to find device %s\n", argv[0]);
180 return EXIT_FAILURE;
181 }
182
183 dev = XOpenDevice(dpy, info->id);
184 if (!dev)
185 {
186 fprintf(stderr, "unable to open device %s\n", argv[0]);
187 return EXIT_FAILURE;
188 }
189
190 name = argv[1];
191
192 for(i = 0; i < strlen(name); i++) {
193 if (!isdigit(name[i])) {
194 is_atom = False;
195 break;
196 }
197 }
198
199 if (!is_atom)
200 prop = XInternAtom(dpy, name, False);
201 else
202 prop = atoi(name);
203
204 nelements = argc - 3;
205 format = atoi(argv[2]);
206 if (format != 8 && format != 16 && format != 32)
207 {
208 fprintf(stderr, "Invalid format %d\n", format);
209 return EXIT_FAILURE;
210 }
211
212 data = calloc(nelements, format/8);
213 for (i = 0; i < nelements; i++)
214 {
215 switch(format)
216 {
217 case 8:
218 *(((int8_t*)data) + i) = atoi(argv[3 + i]);
219 break;
220 case 16:
221 *(((int16_t*)data) + i) = atoi(argv[3 + i]);
222 break;
223 case 32:
224 *(((int32_t*)data) + i) = atoi(argv[3 + i]);
225 break;
226 }
227 }
228
229 XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, format, PropModeReplace,
230 (unsigned char*)data, nelements);
231
232 free(data);
233 XCloseDevice(dpy, dev);
234 return EXIT_SUCCESS;
235 }
236
237 int
238 set_float_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
239 {
240 XDeviceInfo *info;
241 XDevice *dev;
242 Atom prop, float_atom;
243 char *name;
244 int i;
245 Bool is_atom = True;
246 float *data;
247 int nelements = 0;
248 char* endptr;
249
250 if (argc < 2)
251 {
252 fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
253 return EXIT_FAILURE;
254 }
255
256 info = find_device_info(dpy, argv[0], False);
257 if (!info)
258 {
259 fprintf(stderr, "unable to find device %s\n", argv[0]);
260 return EXIT_FAILURE;
261 }
262
263 dev = XOpenDevice(dpy, info->id);
264 if (!dev)
265 {
266 fprintf(stderr, "unable to open device %s\n", argv[0]);
267 return EXIT_FAILURE;
268 }
269
270 name = argv[1];
271
272 for(i = 0; i < strlen(name); i++) {
273 if (!isdigit(name[i])) {
274 is_atom = False;
275 break;
276 }
277 }
278
279 if (!is_atom)
280 prop = XInternAtom(dpy, name, False);
281 else
282 prop = atoi(name);
283
284 nelements = argc - 2;
285
286 float_atom = XInternAtom(dpy, "FLOAT", False);
287
288 if (float_atom == (Atom)0)
289 {
290 fprintf(stderr, "no FLOAT atom present in server\n");
291 return EXIT_FAILURE;
292 }
293
294 if (sizeof(float) != 4)
295 {
296 fprintf(stderr, "sane FP required\n");
297 return EXIT_FAILURE;
298 }
299
300 data = calloc(nelements, 4);
301 for (i = 0; i < nelements; i++)
302 {
303 *(data + i) = strtod(argv[2 + i], &endptr);
304 if(endptr == argv[2 + i]){
305 fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
306 return EXIT_FAILURE;
307 }
308 }
309
310 XChangeDeviceProperty(dpy, dev, prop, float_atom, 32, PropModeReplace,
311 (unsigned char*)data, nelements);
312
313 free(data);
314 XCloseDevice(dpy, dev);
315 return EXIT_SUCCESS;
316 }
317
318
319 int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc)
320 {
321 XDevice *dev;
322 XDeviceInfo *info;
323 XEvent ev;
324 XDevicePropertyNotifyEvent *dpev;
325 char *name;
326 int type_prop;
327 XEventClass cls_prop;
328
329 if (list_props(dpy, argc, argv, n, desc) != EXIT_SUCCESS)
330 return EXIT_FAILURE;
331
332 info = find_device_info(dpy, argv[0], False);
333 if (!info)
334 {
335 fprintf(stderr, "unable to find device %s\n", argv[0]);
336 return EXIT_FAILURE;
337 }
338
339 dev = XOpenDevice(dpy, info->id);
340 if (!dev)
341 {
342 fprintf(stderr, "unable to open device '%s'\n", info->name);
343 return EXIT_FAILURE;
344 }
345
346 DevicePropertyNotify(dev, type_prop, cls_prop);
347 XSelectExtensionEvent(dpy, DefaultRootWindow(dpy), &cls_prop, 1);
348
349 while(1)
350 {
351 XNextEvent(dpy, &ev);
352
353 dpev = (XDevicePropertyNotifyEvent*)&ev;
354 if (dpev->type != type_prop)
355 continue;
356
357 name = XGetAtomName(dpy, dpev->atom);
358 printf("Property '%s' changed.\n", name);
359 print_property(dpy, dev, dpev->atom);
360 }
361
362 XCloseDevice(dpy, dev);
363 }
364
365 int delete_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
366 {
367 XDevice *dev;
368 XDeviceInfo *info;
369 char *name;
370 int i;
371 Bool is_atom = True;
372 Atom prop;
373
374 info = find_device_info(dpy, argv[0], False);
375 if (!info)
376 {
377 fprintf(stderr, "unable to find device %s\n", argv[0]);
378 return EXIT_FAILURE;
379 }
380
381 dev = XOpenDevice(dpy, info->id);
382 if (!dev)
383 {
384 fprintf(stderr, "unable to open device '%s'\n", info->name);
385 return EXIT_FAILURE;
386 }
387
388 name = argv[1];
389
390 for(i = 0; i < strlen(name); i++) {
391 if (!isdigit(name[i])) {
392 is_atom = False;
393 break;
394 }
395 }
396
397 if (!is_atom)
398 prop = XInternAtom(dpy, name, False);
399 else
400 prop = atoi(name);
401
402 XDeleteDeviceProperty(dpy, dev, prop);
403
404 XCloseDevice(dpy, dev);
405 return EXIT_SUCCESS;
406 }
407
408 int
409 set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
410 {
411 XDeviceInfo *info;
412 XDevice *dev;
413 Atom prop;
414 char *name;
415 int i, j;
416 Bool is_atom = True;
417 Atom *data;
418 int nelements = 0;
419
420 if (argc < 3)
421 {
422 fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
423 return EXIT_FAILURE;
424 }
425
426 info = find_device_info(dpy, argv[0], False);
427 if (!info)
428 {
429 fprintf(stderr, "unable to find device %s\n", argv[0]);
430 return EXIT_FAILURE;
431 }
432
433 dev = XOpenDevice(dpy, info->id);
434 if (!dev)
435 {
436 fprintf(stderr, "unable to open device %s\n", argv[0]);
437 return EXIT_FAILURE;
438 }
439
440 name = argv[1];
441
442 for(i = 0; i < strlen(name); i++) {
443 if (!isdigit(name[i])) {
444 is_atom = False;
445 break;
446 }
447 }
448
449 if (!is_atom)
450 prop = XInternAtom(dpy, name, False);
451 else
452 prop = atoi(name);
453
454 nelements = argc - 2;
455 data = calloc(nelements, sizeof(Atom));
456 for (i = 0; i < nelements; i++)
457 {
458 is_atom = True;
459 name = argv[2 + i];
460 for(j = 0; j < strlen(name); j++) {
461 if (!isdigit(name[j])) {
462 is_atom = False;
463 break;
464 }
465 }
466
467 if (!is_atom)
468 data[i] = XInternAtom(dpy, name, False);
469 else
470 {
471 data[i] = atoi(name);
472 XFree(XGetAtomName(dpy, data[i]));
473 }
474 }
475
476 XChangeDeviceProperty(dpy, dev, prop, XA_ATOM, 32, PropModeReplace,
477 (unsigned char*)data, nelements);
478
479 free(data);
480 XCloseDevice(dpy, dev);
481 return EXIT_SUCCESS;
482 }
483
484