diff options
Diffstat (limited to 'xorg-server/hw/dmx/examples/xinput.c')
-rw-r--r-- | xorg-server/hw/dmx/examples/xinput.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/xorg-server/hw/dmx/examples/xinput.c b/xorg-server/hw/dmx/examples/xinput.c new file mode 100644 index 000000000..b6753e4ec --- /dev/null +++ b/xorg-server/hw/dmx/examples/xinput.c @@ -0,0 +1,318 @@ +/* + * Copyright 2001,2002 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Authors: + * Rickard E. (Rik) Faith <faith@redhat.com> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XInput.h> +#include <X11/extensions/XKB.h> +#include "xkbstr.h" +#include <X11/extensions/dmxext.h> +#include <sys/time.h> + +static const char *core(DMXInputAttributes *iinf) +{ + if (iinf->isCore) return "core"; + else if (iinf->sendsCore) return "extension (sends core events)"; + else return "extension"; +} + +static void printdmxinfo(Display *display, int id) +{ + int event_base; + int error_base; + int major_version, minor_version, patch_version; + DMXInputAttributes iinf; + Display *backend; + char *backendname = NULL; + + if (!DMXQueryExtension(display, &event_base, &error_base)) return; + if (!DMXQueryVersion(display, &major_version, &minor_version, + &patch_version)) return; + if (major_version == 1 && minor_version == 0) return; /* too old */ + if (!DMXGetInputAttributes(display, id, &iinf)) return; + + printf(" DMX Information: "); + if (iinf.detached) printf("detached "); + else printf("active "); + switch (iinf.inputType) { + case DMXLocalInputType: + printf("local, %s", core(&iinf)); + break; + case DMXConsoleInputType: + printf("console %s, %s", iinf.name, core(&iinf)); + break; + case DMXBackendInputType: + if (iinf.physicalId >= 0) { + if ((backend = XOpenDisplay(iinf.name))) { + XExtensionVersion *ext = XGetExtensionVersion(backend, INAME); + if (ext && ext != (XExtensionVersion *)NoSuchExtension) { + int count, i; + XDeviceInfo *devInfo = XListInputDevices(backend, &count); + if (devInfo) { + for (i = 0; i < count; i++) { + if ((unsigned)iinf.physicalId == devInfo[i].id + && devInfo[i].name) { + backendname = strdup(devInfo[i].name); + break; + } + } + XFreeDeviceList(devInfo); + } + } + XCloseDisplay(backend); + } + } + printf("backend o%d/%s",iinf.physicalScreen, iinf.name); + if (iinf.physicalId >= 0) printf("/id%d", iinf.physicalId); + if (backendname) { + printf("=%s", backendname); + free(backendname); + } + printf(" %s", core(&iinf)); + break; + } + printf("\n"); +} + +int main(int argc, char **argv) +{ + Display *display = NULL; + int device = -1; + int newmouse = -1; + int newkbd = -1; + int count; + int i, j; + XDeviceInfo *devInfo; + XExtensionVersion *ext; + + if (argc == 2 || argc == 3 || argc == 4 || argc == 5) { + if (!(display = XOpenDisplay(argv[1]))) { + printf("Cannot open display %s\n", argv[1]); + return -1; + } + if (argc >= 3) device = strtol(argv[2], NULL, 0); + if (argc >= 4) newmouse = strtol(argv[3], NULL, 0); + if (argc >= 5) newkbd = strtol(argv[4], NULL, 0); + } else { + printf("Usage: %s display [device] [newmouse] [newkbd]\n", argv[0]); + return -1; + } + + if (!display && !(display = XOpenDisplay(NULL))) { + printf("Cannot open default display\n"); + return -1; + } + + ext = XGetExtensionVersion(display, INAME); + if (!ext || ext == (XExtensionVersion *)NoSuchExtension) { + printf("No XInputExtension\n"); + return -1; + } + printf("%s version %d.%d\n", + INAME, ext->major_version, ext->minor_version); + + if (!(devInfo = XListInputDevices(display, &count)) || !count) { + printf("Cannot list devices\n"); + return -1; + } + + for (i = 0; i < count; i++) { + XAnyClassPtr any; + const char *kind = "Unknown"; + int has_key = 0; + + switch (devInfo[i].use) { + case IsXPointer: kind = "XPointer"; break; + case IsXKeyboard: kind = "XKeyboard"; break; + case IsXExtensionDevice: kind = "XExtensionDevice"; break; + } + printf("%2lu %-20.20s %-16.16s", + (long unsigned)devInfo[i].id, + devInfo[i].name ? devInfo[i].name : "", kind); + + for (j = 0, any = devInfo[i].inputclassinfo; + j < devInfo[i].num_classes; + any = (XAnyClassPtr)((char *)any + any->length), j++) { + const char *class = "unk"; + switch (any->class) { + case KeyClass: class = "key"; ++has_key; break; + case ButtonClass: class = "btn"; break; + case ValuatorClass: class = "val"; break; + case FeedbackClass: class = "fdb"; break; + case ProximityClass: class = "prx"; break; + case FocusClass: class = "foc"; break; + case OtherClass: class = "oth"; break; + } + printf(" %s", class); + } + printf("\n"); + printdmxinfo(display, i); + + if (has_key) { + XkbDescPtr xkb; + if ((xkb = XkbGetKeyboard(display, + XkbAllComponentsMask, + devInfo[i].id))) { + printf(" Xkb Information:\n"); + printf(" Device id = %d\n", xkb->device_spec); + printf(" Min keycode = 0x%02x\n", xkb->min_key_code); + printf(" Max keycode = 0x%02x\n", xkb->max_key_code); +#define PRINTNAME(x) \ + printf(" %s = %s\n", \ + #x, xkb->names->x ? XGetAtomName(display, xkb->names->x) : "") + PRINTNAME(keycodes); + PRINTNAME(geometry); + PRINTNAME(symbols); + PRINTNAME(types); + PRINTNAME(compat); + } + } + } + + if (newmouse >= 0) { + XDevice *dev; + + printf("Trying to make device %d core mouse\n", newmouse); + dev = XOpenDevice(display, devInfo[newmouse].id); + printf("Status = %d\n", + XChangePointerDevice(display, dev, 0, 1)); + return 0; + } + + if (newkbd >= 0) { + XDevice *dev; + + printf("Trying to make device %d core keyboard\n", newkbd); + dev = XOpenDevice(display, devInfo[newkbd].id); + printf("Status = %d\n", + XChangeKeyboardDevice(display, dev)); + return 0; + } + + + if (device >=0){ +#define MAX_EVENTS 100 + int cnt = 0; + XDevice *dev; + XEventClass event_list[MAX_EVENTS]; + int event_type[MAX_EVENTS]; + const char *names[MAX_EVENTS]; + int total = 0; + +#define ADD(type) \ + if (cnt >= MAX_EVENTS) abort(); \ + names[cnt] = #type; \ + type(dev, event_type[cnt], event_list[cnt]); \ + if (event_type[cnt]) ++cnt + + + dev = XOpenDevice(display, devInfo[device].id); + ADD(DeviceKeyPress); + ADD(DeviceKeyRelease); + ADD(DeviceButtonPress); + ADD(DeviceButtonRelease); + ADD(DeviceMotionNotify); + ADD(DeviceFocusIn); + ADD(DeviceFocusOut); + ADD(ProximityIn); + ADD(ProximityOut); + ADD(DeviceStateNotify); + ADD(DeviceMappingNotify); + ADD(ChangeDeviceNotify); + + for (i = 0; i < cnt; i++) { + printf("Waiting for %s events of type %d (%lu) on 0x%08lx\n", + names[i], + event_type[i], (unsigned long)event_list[i], + (long unsigned)DefaultRootWindow(display)); + } + XSelectExtensionEvent(display, DefaultRootWindow(display), + event_list, cnt); + + for (;;) { + XEvent event; + XNextEvent(display, &event); + for (i = 0; i < cnt; i++) { + XDeviceMotionEvent *e = (XDeviceMotionEvent *)&event; + XDeviceButtonEvent *b = (XDeviceButtonEvent *)&event; + if (event.type == event_type[i]) { + printf("%s id=%lu (%d @ %d,%d; s=0x%04x, d=%d, t=%lu)" + " axes_count=%d first=%d %d %d %d %d %d %d\n", + names[i], + (long unsigned)e->deviceid, + e->type, + e->x, e->y, + e->device_state, + b->button, + (long unsigned)b->time, + e->axes_count, + e->first_axis, + e->axis_data[0], + e->axis_data[1], + e->axis_data[2], + e->axis_data[3], + e->axis_data[4], + e->axis_data[5]); + } + } + ++total; +#if 0 + /* Used to check motion history for + * extension devices. */ + if (!(total % 10)) { + XDeviceTimeCoord *tc; + int n, m, a; + struct timeval tv; + unsigned long ms; + gettimeofday(&tv, NULL); + ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; + tc = XGetDeviceMotionEvents(display, dev, ms-1000, ms, + &n, &m, &a); + printf("Got %d events of mode %s with %d axes\n", + n, m == Absolute ? "Absolute" : "Relative", a); + for (i = 0; i < n && i < 10; i++) { + printf(" %d: %lu %d %d\n", + i, tc[i].time, tc[i].data[0], tc[i].data[1]); + } + XFreeDeviceMotionEvents(tc); + } +#endif + } + } + + XCloseDisplay(display); + return 0; +} |