char* e_version() { static char r[10]; //should be enough... XExtensionVersion *version; Display *display; display = XOpenDisplay(NULL); //printf("XI version on server: "); r[0] = '\0'; if (display == NULL) return("Failed to open display.\n"); else { version = XGetExtensionVersion(display, INAME); if (!version || (version == (XExtensionVersion*) NoSuchExtension)) return("Extension not supported.\n"); else { char major[3]; snprintf(major,3, "%d", version->major_version); char minor[3]; snprintf(minor, 3, "%d", version->minor_version); strncat(r, major, 3); strncat(r, ".", 3); strncat(r, minor, 3); XFree(version); } } return(r); }
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"); }
static gboolean find_synaptics (void) { gboolean ret = FALSE; #ifdef HAVE_XINPUT int numdevices, i; XDeviceInfo *devicelist; Atom realtype, prop; int realformat; unsigned long nitems, bytes_after; unsigned char *data; XExtensionVersion *version; /* Input device properties require version 1.5 or higher */ version = XGetExtensionVersion (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "XInputExtension"); if (!version->present || (version->major_version * 1000 + version->minor_version) < 1005) { XFree (version); return False; } prop = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Off", True); if (!prop) return False; devicelist = XListInputDevices (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &numdevices); for (i = 0; i < numdevices; i++) { if (devicelist[i].use != IsXExtensionPointer) continue; gdk_error_trap_push(); XDevice *device = XOpenDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), devicelist[i].id); if (gdk_error_trap_pop ()) continue; gdk_error_trap_push (); if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, prop, 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &data) == Success) && (realtype != None)) { XFree (data); ret = TRUE; } gdk_error_trap_pop (); XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device); if (ret) break; } XFree (version); XFreeDeviceList (devicelist); #endif return ret; }
/** Init display connection or NULL on error */ static Display* dp_init() { Display *dpy = NULL; XExtensionVersion *v = NULL; Atom touchpad_type = 0; Atom synaptics_property = 0; int error = 0; dpy = XOpenDisplay(NULL); if (!dpy) { fprintf(stderr, "Failed to connect to X Server.\n"); error = 1; goto unwind; } v = XGetExtensionVersion(dpy, INAME); if (!v->present || (v->major_version * 1000 + v->minor_version) < (XI_Add_DeviceProperties_Major * 1000 + XI_Add_DeviceProperties_Minor)) { fprintf(stderr, "X server supports X Input %d.%d. I need %d.%d.\n", v->major_version, v->minor_version, XI_Add_DeviceProperties_Major, XI_Add_DeviceProperties_Minor); error = 1; goto unwind; } /* We know synaptics sets XI_TOUCHPAD for all the devices. */ touchpad_type = XInternAtom(dpy, XI_TOUCHPAD, True); if (!touchpad_type) { fprintf(stderr, "XI_TOUCHPAD not initialised.\n"); error = 1; goto unwind; } synaptics_property = XInternAtom(dpy, SYNAPTICS_PROP_EDGES, True); if (!synaptics_property) { fprintf(stderr, "Couldn't find synaptics properties. No synaptics " "driver loaded?\n"); error = 1; goto unwind; } unwind: XFree(v); if (error && dpy) { XCloseDisplay(dpy); dpy = NULL; } return dpy; }
Bool XInputDriver::xinput_is_present() { XExtensionVersion* version = XGetExtensionVersion(sys.info.x11.display, INAME); if (version && (version != (XExtensionVersion*)NoSuchExtension)) { Bool present = version->present; XFree(version); return present; } else { return False; } }
Bool CL_DisplayWindow_OpenGL::xinput_is_present() { XExtensionVersion *version; Bool present; version = XGetExtensionVersion(disp, INAME); if (version && (version != (XExtensionVersion*) NoSuchExtension)) { present = version->present; XFree(version); return present; } else { return False; } }
GlobalShortcutX::GlobalShortcutX() { bRunning=false; bXInput = false; display = NULL; iKeyPress = iKeyRelease = iButtonPress = iButtonRelease = -1; #ifdef Q_OS_LINUX QString dir = QLatin1String("/dev/input"); QFileSystemWatcher *fsw = new QFileSystemWatcher(QStringList(dir), this); connect(fsw, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &))); directoryChanged(dir); if (qsKeyboards.isEmpty()) { foreach(QFile *f, qmInputDevices) delete f; qmInputDevices.clear(); delete fsw; qWarning("GlobalShortcutX: Unable to open any keyboard input devices under /dev/input, falling back to XInput"); } else { return; } #endif display = XOpenDisplay(NULL); if (! display) { qWarning("GlobalShortcutX: Unable to open dedicated display connection."); return; } XExtensionVersion *version = XGetExtensionVersion(display, INAME); if (version && (version != reinterpret_cast<XExtensionVersion *>(NoSuchExtension))) { qWarning("GlobalShortcutX: Using XInput %d.%d", version->major_version, version->minor_version); bXInput = true; XFree(version); initXInput(); if (qmXDevices.isEmpty()) { qWarning("GlobalShortcutX: No XInput devices"); } else { connect(new QSocketNotifier(ConnectionNumber(display), QSocketNotifier::Read, this), SIGNAL(activated(int)), this, SLOT(displayReadyRead(int))); return; } } else {
static gboolean ccm_display_init_input (CCMDisplay * self) { g_return_val_if_fail (self != NULL, FALSE); XExtensionVersion *version; #ifdef HAVE_XI2 version = XQueryInputVersion (self->priv->xdisplay, XI_2_Major, XI_2_Minor); #else version = XGetExtensionVersion (self->priv->xdisplay, INAME); #endif if (version && (version != (XExtensionVersion *) NoSuchExtension)) { self->priv->input.available = TRUE; XFree (version); return TRUE; } return FALSE; }
int initialize() { std::lock_guard<std::mutex> scope_lock(m_lock); if (m_display != nullptr) return 0; m_display = XOpenDisplay(NULL); if (m_display == nullptr) { osd_printf_verbose("Unable to connect to X server\n"); return -1; } XExtensionVersion *version = XGetExtensionVersion(m_display, INAME); if (!version || (version == (XExtensionVersion*)NoSuchExtension)) { osd_printf_verbose("xinput extension not available!\n"); return -1; } return 0; }
static int probeDevices(void) { static Bool been_here = False; static int support; #if !defined(WIN32) XExtensionVersion *version; XDeviceInfoPtr device_info, device; XAnyClassPtr any; XButtonInfoPtr b; XValuatorInfoPtr v; XAxisInfoPtr a; int num_dev, btns, dials; int i, j, k; #endif /* !WIN32 */ if (been_here) { return support; } been_here = True; #if !defined(WIN32) version = XGetExtensionVersion(__glutDisplay, "XInputExtension"); if (version == NULL || ((int) version) == NoSuchExtension) { support = 0; return support; } XFree(version); device_info = XListInputDevices(__glutDisplay, &num_dev); if (device_info) { for (i = 0; i < num_dev; i++) { /* XXX These are SGI names for these devices; unfortunately, no good standard exists for standard types of X input extension devices. */ device = &device_info[i]; any = (XAnyClassPtr) device->inputclassinfo; if (!__glutSpaceball && !strcmp(device->name, "spaceball")) { v = NULL; b = NULL; for (j = 0; j < device->num_classes; j++) { switch (any->class) { case ButtonClass: b = (XButtonInfoPtr) any; btns = b->num_buttons; break; case ValuatorClass: v = (XValuatorInfoPtr) any; /* Sanity check: at least 6 valuators? */ if (v->num_axes < NUM_SPACEBALL_AXIS) goto skip_device; a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo)); for (k = 0; k < NUM_SPACEBALL_AXIS; k++, a++) { __glutSpaceballRange[k].min = a->min_value; __glutSpaceballRange[k].range = a->max_value - a->min_value; } break; } any = (XAnyClassPtr) ((char *) any + any->length); } if (v) { __glutSpaceball = XOpenDevice(__glutDisplay, device->id); if (__glutSpaceball) { __glutNumSpaceballButtons = btns; addDeviceEventParser(); } } } else if (!__glutDials && !strcmp(device->name, "dial+buttons")) { v = NULL; b = NULL; for (j = 0; j < device->num_classes; j++) { switch (any->class) { case ButtonClass: b = (XButtonInfoPtr) any; btns = b->num_buttons; break; case ValuatorClass: v = (XValuatorInfoPtr) any; /* Sanity check: at least 8 valuators? */ if (v->num_axes < NUM_DIALS_AXIS) goto skip_device; dials = v->num_axes; __glutDialsResolution = (int *) malloc(sizeof(int) * dials); a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo)); for (k = 0; k < dials; k++, a++) { __glutDialsResolution[k] = a->resolution; } break; } any = (XAnyClassPtr) ((char *) any + any->length); } if (v) { __glutDials = XOpenDevice(__glutDisplay, device->id); if (__glutDials) { __glutNumButtonBoxButtons = btns; __glutNumDials = dials; addDeviceEventParser(); } } } else if (!__glutTablet && !strcmp(device->name, "tablet")) {
int main(int argc, char *argv[], char *env[]) { char *display_name = NULL; char *device_name = NULL; char *output_name = NULL; XSetWindowAttributes xswa; int i = 0; double a, a1, a2, b, b1, b2, xerr, yerr; int xi_opcode, event, error; XExtensionVersion *version; XDeviceInfo *info; XDevice *device; long calib_data[4]; unsigned long mask; unsigned char swap; int keep_cursor = 0, ch; /* Crosshair placement */ int cpx[] = { 0, 0, 1, 1, 1 }; int cpy[] = { 0, 1, 0, 0, 1 }; while ((ch = getopt(argc, argv, "cD:d:o:v")) != -1) { switch (ch) { case 'c': keep_cursor++; break; case 'D': display_name = optarg; break; case 'd': device_name = optarg; break; case 'o': output_name = optarg; break; case 'v': verbose = True; break; default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc != 0) usage(); /* connect to X server */ if ((display = XOpenDisplay(display_name)) == NULL) { fprintf(stderr, "%s: cannot connect to X server %s\n", __progname, XDisplayName(display_name)); exit(1); } screen = DefaultScreen(display); root = RootWindow(display, screen); /* get screen size from display structure macro */ xpos = 0; ypos = 0; width = DisplayWidth(display, screen); height = DisplayHeight(display, screen); if (XRRQueryExtension(display, &event, &error)) { int major, minor; if (XRRQueryVersion(display, &major, &minor) != True) { fprintf(stderr, "Error querying XRandR version"); } else { printf("XRandR extension version %d.%d present\n", major, minor); has_xrandr = True; if (major > 1 || (major == 1 && minor >=2)) has_xrandr_1_2 = True; if (major > 1 || (major == 1 && minor >=3)) has_xrandr_1_3 = True; } } if (output_name != NULL) { if (has_xrandr_1_2) { get_xrandr_config(display, root, output_name, &xpos, &ypos, &width, &height); } else { fprintf(stderr, "%s: can not specify an output " "whithout XRandr 1.2 or later", __progname); exit(2); } } if (!XQueryExtension(display, INAME, &xi_opcode, &event, &error)) { fprintf(stderr, "%s: X Input extension not available.\n", __progname); exit(1); } version = XGetExtensionVersion(display, INAME); if (version == NULL || version == (XExtensionVersion *)NoSuchExtension) { fprintf(stderr, "Cannot query X Input version.\n"); exit(1); } XFree(version); prop_calibration = XInternAtom(display, WS_PROP_CALIBRATION, True); if (prop_calibration == None) { fprintf(stderr, "Unable to find the \"%s\" device property.\n" "There are probably no calibrable devices " "on this system.\n", WS_PROP_CALIBRATION); exit(1); } prop_swap = XInternAtom(display, WS_PROP_SWAP_AXES, True); if (prop_swap == None) { fprintf(stderr, "Unable to find the \"%s\" device property\n", WS_PROP_SWAP_AXES); exit(1); } info = find_device_info(device_name); if (info == NULL) { fprintf(stderr, "Unable to find the %s device\n", device_name ? device_name : "default"); exit(1); } /* setup window attributes */ xswa.override_redirect = True; xswa.background_pixel = BlackPixel(display, screen); xswa.event_mask = ExposureMask | KeyPressMask; mask = CWOverrideRedirect | CWBackPixel | CWEventMask; if (!keep_cursor) { xswa.cursor = create_empty_cursor(); mask |= CWCursor; } win = XCreateWindow(display, RootWindow(display, screen), xpos, ypos, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, mask, &xswa); render_init(); XMapWindow(display, win); XGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabServer(display); XClearWindow(display, win); if (verbose) printf("Calibrating %s\n", info->name); device = XOpenDevice(display, info->id); if (!device) { fprintf(stderr, "Unable to open the X input device \"%s\"\n", info->name); return 0; } if (!register_events(info, device, 0)) exit(1); uncalibrate(device); calib: XftDrawRect(draw, &bg, 0, 0, width, height); for (i = 0; i < 5; i++) { draw_graphics(cpx[i], cpy[i], i); XFlush(display); if (!get_events(i)) break; XftDrawRect(draw, &bg, 0, 0, width, height); } if (interrupted) cleanup_exit(device); /* Check if X and Y should be swapped */ if (fabs(x[0] - x[1]) > fabs(y[0] - y[1])) { calib.swapxy = 1; for (i = 0; i < 5; i++) { int t = x[i]; x[i] = y[i]; y[i] = t; } } /* get touch pad resolution to screen resolution ratio */ a1 = (double) (x[4] - x[0]) / (double) (cx[4] - cx[0]); a2 = (double) (x[3] - x[1]) / (double) (cx[3] - cx[1]); /* get the minimum pad position on the X-axis */ b1 = x[0] - a1 * cx[0]; b2 = x[1] - a2 * cx[1]; /* use the average ratio and average minimum position */ a = (a1 + a2) / 2.0; b = (b1 + b2) / 2.0; xerr = a * width / 2 + b - x[2]; if (fabs(xerr) > fabs(a * width * .01)) { fprintf(stderr, "Calibration problem: X axis error (%.2f) too high, try again\n", fabs(xerr)); goto err; } calib.minx = (int) (b + 0.5); calib.maxx = (int) (a * width + b + 0.5); /* get touch pad resolution to screen resolution ratio */ a1 = (double) (y[4] - y[0]) / (double) (cy[4] - cy[0]); a2 = (double) (y[3] - y[1]) / (double) (cy[3] - cy[1]); /* get the minimum pad position on the Y-axis */ b1 = y[0] - a1 * cy[0]; b2 = y[1] - a2 * cy[1]; /* use the average ratio and average minimum position */ a = (a1 + a2) / 2.0; b = (b1 + b2) / 2.0; yerr = a * height / 2 + b - y[2]; if (fabs(yerr) > fabs(a * height * 0.01)) { fprintf(stderr, "Calibration problem: Y axis error (%.2f) too high, try again\n", fabs(yerr)); goto err; } calib.miny = (int) (b + 0.5); calib.maxy = (int) (a * height + b + 0.5); XFlush(display); calib.resx = width; calib.resy = height; /* Send new values to the X server */ calib_data[0] = calib.minx; calib_data[1] = calib.maxx; calib_data[2] = calib.miny; calib_data[3] = calib.maxy; XChangeDeviceProperty(display, device, prop_calibration, XA_INTEGER, 32, PropModeReplace, (unsigned char *)calib_data, 4); swap = calib.swapxy; XChangeDeviceProperty(display, device, prop_swap, XA_INTEGER, 8, PropModeReplace, (unsigned char *)&swap, 1); XCloseDevice(display, device); XCloseDisplay(display); /* And print them for storage in wsconsctl.conf */ printf("mouse.scale=%d,%d,%d,%d,%d,%d,%d\n", calib.minx, calib.maxx, calib.miny, calib.maxy, calib.swapxy, calib.resx, calib.resy); return 0; err: draw_text(error_message, &errorColor); XFlush(display); sleep(2); goto calib; }
/** * find a calibratable touchscreen device (using XInput) * * if pre_device is NULL, the last calibratable device is selected. * retuns number of devices found, * the data of the device is returned in the last 3 function parameters */ int Calibrator::find_device(const char* pre_device, bool list_devices, XID& device_id, const char*& device_name, XYinfo& device_axys) { bool pre_device_is_id = true; bool pre_device_is_sysfs = false; int found = 0; Display* display = XOpenDisplay(NULL); if (display == NULL) { fprintf(stderr, "Unable to connect to X server\n"); exit(1); } int xi_opcode, event, error; if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) { fprintf(stderr, "X Input extension not available.\n"); exit(1); } // verbose, get Xi version if (verbose) { XExtensionVersion *version = XGetExtensionVersion(display, INAME); if (version && (version != (XExtensionVersion*) NoSuchExtension)) { printf("DEBUG: %s version is %i.%i\n", INAME, version->major_version, version->minor_version); XFree(version); } } if (pre_device != NULL) { // check whether the pre_device is an ID (only digits) int len = strlen(pre_device); for (int loop=0; loop<len; loop++) { if (!isdigit(pre_device[loop])) { pre_device_is_id = false; break; } } } std::string pre_device_sysfs; if (pre_device != NULL && !pre_device_is_id) { /* avoid overflow below - 10000 devices should be OK */ if ( strlen(pre_device) < strlen("event") + 4 && strncmp(pre_device, "event", strlen("event")) == 0 ) { // check whether the pre_device is an sysfs-path name char filename[40]; // actually 35, but hey... (void) sprintf(filename, "%s/%s/%s", SYSFS_INPUT, pre_device, SYSFS_DEVNAME); std::ifstream ifile(filename); if (ifile.is_open()) { if (!ifile.eof()) { pre_device_is_sysfs = true; std::getline(ifile, pre_device_sysfs); ifile.close(); } } } } if (verbose) printf("DEBUG: Skipping virtual master devices and devices without axis valuators.\n"); int ndevices; XDeviceInfoPtr list, slist; slist=list=(XDeviceInfoPtr) XListInputDevices (display, &ndevices); for (int i=0; i<ndevices; i++, list++) { if (list->use == IsXKeyboard || list->use == IsXPointer) // virtual master device continue; // if we are looking for a specific device if (pre_device != NULL) { if ((pre_device_is_id && list->id == (XID) atoi(pre_device)) || (!pre_device_is_id && strcmp(list->name, pre_device_is_sysfs ? pre_device_sysfs.c_str() : pre_device ) == 0)) { // OK, fall through } else { // skip, not this device continue; } } XAnyClassPtr any = (XAnyClassPtr) (list->inputclassinfo); for (int j=0; j<list->num_classes; j++) { if (any->c_class == ValuatorClass) { XValuatorInfoPtr V = (XValuatorInfoPtr) any; XAxisInfoPtr ax = (XAxisInfoPtr) V->axes; if (V->mode != Absolute) { if (verbose) printf("DEBUG: Skipping device '%s' id=%i, does not report Absolute events.\n", list->name, (int)list->id); } else if (V->num_axes < 2 || (ax[0].min_value == -1 && ax[0].max_value == -1) || (ax[1].min_value == -1 && ax[1].max_value == -1)) { if (verbose) printf("DEBUG: Skipping device '%s' id=%i, does not have two calibratable axes.\n", list->name, (int)list->id); } else { /* a calibratable device (has 2 axis valuators) */ found++; device_id = list->id; device_name = my_strdup(list->name); device_axys.x.min = ax[0].min_value; device_axys.x.max = ax[0].max_value; device_axys.y.min = ax[1].min_value; device_axys.y.max = ax[1].max_value; if (list_devices) printf("Device \"%s\" id=%i\n", device_name, (int)device_id); } } /* * Increment 'any' to point to the next item in the linked * list. The length is in bytes, so 'any' must be cast to * a character pointer before being incremented. */ any = (XAnyClassPtr) ((char *) any + any->length); } } XFreeDeviceList(slist); XCloseDisplay(display); return found; }
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; }
/** * find a calibratable touchscreen device (using XInput) * * if pre_device is NULL, the last calibratable device is selected. * retuns number of devices found, * the data of the device is returned in the last 3 function parameters */ int Calibrator::find_device(const char* pre_device, bool list_devices, XID& device_id, const char*& device_name, XYinfo& device_axys) { bool pre_device_is_id = true; int found = 0; Display* display = XOpenDisplay(NULL); if (display == NULL) { fprintf(stderr, "Unable to connect to X server\n"); exit(1); } int xi_opcode, event, error; if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) { fprintf(stderr, "X Input extension not available.\n"); exit(1); } // verbose, get Xi version if (verbose) { XExtensionVersion *version = XGetExtensionVersion(display, INAME); if (version && (version != (XExtensionVersion*) NoSuchExtension)) { printf("DEBUG: %s version is %i.%i\n", INAME, version->major_version, version->minor_version); XFree(version); } } if (pre_device != NULL) { // check whether the pre_device is an ID (only digits) int len = strlen(pre_device); for (int loop=0; loop<len; loop++) { if (!isdigit(pre_device[loop])) { pre_device_is_id = false; break; } } } if (verbose) printf("DEBUG: Skipping virtual master devices and devices without axis valuators.\n"); int ndevices; XDeviceInfoPtr list, slist; slist=list=(XDeviceInfoPtr) XListInputDevices (display, &ndevices); for (int i=0; i<ndevices; i++, list++) { if (list->use == IsXKeyboard || list->use == IsXPointer) // virtual master device continue; // if we are looking for a specific device if (pre_device != NULL) { if ((pre_device_is_id && list->id == (XID) atoi(pre_device)) || (!pre_device_is_id && strcmp(list->name, pre_device) == 0)) { // OK, fall through } else { // skip, not this device continue; } } XAnyClassPtr any = (XAnyClassPtr) (list->inputclassinfo); for (int j=0; j<list->num_classes; j++) { if (any->c_class == ValuatorClass) { XValuatorInfoPtr V = (XValuatorInfoPtr) any; XAxisInfoPtr ax = (XAxisInfoPtr) V->axes; unsigned int axis_count = 0; if (V->mode != Absolute) { if (verbose) printf("DEBUG: Skipping device '%s' id=%i, does not report Absolute events.\n", list->name, (int)list->id); } else { for (int k=0; k<V->num_axes; k++) if (! (ax[k].min_value == -1 && ax[k].max_value == -1)) axis_count++; if (axis_count < 2) { if (verbose) printf("DEBUG: Skipping device '%s' id=%i, does not have two calibratable axes (%u).\n", list->name, (int)list->id, axis_count); /* Note that devices with more than eight calibratable axes * can be calibrated explicitly, but will not be * automatically selected for calibration. This heuristic * causes some devices that are not really pointer devices * but sometimes appear to be (e.g. some USB keyboards) to * be skipped. */ } else if (pre_device == NULL && axis_count > 8) { if (verbose) printf("DEBUG: Skipping device '%s' id=%i, has more than eight calibratable axes (%u).\n", list->name, (int)list->id, axis_count); } else { /* a calibratable device */ found++; device_id = list->id; device_name = my_strdup(list->name); device_axys.x.min = ax[0].min_value; device_axys.x.max = ax[0].max_value; device_axys.y.min = ax[1].min_value; device_axys.y.max = ax[1].max_value; if (list_devices) printf("Device \"%s\" id=%i\n", device_name, (int)device_id); } } } /* * Increment 'any' to point to the next item in the linked * list. The length is in bytes, so 'any' must be cast to * a character pointer before being incremented. */ any = (XAnyClassPtr) ((char *) any + any->length); } } XFreeDeviceList(slist); XCloseDisplay(display); return found; }