2 * Copyright 2007 Peter Hutterer
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
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
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.
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
32 #include <X11/Xatom.h>
33 #include <X11/extensions/XIproto.h>
37 static Atom
parse_atom(Display
*dpy
, char *name
) {
41 for (i
= 0; name
[i
] != '\0'; i
++) {
42 if (!isdigit(name
[i
])) {
51 return XInternAtom(dpy
, name
, False
);
55 print_property(Display
*dpy
, XDevice
* dev
, Atom property
)
60 unsigned long nitems
, bytes_after
;
61 unsigned char *data
, *ptr
;
62 int j
, done
= False
, size
;
64 name
= XGetAtomName(dpy
, property
);
65 printf("\t%s (%ld):\t", name
, property
);
67 if (XGetDeviceProperty(dpy
, dev
, property
, 0, 1000, False
,
68 AnyPropertyType
, &act_type
, &act_format
,
69 &nitems
, &bytes_after
, &data
) == Success
)
71 Atom float_atom
= XInternAtom(dpy
, "FLOAT", True
);
77 case 8: size
= sizeof(char); break;
78 case 16: size
= sizeof(short); break;
79 case 32: size
= sizeof(long); break;
82 for (j
= 0; j
< nitems
; j
++)
90 printf("%d", *((char*)ptr
));
93 printf("%d", *((short*)ptr
));
96 printf("%ld", *((long*)ptr
));
103 printf("Unknown string format.\n");
107 printf("\"%s\"", ptr
);
108 j
+= strlen((char*)ptr
); /* The loop's j++ jumps over the
110 ptr
+= strlen((char*)ptr
); /* ptr += size below jumps over
114 printf("\"%s\"", XGetAtomName(dpy
, *(Atom
*)ptr
));
117 if (float_atom
!= None
&& act_type
== float_atom
)
119 printf("%f", *((float*)ptr
));
123 printf("\t... of unknown type %s\n",
124 XGetAtomName(dpy
, act_type
));
139 printf("\tFetch failure\n");
143 int list_props(Display
*dpy
, int argc
, char** argv
, char* name
, char *desc
)
153 fprintf(stderr
, "Usage: xinput %s %s\n", name
, desc
);
157 for (i
= 0; i
< argc
; i
++)
159 info
= find_device_info(dpy
, argv
[i
], False
);
162 fprintf(stderr
, "unable to find device %s\n", argv
[i
]);
166 dev
= XOpenDevice(dpy
, info
->id
);
169 fprintf(stderr
, "unable to open device '%s'\n", info
->name
);
173 props
= XListDeviceProperties(dpy
, dev
, &nprops
);
176 printf("Device '%s' does not report any properties.\n", info
->name
);
180 printf("Device '%s':\n", info
->name
);
183 print_property(dpy
, dev
, props
[nprops
]);
187 XCloseDevice(dpy
, dev
);
193 set_int_prop(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
201 int format
, nelements
= 0;
205 fprintf(stderr
, "Usage: xinput %s %s\n", n
, desc
);
209 info
= find_device_info(dpy
, argv
[0], False
);
212 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
216 dev
= XOpenDevice(dpy
, info
->id
);
219 fprintf(stderr
, "unable to open device %s\n", argv
[0]);
225 prop
= parse_atom(dpy
, name
);
227 nelements
= argc
- 3;
228 format
= atoi(argv
[2]);
229 if (format
!= 8 && format
!= 16 && format
!= 32)
231 fprintf(stderr
, "Invalid format %d\n", format
);
235 data
= calloc(nelements
, sizeof(long));
236 for (i
= 0; i
< nelements
; i
++)
241 *(((char*)data
) + i
) = atoi(argv
[3 + i
]);
244 *(((short*)data
) + i
) = atoi(argv
[3 + i
]);
247 *(((long*)data
) + i
) = atoi(argv
[3 + i
]);
252 XChangeDeviceProperty(dpy
, dev
, prop
, XA_INTEGER
, format
, PropModeReplace
,
253 (unsigned char*)data
, nelements
);
256 XCloseDevice(dpy
, dev
);
261 set_float_prop(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
265 Atom prop
, float_atom
;
274 fprintf(stderr
, "Usage: xinput %s %s\n", n
, desc
);
278 info
= find_device_info(dpy
, argv
[0], False
);
281 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
285 dev
= XOpenDevice(dpy
, info
->id
);
288 fprintf(stderr
, "unable to open device %s\n", argv
[0]);
294 prop
= parse_atom(dpy
, name
);
296 nelements
= argc
- 2;
298 float_atom
= XInternAtom(dpy
, "FLOAT", False
);
300 if (float_atom
== (Atom
)0)
302 fprintf(stderr
, "no FLOAT atom present in server\n");
306 if (sizeof(float) != 4)
308 fprintf(stderr
, "sane FP required\n");
312 data
= calloc(nelements
, sizeof(long));
313 for (i
= 0; i
< nelements
; i
++)
315 *((float*)(data
+ i
)) = strtod(argv
[2 + i
], &endptr
);
316 if(endptr
== argv
[2 + i
]){
317 fprintf(stderr
, "argument %s could not be parsed\n", argv
[2 + i
]);
322 XChangeDeviceProperty(dpy
, dev
, prop
, float_atom
, 32, PropModeReplace
,
323 (unsigned char*)data
, nelements
);
326 XCloseDevice(dpy
, dev
);
331 int watch_props(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
336 XDevicePropertyNotifyEvent
*dpev
;
339 XEventClass cls_prop
;
341 if (list_props(dpy
, argc
, argv
, n
, desc
) != EXIT_SUCCESS
)
344 info
= find_device_info(dpy
, argv
[0], False
);
347 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
351 dev
= XOpenDevice(dpy
, info
->id
);
354 fprintf(stderr
, "unable to open device '%s'\n", info
->name
);
358 DevicePropertyNotify(dev
, type_prop
, cls_prop
);
359 XSelectExtensionEvent(dpy
, DefaultRootWindow(dpy
), &cls_prop
, 1);
363 XNextEvent(dpy
, &ev
);
365 dpev
= (XDevicePropertyNotifyEvent
*)&ev
;
366 if (dpev
->type
!= type_prop
)
369 name
= XGetAtomName(dpy
, dpev
->atom
);
370 printf("Property '%s' changed.\n", name
);
371 print_property(dpy
, dev
, dpev
->atom
);
374 XCloseDevice(dpy
, dev
);
377 int delete_prop(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
384 info
= find_device_info(dpy
, argv
[0], False
);
387 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
391 dev
= XOpenDevice(dpy
, info
->id
);
394 fprintf(stderr
, "unable to open device '%s'\n", info
->name
);
400 prop
= parse_atom(dpy
, name
);
402 XDeleteDeviceProperty(dpy
, dev
, prop
);
404 XCloseDevice(dpy
, dev
);
409 set_atom_prop(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
422 fprintf(stderr
, "Usage: xinput %s %s\n", n
, desc
);
426 info
= find_device_info(dpy
, argv
[0], False
);
429 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
433 dev
= XOpenDevice(dpy
, info
->id
);
436 fprintf(stderr
, "unable to open device %s\n", argv
[0]);
442 prop
= parse_atom(dpy
, name
);
444 nelements
= argc
- 2;
445 data
= calloc(nelements
, sizeof(Atom
));
446 for (i
= 0; i
< nelements
; i
++)
450 for(j
= 0; j
< strlen(name
); j
++) {
451 if (!isdigit(name
[j
])) {
458 data
[i
] = XInternAtom(dpy
, name
, False
);
461 data
[i
] = atoi(name
);
462 XFree(XGetAtomName(dpy
, data
[i
]));
466 XChangeDeviceProperty(dpy
, dev
, prop
, XA_ATOM
, 32, PropModeReplace
,
467 (unsigned char*)data
, nelements
);
470 XCloseDevice(dpy
, dev
);
475 set_prop(Display
*dpy
, int argc
, char **argv
, char *n
, char *desc
)
484 int format
, nelements
= 0;
485 unsigned long act_nitems
, bytes_after
;
496 fprintf(stderr
, "Usage: xinput %s %s\n", n
, desc
);
500 info
= find_device_info(dpy
, argv
[0], False
);
503 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
507 dev
= XOpenDevice(dpy
, info
->id
);
510 fprintf(stderr
, "unable to open device %s\n", argv
[0]);
516 prop
= parse_atom(dpy
, name
);
519 fprintf(stderr
, "invalid property %s\n", name
);
523 float_atom
= XInternAtom(dpy
, "FLOAT", False
);
525 nelements
= argc
- 2;
526 if (XGetDeviceProperty(dpy
, dev
, prop
, 0, 0, False
, AnyPropertyType
,
527 &type
, &format
, &act_nitems
, &bytes_after
, &data
.c
)
529 fprintf(stderr
, "failed to get property type and format for %s\n", name
);
536 fprintf(stderr
, "property %s doesn't exist\n", name
);
540 data
.c
= calloc(nelements
, sizeof(long));
542 for (i
= 0; i
< nelements
; i
++)
544 if (type
== XA_INTEGER
) {
548 data
.c
[i
] = atoi(argv
[2 + i
]);
551 data
.s
[i
] = atoi(argv
[2 + i
]);
554 data
.l
[i
] = atoi(argv
[2 + i
]);
557 fprintf(stderr
, "unexpected size for property %s", name
);
560 } else if (type
== float_atom
) {
562 fprintf(stderr
, "unexpected format %d for property %s\n",
566 *(float *)(data
.l
+ i
) = strtod(argv
[2 + i
], &endptr
);
567 if (endptr
== argv
[2 + i
]) {
568 fprintf(stderr
, "argument %s could not be parsed\n", argv
[2 + i
]);
571 } else if (type
== XA_ATOM
) {
573 fprintf(stderr
, "unexpected format %d for property %s\n",
577 data
.a
[i
] = parse_atom(dpy
, argv
[2 + i
]);
579 fprintf(stderr
, "unexpected type for property %s\n", name
);
584 XChangeDeviceProperty(dpy
, dev
, prop
, type
, format
, PropModeReplace
,
587 XCloseDevice(dpy
, dev
);