aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/dmx/examples/xinput.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/dmx/examples/xinput.c')
-rw-r--r--xorg-server/hw/dmx/examples/xinput.c318
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;
+}