]> diplodocus.org Git - xorg-xinput/blob - src/property.c
bf04eeba4fcd9e43bdeada4f9fcdf2e3d51ae286
[xorg-xinput] / src / property.c
1 /*
2 * Copyright © 2007 Peter Hutterer
3 * Copyright © 2009 Red Hat, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <ctype.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdint.h>
29 #include <X11/Xatom.h>
30 #include <X11/extensions/XIproto.h>
31
32 #include "xinput.h"
33
34 static Atom parse_atom(Display *dpy, char *name) {
35 Bool is_atom = True;
36 int i;
37
38 for (i = 0; name[i] != '\0'; i++) {
39 if (!isdigit(name[i])) {
40 is_atom = False;
41 break;
42 }
43 }
44
45 if (is_atom)
46 return atoi(name);
47 else
48 return XInternAtom(dpy, name, False);
49 }
50
51 static void
52 print_property(Display *dpy, XDevice* dev, Atom property)
53 {
54 Atom act_type;
55 char *name;
56 int act_format;
57 unsigned long nitems, bytes_after;
58 unsigned char *data, *ptr;
59 int j, done = False, size = 0;
60
61 name = XGetAtomName(dpy, property);
62 printf("\t%s (%ld):\t", name, property);
63 XFree(name);
64
65 if (XGetDeviceProperty(dpy, dev, property, 0, 1000, False,
66 AnyPropertyType, &act_type, &act_format,
67 &nitems, &bytes_after, &data) == Success)
68 {
69 Atom float_atom = XInternAtom(dpy, "FLOAT", True);
70
71 ptr = data;
72
73 if (nitems == 0)
74 printf("<no items>");
75
76 switch(act_format)
77 {
78 case 8: size = sizeof(char); break;
79 case 16: size = sizeof(short); break;
80 case 32: size = sizeof(long); break;
81 }
82
83 for (j = 0; j < nitems; j++)
84 {
85 switch(act_type)
86 {
87 case XA_INTEGER:
88 switch(act_format)
89 {
90 case 8:
91 printf("%d", *((char*)ptr));
92 break;
93 case 16:
94 printf("%d", *((short*)ptr));
95 break;
96 case 32:
97 printf("%ld", *((long*)ptr));
98 break;
99 }
100 break;
101 case XA_CARDINAL:
102 switch(act_format)
103 {
104 case 8:
105 printf("%u", *((unsigned char*)ptr));
106 break;
107 case 16:
108 printf("%u", *((unsigned short*)ptr));
109 break;
110 case 32:
111 printf("%lu", *((unsigned long*)ptr));
112 break;
113 }
114 break;
115 case XA_STRING:
116 if (act_format != 8)
117 {
118 printf("Unknown string format.\n");
119 done = True;
120 break;
121 }
122 printf("\"%s\"", ptr);
123 j += strlen((char*)ptr); /* The loop's j++ jumps over the
124 terminating 0 */
125 ptr += strlen((char*)ptr); /* ptr += size below jumps over
126 the terminating 0 */
127 break;
128 case XA_ATOM:
129 {
130 Atom a = *(Atom*)ptr;
131 name = (a) ? XGetAtomName(dpy, a) : NULL;
132 printf("\"%s\" (%d)", name ? name : "None", (int)a);
133 XFree(name);
134 break;
135 }
136 default:
137 if (float_atom != None && act_type == float_atom)
138 {
139 printf("%f", *((float*)ptr));
140 break;
141 }
142
143 name = XGetAtomName(dpy, act_type);
144 printf("\t... of unknown type '%s'\n", name);
145 XFree(name);
146 done = True;
147 break;
148 }
149
150 ptr += size;
151
152 if (done == True)
153 break;
154 if (j < nitems - 1)
155 printf(", ");
156 }
157 printf("\n");
158 XFree(data);
159 } else
160 printf("\tFetch failure\n");
161
162 }
163
164 static int
165 list_props_xi1(Display *dpy, int argc, char** argv, char* name, char *desc)
166 {
167 XDeviceInfo *info;
168 XDevice *dev;
169 int i;
170 int nprops;
171 Atom *props;
172
173 if (argc == 0)
174 {
175 fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
176 return EXIT_FAILURE;
177 }
178
179 for (i = 0; i < argc; i++)
180 {
181 info = find_device_info(dpy, argv[i], False);
182 if (!info)
183 {
184 fprintf(stderr, "unable to find device '%s'\n", argv[i]);
185 continue;
186 }
187
188 dev = XOpenDevice(dpy, info->id);
189 if (!dev)
190 {
191 fprintf(stderr, "unable to open device '%s'\n", info->name);
192 continue;
193 }
194
195 props = XListDeviceProperties(dpy, dev, &nprops);
196 if (!nprops)
197 {
198 printf("Device '%s' does not report any properties.\n", info->name);
199 continue;
200 }
201
202 printf("Device '%s':\n", info->name);
203 while(nprops--)
204 {
205 print_property(dpy, dev, props[nprops]);
206 }
207
208 XFree(props);
209 XCloseDevice(dpy, dev);
210 }
211 return EXIT_SUCCESS;
212 }
213
214
215 int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc)
216 {
217 XDevice *dev;
218 XDeviceInfo *info;
219 XEvent ev;
220 XDevicePropertyNotifyEvent *dpev;
221 char *name;
222 int type_prop;
223 XEventClass cls_prop;
224
225 if (list_props(dpy, argc, argv, n, desc) != EXIT_SUCCESS)
226 return EXIT_FAILURE;
227
228 info = find_device_info(dpy, argv[0], False);
229 if (!info)
230 {
231 fprintf(stderr, "unable to find device '%s'\n", argv[0]);
232 return EXIT_FAILURE;
233 }
234
235 dev = XOpenDevice(dpy, info->id);
236 if (!dev)
237 {
238 fprintf(stderr, "unable to open device '%s'\n", info->name);
239 return EXIT_FAILURE;
240 }
241
242 DevicePropertyNotify(dev, type_prop, cls_prop);
243 XSelectExtensionEvent(dpy, DefaultRootWindow(dpy), &cls_prop, 1);
244
245 while(1)
246 {
247 XNextEvent(dpy, &ev);
248
249 dpev = (XDevicePropertyNotifyEvent*)&ev;
250 if (dpev->type != type_prop)
251 continue;
252
253 name = XGetAtomName(dpy, dpev->atom);
254 printf("Property '%s' changed.\n", name);
255 XFree(name);
256 print_property(dpy, dev, dpev->atom);
257 }
258
259 XCloseDevice(dpy, dev);
260 }
261
262 static int
263 delete_prop_xi1(Display *dpy, int argc, char** argv, char* n, char *desc)
264 {
265 XDevice *dev;
266 XDeviceInfo *info;
267 char *name;
268 Atom prop;
269
270 info = find_device_info(dpy, argv[0], False);
271 if (!info)
272 {
273 fprintf(stderr, "unable to find device '%s'\n", argv[0]);
274 return EXIT_FAILURE;
275 }
276
277 dev = XOpenDevice(dpy, info->id);
278 if (!dev)
279 {
280 fprintf(stderr, "unable to open device '%s'\n", info->name);
281 return EXIT_FAILURE;
282 }
283
284 name = argv[1];
285
286 prop = parse_atom(dpy, name);
287
288 XDeleteDeviceProperty(dpy, dev, prop);
289
290 XCloseDevice(dpy, dev);
291 return EXIT_SUCCESS;
292 }
293
294 static int
295 do_set_prop_xi1(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc)
296 {
297 XDeviceInfo *info;
298 XDevice *dev;
299 Atom prop;
300 Atom old_type;
301 char *name;
302 int i;
303 Atom float_atom;
304 int old_format, nelements = 0;
305 unsigned long act_nitems, bytes_after;
306 char *endptr;
307 union {
308 unsigned char *c;
309 short *s;
310 long *l;
311 Atom *a;
312 } data;
313
314 if (argc < 3)
315 {
316 fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
317 return EXIT_FAILURE;
318 }
319
320 info = find_device_info(dpy, argv[0], False);
321 if (!info)
322 {
323 fprintf(stderr, "unable to find device '%s'\n", argv[0]);
324 return EXIT_FAILURE;
325 }
326
327 dev = XOpenDevice(dpy, info->id);
328 if (!dev)
329 {
330 fprintf(stderr, "unable to open device '%s'\n", argv[0]);
331 return EXIT_FAILURE;
332 }
333
334 name = argv[1];
335
336 prop = parse_atom(dpy, name);
337
338 if (prop == None) {
339 fprintf(stderr, "invalid property '%s'\n", name);
340 return EXIT_FAILURE;
341 }
342
343 float_atom = XInternAtom(dpy, "FLOAT", False);
344
345 nelements = argc - 2;
346 if (type == None || format == 0) {
347 if (XGetDeviceProperty(dpy, dev, prop, 0, 0, False, AnyPropertyType,
348 &old_type, &old_format, &act_nitems,
349 &bytes_after, &data.c) != Success) {
350 fprintf(stderr, "failed to get property type and format for '%s'\n",
351 name);
352 return EXIT_FAILURE;
353 } else {
354 if (type == None)
355 type = old_type;
356 if (format == 0)
357 format = old_format;
358 }
359
360 XFree(data.c);
361 }
362
363 if (type == None) {
364 fprintf(stderr, "property '%s' doesn't exist, you need to specify "
365 "its type and format\n", name);
366 return EXIT_FAILURE;
367 }
368
369 data.c = calloc(nelements, sizeof(long));
370
371 for (i = 0; i < nelements; i++)
372 {
373 if (type == XA_INTEGER || type == XA_CARDINAL) {
374 switch (format)
375 {
376 case 8:
377 data.c[i] = atoi(argv[2 + i]);
378 break;
379 case 16:
380 data.s[i] = atoi(argv[2 + i]);
381 break;
382 case 32:
383 data.l[i] = atoi(argv[2 + i]);
384 break;
385 default:
386 fprintf(stderr, "unexpected size for property '%s'", name);
387 return EXIT_FAILURE;
388 }
389 } else if (type == float_atom) {
390 if (format != 32) {
391 fprintf(stderr, "unexpected format %d for property '%s'\n",
392 format, name);
393 return EXIT_FAILURE;
394 }
395 *(float *)(data.l + i) = strtod(argv[2 + i], &endptr);
396 if (endptr == argv[2 + i]) {
397 fprintf(stderr, "argument '%s' could not be parsed\n", argv[2 + i]);
398 return EXIT_FAILURE;
399 }
400 } else if (type == XA_ATOM) {
401 if (format != 32) {
402 fprintf(stderr, "unexpected format %d for property '%s'\n",
403 format, name);
404 return EXIT_FAILURE;
405 }
406 data.a[i] = parse_atom(dpy, argv[2 + i]);
407 } else {
408 fprintf(stderr, "unexpected type for property '%s'\n", name);
409 return EXIT_FAILURE;
410 }
411 }
412
413 XChangeDeviceProperty(dpy, dev, prop, type, format, PropModeReplace,
414 data.c, nelements);
415 free(data.c);
416 XCloseDevice(dpy, dev);
417 return EXIT_SUCCESS;
418 }
419
420 #if HAVE_XI2
421 static void
422 print_property_xi2(Display *dpy, int deviceid, Atom property)
423 {
424 Atom act_type;
425 char *name;
426 int act_format;
427 unsigned long nitems, bytes_after;
428 unsigned char *data, *ptr;
429 int j, done = False;
430
431 name = XGetAtomName(dpy, property);
432 printf("\t%s (%ld):\t", name, property);
433 XFree(name);
434
435 if (XIGetProperty(dpy, deviceid, property, 0, 1000, False,
436 AnyPropertyType, &act_type, &act_format,
437 &nitems, &bytes_after, &data) == Success)
438 {
439 Atom float_atom = XInternAtom(dpy, "FLOAT", True);
440
441 ptr = data;
442
443 if (nitems == 0)
444 printf("<no items>");
445
446 for (j = 0; j < nitems; j++)
447 {
448 switch(act_type)
449 {
450 case XA_INTEGER:
451 switch(act_format)
452 {
453 case 8:
454 printf("%d", *((int8_t*)ptr));
455 break;
456 case 16:
457 printf("%d", *((int16_t*)ptr));
458 break;
459 case 32:
460 printf("%d", *((int32_t*)ptr));
461 break;
462 }
463 break;
464 case XA_CARDINAL:
465 switch(act_format)
466 {
467 case 8:
468 printf("%u", *((uint8_t*)ptr));
469 break;
470 case 16:
471 printf("%u", *((uint16_t*)ptr));
472 break;
473 case 32:
474 printf("%u", *((uint32_t*)ptr));
475 break;
476 }
477 break;
478 case XA_STRING:
479 if (act_format != 8)
480 {
481 printf("Unknown string format.\n");
482 done = True;
483 break;
484 }
485 printf("\"%s\"", ptr);
486 j += strlen((char*)ptr); /* The loop's j++ jumps over the
487 terminating 0 */
488 ptr += strlen((char*)ptr); /* ptr += size below jumps over
489 the terminating 0 */
490 break;
491 case XA_ATOM:
492 {
493 Atom a = *(uint32_t*)ptr;
494 name = (a) ? XGetAtomName(dpy, a) : NULL;
495 printf("\"%s\" (%ld)", name ? name : "None", a);
496 XFree(name);
497 break;
498 }
499 break;
500 default:
501 if (float_atom != None && act_type == float_atom)
502 {
503 printf("%f", *((float*)ptr));
504 break;
505 }
506
507 name = XGetAtomName(dpy, act_type);
508 printf("\t... of unknown type %s\n", name);
509 XFree(name);
510 done = True;
511 break;
512 }
513
514 ptr += act_format/8;
515
516 if (done == True)
517 break;
518 if (j < nitems - 1)
519 printf(", ");
520 }
521 printf("\n");
522 XFree(data);
523 } else
524 printf("\tFetch failure\n");
525
526 }
527
528 static int
529 list_props_xi2(Display *dpy, int argc, char** argv, char* name, char *desc)
530 {
531 XIDeviceInfo *info;
532 int i;
533 int nprops;
534 Atom *props;
535
536 if (argc == 0)
537 {
538 fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
539 return EXIT_FAILURE;
540 }
541
542 for (i = 0; i < argc; i++)
543 {
544 info = xi2_find_device_info(dpy, argv[i]);
545 if (!info)
546 {
547 fprintf(stderr, "unable to find device %s\n", argv[i]);
548 continue;
549 }
550
551 props = XIListProperties(dpy, info->deviceid, &nprops);
552 if (!nprops)
553 {
554 printf("Device '%s' does not report any properties.\n", info->name);
555 continue;
556 }
557
558 printf("Device '%s':\n", info->name);
559 while(nprops--)
560 {
561 print_property_xi2(dpy, info->deviceid, props[nprops]);
562 }
563
564 XFree(props);
565 }
566 return EXIT_SUCCESS;
567 }
568
569 static int
570 delete_prop_xi2(Display *dpy, int argc, char** argv, char* n, char *desc)
571 {
572 XIDeviceInfo *info;
573 char *name;
574 Atom prop;
575
576 info = xi2_find_device_info(dpy, argv[0]);
577 if (!info)
578 {
579 fprintf(stderr, "unable to find device %s\n", argv[0]);
580 return EXIT_FAILURE;
581 }
582
583 name = argv[1];
584
585 prop = parse_atom(dpy, name);
586
587 XIDeleteProperty(dpy, info->deviceid, prop);
588
589 return EXIT_SUCCESS;
590 }
591
592 static int
593 do_set_prop_xi2(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc)
594 {
595 XIDeviceInfo *info;
596 Atom prop;
597 Atom old_type;
598 char *name;
599 int i;
600 Atom float_atom;
601 int old_format, nelements = 0;
602 unsigned long act_nitems, bytes_after;
603 char *endptr;
604 union {
605 unsigned char *c;
606 int16_t *s;
607 int32_t *l;
608 } data;
609
610 if (argc < 3)
611 {
612 fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
613 return EXIT_FAILURE;
614 }
615
616 info = xi2_find_device_info(dpy, argv[0]);
617 if (!info)
618 {
619 fprintf(stderr, "unable to find device %s\n", argv[0]);
620 return EXIT_FAILURE;
621 }
622
623 name = argv[1];
624
625 prop = parse_atom(dpy, name);
626
627 if (prop == None) {
628 fprintf(stderr, "invalid property '%s'\n", name);
629 return EXIT_FAILURE;
630 }
631
632 float_atom = XInternAtom(dpy, "FLOAT", False);
633
634 nelements = argc - 2;
635 if (type == None || format == 0) {
636 if (XIGetProperty(dpy, info->deviceid, prop, 0, 0, False,
637 AnyPropertyType, &old_type, &old_format, &act_nitems,
638 &bytes_after, &data.c) != Success) {
639 fprintf(stderr, "failed to get property type and format for '%s'\n",
640 name);
641 return EXIT_FAILURE;
642 } else {
643 if (type == None)
644 type = old_type;
645 if (format == 0)
646 format = old_format;
647 }
648
649 XFree(data.c);
650 }
651
652 if (type == None) {
653 fprintf(stderr, "property '%s' doesn't exist, you need to specify "
654 "its type and format\n", name);
655 return EXIT_FAILURE;
656 }
657
658 data.c = calloc(nelements, sizeof(int32_t));
659
660 for (i = 0; i < nelements; i++)
661 {
662 if (type == XA_INTEGER || type == XA_CARDINAL) {
663 switch (format)
664 {
665 case 8:
666 data.c[i] = atoi(argv[2 + i]);
667 break;
668 case 16:
669 data.s[i] = atoi(argv[2 + i]);
670 break;
671 case 32:
672 data.l[i] = atoi(argv[2 + i]);
673 break;
674 default:
675 fprintf(stderr, "unexpected size for property %s", name);
676 return EXIT_FAILURE;
677 }
678 } else if (type == float_atom) {
679 if (format != 32) {
680 fprintf(stderr, "unexpected format %d for property '%s'\n",
681 format, name);
682 return EXIT_FAILURE;
683 }
684 *(float *)(data.l + i) = strtod(argv[2 + i], &endptr);
685 if (endptr == argv[2 + i]) {
686 fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
687 return EXIT_FAILURE;
688 }
689 } else if (type == XA_ATOM) {
690 if (format != 32) {
691 fprintf(stderr, "unexpected format %d for property '%s'\n",
692 format, name);
693 return EXIT_FAILURE;
694 }
695 data.l[i] = parse_atom(dpy, argv[2 + i]);
696 } else {
697 fprintf(stderr, "unexpected type for property '%s'\n", name);
698 return EXIT_FAILURE;
699 }
700 }
701
702 XIChangeProperty(dpy, info->deviceid, prop, type, format, PropModeReplace,
703 data.c, nelements);
704 free(data.c);
705 return EXIT_SUCCESS;
706 }
707 #endif
708
709 int list_props(Display *display, int argc, char *argv[], char *name,
710 char *desc)
711 {
712 #ifdef HAVE_XI2
713 if (xinput_version(display) == XI_2_Major)
714 return list_props_xi2(display, argc, argv, name, desc);
715 #endif
716 return list_props_xi1(display, argc, argv, name, desc);
717
718 }
719
720 int delete_prop(Display *display, int argc, char *argv[], char *name,
721 char *desc)
722 {
723 #ifdef HAVE_XI2
724 if (xinput_version(display) == XI_2_Major)
725 return delete_prop_xi2(display, argc, argv, name, desc);
726 #endif
727 return delete_prop_xi1(display, argc, argv, name, desc);
728
729 }
730
731 static int
732 do_set_prop(Display *display, Atom type, int format, int argc, char *argv[], char *name, char *desc)
733 {
734 #ifdef HAVE_XI2
735 if (xinput_version(display) == XI_2_Major)
736 return do_set_prop_xi2(display, type, format, argc, argv, name, desc);
737 #endif
738 return do_set_prop_xi1(display, type, format, argc, argv, name, desc);
739 }
740
741 int
742 set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
743 {
744 return do_set_prop(dpy, XA_ATOM, 32, argc, argv, n, desc);
745 }
746
747 int
748 set_int_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
749 {
750 int i;
751 int format;
752
753 if (argc < 3)
754 {
755 fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
756 return EXIT_FAILURE;
757 }
758
759 format = atoi(argv[2]);
760 if (format != 8 && format != 16 && format != 32)
761 {
762 fprintf(stderr, "Invalid format %d\n", format);
763 return EXIT_FAILURE;
764 }
765
766 for (i = 3; i < argc; i++)
767 argv[i - 1] = argv[i];
768
769 return do_set_prop(dpy, XA_INTEGER, format, argc - 1, argv, n, desc);
770 }
771
772 int
773 set_float_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
774 {
775 Atom float_atom = XInternAtom(dpy, "FLOAT", False);
776
777 if (sizeof(float) != 4)
778 {
779 fprintf(stderr, "sane FP required\n");
780 return EXIT_FAILURE;
781 }
782
783 return do_set_prop(dpy, float_atom, 32, argc, argv, n, desc);
784 }
785
786 int set_prop(Display *display, int argc, char *argv[], char *name,
787 char *desc)
788 {
789 Atom type = None;
790 int format = 0;
791 int i = 0, j;
792
793 while (i < argc) {
794 char *option = strchr(argv[i], '=');
795 /* skip non-option arguments */
796 if (strncmp(argv[i], "--", 2) || !option) {
797 i++;
798 continue;
799 }
800
801 if (!strncmp(argv[i], "--type=", strlen("--type="))) {
802 if (!strcmp(option + 1, "int")) {
803 type = XA_INTEGER;
804 } else if (!strcmp(option + 1, "float")) {
805 type = XInternAtom(display, "FLOAT", False);
806 format = 32;
807 } else if (!strcmp(option + 1, "atom")) {
808 type = XA_ATOM;
809 format = 32;
810 } else {
811 fprintf(stderr, "unknown property type %s\n", option + 1);
812 return EXIT_FAILURE;
813 }
814 } else if (!strncmp(argv[i], "--format=", strlen("--format="))) {
815 format = atoi(option + 1);
816 if (format != 8 && format != 16 && format != 32) {
817 fprintf(stderr, "invalid property format '%s'\n", option + 1);
818 return EXIT_FAILURE;
819 }
820 } else {
821 fprintf(stderr, "invalid option '%s'\n", argv[i]);
822 return EXIT_FAILURE;
823 }
824
825 for (j = i; j + 1 < argc; j++)
826 argv[j] = argv[j + 1];
827 argc--;
828 }
829
830 return do_set_prop(display, type, format, argc, argv, name, desc);
831 }
832
833 int disable(Display *display, int argc, char *argv[], char *name, char *desc)
834 {
835 char *new_argv[3] = { NULL, "Device Enabled", "0" };
836
837 if (argc != 1) {
838 fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
839 return EXIT_FAILURE;
840 }
841
842 new_argv[0] = argv[0];
843
844 return set_prop(display, 3, new_argv, name, desc);
845 }
846
847 int enable(Display *display, int argc, char *argv[], char *name, char *desc)
848 {
849 char *new_argv[3] = { NULL, "Device Enabled", "1" };
850
851 if (argc != 1) {
852 fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
853 return EXIT_FAILURE;
854 }
855
856 new_argv[0] = argv[0];
857
858 return set_prop(display, 3, new_argv, name, desc);
859 }