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>
38 print_property(Display
*dpy
, XDevice
* dev
, Atom property
)
43 unsigned long nitems
, bytes_after
;
44 unsigned char *data
, *ptr
;
47 name
= XGetAtomName(dpy
, property
);
48 printf("\t%s (%ld):\t", name
, property
);
50 if (XGetDeviceProperty(dpy
, dev
, property
, 0, 1000, False
,
51 AnyPropertyType
, &act_type
, &act_format
,
52 &nitems
, &bytes_after
, &data
) == Success
)
54 int float_atom
= XInternAtom(dpy
, "FLOAT", False
);
59 for (j
= 0; j
< nitems
; j
++)
67 printf("%d", *((int8_t*)ptr
));
70 printf("%d", *((int16_t*)ptr
));
73 printf("%d", *((int32_t*)ptr
));
81 printf("\t%s", XGetAtomName(dpy
, *(Atom
*)ptr
));
84 if (float_atom
!= None
&& act_type
== float_atom
)
86 printf("\t%f\n", *((float*)ptr
));
90 printf("\t\t... of unknown type %s\n",
91 XGetAtomName(dpy
, act_type
));
99 if (act_type
== XA_STRING
)
105 printf("\tFetch failure\n");
109 int list_props(Display
*dpy
, int argc
, char** argv
, char* name
, char *desc
)
119 fprintf(stderr
, "Usage: xinput %s %s\n", name
, desc
);
123 for (i
= 0; i
< argc
; i
++)
125 info
= find_device_info(dpy
, argv
[i
], False
);
128 fprintf(stderr
, "unable to find device %s\n", argv
[i
]);
132 dev
= XOpenDevice(dpy
, info
->id
);
135 fprintf(stderr
, "unable to open device '%s'\n", info
->name
);
139 props
= XListDeviceProperties(dpy
, dev
, &nprops
);
142 printf("Device '%s' does not report any properties.\n", info
->name
);
146 printf("Device '%s':\n", info
->name
);
149 print_property(dpy
, dev
, props
[nprops
]);
153 XCloseDevice(dpy
, dev
);
159 set_int_prop(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
168 int format
, nelements
= 0;
172 fprintf(stderr
, "Usage: xinput %s %s\n", n
, desc
);
176 info
= find_device_info(dpy
, argv
[0], False
);
179 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
183 dev
= XOpenDevice(dpy
, info
->id
);
186 fprintf(stderr
, "unable to open device %s\n", argv
[0]);
192 for(i
= 0; i
< strlen(name
); i
++) {
193 if (!isdigit(name
[i
])) {
200 prop
= XInternAtom(dpy
, name
, False
);
204 nelements
= argc
- 3;
205 format
= atoi(argv
[2]);
206 if (format
!= 8 && format
!= 16 && format
!= 32)
208 fprintf(stderr
, "Invalid format %d\n", format
);
212 data
= calloc(nelements
, format
/8);
213 for (i
= 0; i
< nelements
; i
++)
218 *(((int8_t*)data
) + i
) = atoi(argv
[3 + i
]);
221 *(((int16_t*)data
) + i
) = atoi(argv
[3 + i
]);
224 *(((int32_t*)data
) + i
) = atoi(argv
[3 + i
]);
229 XChangeDeviceProperty(dpy
, dev
, prop
, XA_INTEGER
, format
, PropModeReplace
,
230 (unsigned char*)data
, nelements
);
233 XCloseDevice(dpy
, dev
);
238 set_float_prop(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
242 Atom prop
, float_atom
;
252 fprintf(stderr
, "Usage: xinput %s %s\n", n
, desc
);
256 info
= find_device_info(dpy
, argv
[0], False
);
259 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
263 dev
= XOpenDevice(dpy
, info
->id
);
266 fprintf(stderr
, "unable to open device %s\n", argv
[0]);
272 for(i
= 0; i
< strlen(name
); i
++) {
273 if (!isdigit(name
[i
])) {
280 prop
= XInternAtom(dpy
, name
, False
);
284 nelements
= argc
- 2;
286 float_atom
= XInternAtom(dpy
, "FLOAT", False
);
288 if (float_atom
== (Atom
)0)
290 fprintf(stderr
, "no FLOAT atom present in server\n");
294 if (sizeof(float) != 4)
296 fprintf(stderr
, "sane FP required\n");
300 data
= calloc(nelements
, 4);
301 for (i
= 0; i
< nelements
; i
++)
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
]);
310 XChangeDeviceProperty(dpy
, dev
, prop
, float_atom
, 32, PropModeReplace
,
311 (unsigned char*)data
, nelements
);
314 XCloseDevice(dpy
, dev
);
319 int watch_props(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
324 XDevicePropertyNotifyEvent
*dpev
;
327 XEventClass cls_prop
;
329 if (list_props(dpy
, argc
, argv
, n
, desc
) != EXIT_SUCCESS
)
332 info
= find_device_info(dpy
, argv
[0], False
);
335 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
339 dev
= XOpenDevice(dpy
, info
->id
);
342 fprintf(stderr
, "unable to open device '%s'\n", info
->name
);
346 DevicePropertyNotify(dev
, type_prop
, cls_prop
);
347 XSelectExtensionEvent(dpy
, DefaultRootWindow(dpy
), &cls_prop
, 1);
351 XNextEvent(dpy
, &ev
);
353 dpev
= (XDevicePropertyNotifyEvent
*)&ev
;
354 if (dpev
->type
!= type_prop
)
357 name
= XGetAtomName(dpy
, dpev
->atom
);
358 printf("Property '%s' changed.\n", name
);
359 print_property(dpy
, dev
, dpev
->atom
);
362 XCloseDevice(dpy
, dev
);
365 int delete_prop(Display
*dpy
, int argc
, char** argv
, char* n
, char *desc
)
374 info
= find_device_info(dpy
, argv
[0], False
);
377 fprintf(stderr
, "unable to find device %s\n", argv
[0]);
381 dev
= XOpenDevice(dpy
, info
->id
);
384 fprintf(stderr
, "unable to open device '%s'\n", info
->name
);
390 for(i
= 0; i
< strlen(name
); i
++) {
391 if (!isdigit(name
[i
])) {
398 prop
= XInternAtom(dpy
, name
, False
);
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 for(i
= 0; i
< strlen(name
); i
++) {
443 if (!isdigit(name
[i
])) {
450 prop
= XInternAtom(dpy
, name
, False
);
454 nelements
= argc
- 2;
455 data
= calloc(nelements
, sizeof(Atom
));
456 for (i
= 0; i
< nelements
; i
++)
460 for(j
= 0; j
< strlen(name
); j
++) {
461 if (!isdigit(name
[j
])) {
468 data
[i
] = XInternAtom(dpy
, name
, False
);
471 data
[i
] = atoi(name
);
472 XFree(XGetAtomName(dpy
, data
[i
]));
476 XChangeDeviceProperty(dpy
, dev
, prop
, XA_ATOM
, 32, PropModeReplace
,
477 (unsigned char*)data
, nelements
);
480 XCloseDevice(dpy
, dev
);