int XInputEventNotifier::getNewDeviceEventType(xcb_generic_event_t* event)
{
	int newDeviceType = DEVICE_NONE;
	if( xinputEventType != -1 && event->response_type == xinputEventType ) {
		xcb_input_device_presence_notify_event_t *xdpne = reinterpret_cast<xcb_input_device_presence_notify_event_t *>(event);
		if( xdpne->devchange == DeviceEnabled ) {
			int ndevices;
			XDeviceInfo *devices = XListInputDevices(display, &ndevices);
			if( devices != NULL ) {
				qCDebug(KCM_KEYBOARD) << "New device id:" << xdpne->device_id;
				for(int i=0; i<ndevices; i++) {
					qCDebug(KCM_KEYBOARD) << "id:" << devices[i].id << "name:" << devices[i].name << "used as:" << devices[i].use;
					if( devices[i].id == xdpne->device_id ) {
						if( devices[i].use == IsXKeyboard || devices[i].use == IsXExtensionKeyboard ) {
							if( isRealKeyboard(devices[i].name) ) {
								newDeviceType = DEVICE_KEYBOARD;
								qCDebug(KCM_KEYBOARD) << "new keyboard device, id:" << devices[i].id << "name:" << devices[i].name << "used as:" << devices[i].use;
								break;
							}
						}
						if( devices[i].use == IsXPointer || devices[i].use == IsXExtensionPointer ) {
							newDeviceType = DEVICE_POINTER;
							qCDebug(KCM_KEYBOARD) << "new pointer device, id:" << devices[i].id << "name:" << devices[i].name << "used as:" << devices[i].use;
							break;
						}
					}
				}
				XFreeDeviceList(devices);
			}
		}
	}
	return newDeviceType;
}
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;
}
Example #3
0
XDeviceInfo*
find_device_info(Display    *display,
			const char       *name,
			bool       only_extended)
{
	XDeviceInfo *devices;
	XDeviceInfo *found = NULL;
	int     loop;
	int     num_devices;
	int     len = strlen(name);
	bool    is_id = true;
	XID     id = (XID)-1;

	for(loop = 0; loop < len; loop++)
    {
	   if (!isdigit(name[loop]))
       {
            is_id = false;
            break;
	   }
	}

	if (is_id)
    {
	   id = atoi(name);
	}

	devices = XListInputDevices(display, &num_devices);

	for(loop = 0; loop < num_devices; loop++)
    {
        osd_printf_verbose("Evaluating device with name: %s\n", devices[loop].name);
        
        // if only extended devices and our device isn't extended, skip
        if (only_extended && devices[loop].use < IsXExtensionDevice)
            continue;

        // Adjust name to remove spaces for accurate comparison
        std::string name_no_space = remove_spaces(devices[loop].name); 
        if ((!is_id && strcmp(name_no_space.c_str(), name) == 0)
            || (is_id && devices[loop].id == id))
        {
            if (found)
            {
                osd_printf_verbose(
                    "Warning: There are multiple devices named \"%s\".\n"
                    "To ensure the correct one is selected, please use "
                    "the device ID instead.\n\n", name);
            }
            else
            {
                found = &devices[loop];
            }
        }
	}

	return found;
}
Example #4
0
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;
}
bool KeyMonitor::registerEvents()
{
    unsigned long screen;
    Window window;

    XDeviceInfo *devices;
    int num_devices;
    int i, j;

    XDevice *device;
    XInputClassInfo *info;

    XEventClass event_class;

    m_display = XOpenDisplay(NULL);

    screen = DefaultScreen(m_display);
    window = RootWindow(m_display, screen);

    devices = XListInputDevices(m_display, &num_devices);

    for(i=0; i<num_devices; i++) {
        device = XOpenDevice(m_display, devices[i].id);
        if (device == NULL) {
            /* That's not critical since "Virtual core..." devices don't
               allow opening. */
            UQ_DEBUG << "Could not open device: " << devices[i].name;
            continue;
        }

        if (devices[i].use == IsXExtensionKeyboard) {
            for (info=device->classes, j=0; j < device->num_classes; j++, info++) {
                if (info->input_class == KeyClass) {
                    DeviceKeyPress(device, key_press_type, event_class);
                    m_eventList.append(event_class);
                    DeviceMappingNotify(device, notify_type, event_class);
                    m_eventList.append(event_class);
                }
            }
        }
    }

    if (m_eventList.size() == 0) {
        UQ_WARNING << "No input devices found.";
        return false;
    }

    if (XSelectExtensionEvent(m_display, window, m_eventList.data(), m_eventList.size())) {
        UQ_WARNING << "Error selecting events.";
        return false;
    }

    return true;
}
Example #7
0
PyMODINIT_FUNC initxinputextdev(void)
{
	display = XOpenDisplay(NULL);

	/* polling this seems to be the only way 
	 * to do a timed wait on X events */
 	x11_fd = ConnectionNumber(display);

	xdevList = (XDeviceInfoPtr) XListInputDevices(display, &devcount);
	if (!xdevList)
		fprintf(stderr,"Failed to get input device list\n");

	(void) Py_InitModule("xinputextdev", XInputExtDevMethods);
}
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
}
Example #9
0
/*
 * When this button is pressed, we need to disable all of the other items on
 * the page until the user clicks the button again.  This starts a timer to
 * check keyboard state and update the settingsPTTKeyLabel to the key
 * combination value.  Setting isDetectingKey to false will cause the timer
 * callback to stop running.
 * The timer callback is ManglerSettings::settingsPTTKeyDetect.
 */
void ManglerSettings::settingsPTTKeyButton_clicked_cb(void) {/*{{{*/
    builder->get_widget("settingsPTTKeyButton", button);
    if (button->get_label() == "Set") {
        isDetectingKey = true;
        button->set_label("Done");
        builder->get_widget("settingsCancelButton", button);
        button->set_sensitive(false);
        builder->get_widget("settingsApplyButton", button);
        button->set_sensitive(false);
        builder->get_widget("settingsOkButton", button);
        button->set_sensitive(false);
        Glib::signal_timeout().connect( sigc::mem_fun(*this, &ManglerSettings::settingsPTTKeyDetect), 100 );
    } else {
        isDetectingKey = false;
        button->set_label("Set");
        builder->get_widget("settingsCancelButton", button);
        button->set_sensitive(true);
        builder->get_widget("settingsApplyButton", button);
        button->set_sensitive(true);
        builder->get_widget("settingsOkButton", button);
        button->set_sensitive(true);
        builder->get_widget("settingsPTTKeyValueLabel", label);
        // if the text is as follows, the user pressed done without any keys
        // pressed down and reset it to the default text
        if (label->get_label() == PTT_KEY_SET) {
            label->set_markup(PTT_KEY_GET);
        }
    }
}/*}}}*/
void ManglerSettings::settingsEnablePTTMouseCheckButton_toggled_cb(void) {/*{{{*/
    builder->get_widget("settingsEnablePTTMouseCheckButton", checkbutton);
    if (checkbutton->get_active()) {
        // box was checked
        builder->get_widget("settingsPTTMouseLabel", label);
        label->set_sensitive(true);
        builder->get_widget("settingsPTTMouseValueLabel", label);
        label->set_sensitive(true);
        builder->get_widget("settingsPTTMouseButton", button);
        button->set_sensitive(true);
        builder->get_widget("settingsMouseDeviceLabel", label);
        label->set_sensitive(true);
        builder->get_widget("settingsMouseDeviceComboBox", combobox);
        combobox->set_sensitive(true);
    } else {
        // box was unchecked
        builder->get_widget("settingsPTTMouseLabel", label);
        label->set_sensitive(false);
        builder->get_widget("settingsPTTMouseValueLabel", label);
        label->set_sensitive(false);
        builder->get_widget("settingsPTTMouseButton", button);
        button->set_sensitive(false);
        builder->get_widget("settingsMouseDeviceLabel", label);
        label->set_sensitive(false);
        builder->get_widget("settingsMouseDeviceComboBox", combobox);
        combobox->set_sensitive(false);
    }
}/*}}}*/
void ManglerSettings::settingsPTTMouseButton_clicked_cb(void) {/*{{{*/
    isDetectingMouse = true;
    builder->get_widget("settingsPTTMouseValueLabel", label);
    label->set_markup(PTT_MOUSE_SET);
    builder->get_widget("settingsPTTMouseButton", button);
    button->set_sensitive(false);
    builder->get_widget("settingsCancelButton", button);
    button->set_sensitive(false);
    builder->get_widget("settingsApplyButton", button);
    button->set_sensitive(false);
    builder->get_widget("settingsOkButton", button);
    button->set_sensitive(false);
    builder->get_widget("settingsMouseDeviceComboBox", combobox);
    combobox->set_sensitive(false);
    Glib::signal_timeout().connect( sigc::mem_fun(*this, &ManglerSettings::settingsPTTMouseDetect), 100 );
}/*}}}*/
std::map<uint32_t, Glib::ustring> ManglerSettings::getInputDeviceList(void) {/*{{{*/
    GdkWindow   *rootwin = gdk_get_default_root_window();
    XDeviceInfo *xdev;
    int ndevices_return;
    std::map<uint32_t, Glib::ustring> devicelist;

    xdev = XListInputDevices(GDK_WINDOW_XDISPLAY(rootwin), &ndevices_return);
    for (int ctr = 0; ctr < ndevices_return; ctr++) {
        if (xdev[ctr].use == IsXExtensionPointer) {
            devicelist[xdev[ctr].id] = xdev[ctr].name;
        }
    }
    XFreeDeviceList(xdev);
    return(devicelist);
}/*}}}*/
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);
}
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;
}
Example #12
0
XDeviceInfo*
find_device_info(Display	*display,
		 char		*name,
		 Bool		only_extended)
{
  XDeviceInfo	*devices;
  XDeviceInfo *found = NULL;
  int		loop;
  int		num_devices;
  int		len = strlen(name);
  Bool	is_id = True;
  XID		id = (XID)-1;

  for(loop=0; loop<len; loop++) {
    if (!isdigit(name[loop])) {
      is_id = False;
      break;
    }
  }

  if (is_id) {
    id = atoi(name);
  }

  devices = XListInputDevices(display, &num_devices);

  for(loop=0; loop<num_devices; loop++) {
    if ((!only_extended || (devices[loop].use >= IsXExtensionDevice)) &&
	((!is_id && strcmp(devices[loop].name, name) == 0) ||
	 (is_id && devices[loop].id == id))) {
      if (found) {
	fprintf(stderr,
		"Warning: There are multiple devices named '%s'.\n"
		"To ensure the correct one is selected, please use "
		"the device ID instead.\n\n", name);
	return NULL;
      } else {
	found = &devices[loop];
      }
    }
  }
  return found;
}
Example #13
0
XDeviceInfo*
XInputDriver::find_device_info(Display *display,
                               const char* name,
                               Bool only_extended)
{
  // FIXME: Not really needed could simply pass XDeviceInfo to the
  // constructor, might however make a nicer interface
  XDeviceInfo* x_devices;
  int  num_devices;
  int  len = strlen(name);
  Bool is_id = True;
  XID  id = 0;

  for(int i = 0; i < len; ++i) 
  {
    if (!isdigit(name[i])) 
    {
      is_id = False;
      break;
    }
  }

  if (is_id) {
    id = atoi(name);
  }

  x_devices = XListInputDevices(display, &num_devices);

  for(int i = 0; i < num_devices; ++i) 
  {
    if ((!only_extended || (x_devices[i].use == IsXExtensionDevice)) &&
        ((!is_id && strcmp(x_devices[i].name, name) == 0) ||
         (is_id && x_devices[i].id == id))) {
      return &x_devices[i];
    }
  }
  return NULL;
}
Example #14
0
void
XInputDriver::setup_xinput()
{
  if (!xinput_is_present())
  {
    std::cout << "debug: XInput extentsion not found" << std::endl;
  }
  else
  {
    int num_devices;
    XDeviceInfo* info = XListInputDevices(sys.info.x11.display, &num_devices);
    for(int i = 0; i < num_devices; ++i) 
    {
      pout(PINGUS_DEBUG_INPUT) << "XInputDriver: Device name='" << info[i].name << "'" << std::endl;
      // FIXME: Xinput isn't necesarrily a mouse, could be anything
      //if (info[i].use == IsXExtensionDevice)
      // {
      devices.push_back(new XInputDevice(this, &info[i]));
      // } 
    }
    XFreeDeviceList(info);
  }
}
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;
}
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 #17
0
int
main(int argc, char * argv[])
{
  int           loop, num_extensions, num_devices;
  char          **extensions;
  XDeviceInfo   *devices;
  Display       *dpy;
  Window        root_win;
  unsigned long screen;
  int		list = 0;
  
  if (argc != 3) {
    fprintf(stderr, "usage : %s <device name> (ABSOLUTE|RELATIVE)\n", argv[0]);
    exit(1);
  }

  if (strcmp(argv[1], "-l") == 0) {
    list = 1;
  }
  
  dpy = XOpenDisplay(NULL);

  if (!dpy) {
    printf("unable to connect to X Server try to set the DISPLAY variable\n");
    exit(1);
  }

#ifdef DEBUG
  printf("connected to %s\n", XDisplayString(dpy));
#endif

  screen = DefaultScreen(dpy);
  root_win = RootWindow(dpy, screen);

  extensions = XListExtensions(dpy, &num_extensions);
  for (loop = 0; loop < num_extensions &&
         (strcmp(extensions[loop], "XInputExtension") != 0); loop++);
  XFreeExtensionList(extensions);
  if (loop != num_extensions)
    {
      devices = XListInputDevices(dpy, &num_devices);
      for(loop=0; loop<num_devices; loop++)
        {
          if (devices[loop].name &&
              (StrCaseCmp(devices[loop].name, argv[1]) == 0))
            if (devices[loop].use == IsXExtensionDevice)
              {
                XDevice *device;
              
#ifdef DEBUG
                fprintf(stderr, "opening device %s\n",
                        devices[loop].name ? devices[loop].name : "<noname>");
#endif
                device = XOpenDevice(dpy, devices[loop].id);
                if (device)
                  {
		    XSetDeviceMode(dpy, device, (strcmp("ABSOLUTE", argv[2]) == 0) ? Absolute
				   : Relative);
                    exit(0);
                  }
                else
                  {
                    fprintf(stderr, "error opening device\n");
                    exit(1);
                  }
              }
        }
      XFreeDeviceList(devices);
    }
  else
    {
      fprintf(stderr, "No XInput extension available\n");
      exit(1);
    }
  
  if (list) {
    exit(0);
  }
  else {
    fprintf(stderr, "Extended device %s not found\n", argv[1]);
    exit(1);
  }
}
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")) {
Example #19
0
XDeviceInfo*
find_device_info(char *name)
{
	XDeviceInfo    *devices;
	XDeviceInfo    *found = NULL;
	int		i, max_id;
	int		num_devices, num_found;
	Bool		is_id = True;
	XID		id = (XID)-1;
	const char	       *errstr;

	devices = XListInputDevices(display, &num_devices);
	max_id = 0;
	for (i = 0; i < num_devices; i++)
		if (devices[i].id > max_id)
			max_id = devices[i].id;


	if (name != NULL) {
		for(i = 0; i < strlen(name); i++) {
			if (!isdigit(name[i])) {
				is_id = False;
				break;
			}
		}
		if (is_id) {
			id = strtonum(name, 0, max_id, &errstr);
			if (errstr != NULL) {
				fprintf(stderr, "Invalid device id %s: %s\n",
				    name, errstr);
				exit(1);
			}
		}
	}

	num_found = 0;
	for(i = 0; i < num_devices; i++) {
		if (devices[i].use != IsXExtensionPointer)
			continue;
		if (name == NULL) {
			if (check_device(&devices[i])) {
				found = &devices[i];
				num_found++;
			}
			continue;
		}
		if ((!is_id && strcmp(devices[i].name, name) == 0) ||
		    (is_id && devices[i].id == id)) {
			found = &devices[i];
			num_found++;
		}
	}
	if (num_found > 1) {
		fprintf(stderr,
		    "Error: found multiple matching devices.\n"
		    "To ensure the correct one is selected, please use "
		    "the device ID instead.\n");
		return NULL;
	}
	return found;
}
Example #20
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;
}
Example #21
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;
    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;
}
Example #22
0
static PyObject * xextdev_grab(PyObject *self, PyObject *args)
{
	XEventClass cls;
	const char *devname;
	int devid;
	XAnyClassPtr pClass;
	int j;
	XEventClass eventList[32];
	int nEventListCnt = 0;

	if (!display) {
		ASSERTCOND(display = XOpenDisplay(NULL),"open display");

		/* polling this seems to be the only way 
		* 	 * to do a timed wait on X events */
		x11_fd = ConnectionNumber(display);

		xdevList = (XDeviceInfoPtr) XListInputDevices(display, &devcount);
		if (!xdevList) {
			fprintf(stderr,"Failed to get input device list\n");
			return Py_BuildValue("i", 0);
		}
	}

	if (!PyArg_ParseTuple(args, "i", &devid))
		return Py_BuildValue("i", 0);

	ASSERTCOND(devid<devcount,
		   "Tried to grab non-existing device id %d (max %d)",
		   devid,devcount);

	xdevInfo = xdevList + devid;
	devname = xdevInfo->name;

	val = NULL;

	pClass = xdevInfo->inputclassinfo;
	for (j=0; j<xdevInfo->num_classes; ++j)
	{
		switch (pClass->class) {
		case ValuatorClass:
			val = (XValuatorInfoPtr)pClass;
			break;
		}
		pClass = (XAnyClassPtr)((char*)pClass + pClass->length);
	}

	ASSERTCOND(val,"xinputextdev: Unable to get valuator "
		   "information of '%s'\n",devname);

	/* open device */
	ASSERTCOND(xdev = XOpenDevice(display,xdevInfo->id),
		   "xinputextdev: Unable to open "
		   "input device '%s'\n",devname);

	/* button events */
	DeviceButtonPress(xdev,inputEventTypes[INPUTEVENT_BTN_PRESS],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	DeviceButtonRelease(xdev,inputEventTypes[INPUTEVENT_BTN_RELEASE],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* motion events */
	DeviceMotionNotify(xdev,inputEventTypes[INPUTEVENT_MOTION_NOTIFY],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* proximity events */
	ProximityOut(xdev,inputEventTypes[INPUTEVENT_PROXIMITY_OUT],cls);
	if (cls) eventList[nEventListCnt++] = cls;
	ProximityIn(xdev,inputEventTypes[INPUTEVENT_PROXIMITY_IN],cls);
	if (cls) eventList[nEventListCnt++] = cls;

	/* grab device */
	int err = XGrabDevice(display,xdev,DefaultRootWindow(display),
			      0,nEventListCnt,eventList,
			      GrabModeAsync,GrabModeAsync,CurrentTime);

	if (err == AlreadyGrabbed)
		fprintf(stderr,"xinputextdev: Grab error: AlreadyGrabbed\n");
	else if (err == GrabNotViewable)
		fprintf(stderr, "xinputextdev: Grab error: GrabNotViewable\n");
	else if (err == GrabFrozen)
		fprintf(stderr, "xinputextdev: Grab error: GrabFrozen\n");
	else {
		printf("xinputextdev: Device '%s' grabbed.\n",devname);
		return Py_BuildValue("[i,i]",
				     val->axes[0].max_value,
				     val->axes[1].max_value);
	}

	return Py_BuildValue("i", 0);
}
Example #23
0
int
main(int argc, char * argv[])
{
  int           loop, num_extensions, num_devices;
  char          **extensions;
  XDeviceInfo   *devices;
  Display       *dpy;
  Window        root_win;
  unsigned long screen;
  int		list = 0;
  
  if (argc != 2) {
    fprintf(stderr, "usage : %s (-l | <device name>)\n", argv[0]);
    exit(1);
  }

  if (strcmp(argv[1], "-l") == 0) {
    list = 1;
  }
  
  dpy = XOpenDisplay(NULL);

  if (!dpy) {
    printf("unable to connect to X Server try to set the DISPLAY variable\n");
    exit(1);
  }

#ifdef DEBUG
  printf("connected to %s\n", XDisplayString(dpy));
#endif

  screen = DefaultScreen(dpy);
  root_win = RootWindow(dpy, screen);

  extensions = XListExtensions(dpy, &num_extensions);
  for (loop = 0; loop < num_extensions &&
         (strcmp(extensions[loop], "XInputExtension") != 0); loop++);
  XFreeExtensionList(extensions);
  if (loop != num_extensions)
    {
      devices = XListInputDevices(dpy, &num_devices);
      for(loop=0; loop<num_devices; loop++)
        {
	  if (list) {
	      printf("\"%s\"	[", devices[loop].name ? devices[loop].name : "<noname>");
	      switch(devices[loop].use) {
	      case IsXPointer:
		  printf("XPointer]\n");
		  break;
	      case IsXKeyboard:
		  printf("XKeyboard]\n");
		  break;
	      case IsXExtensionDevice:
		  printf("XExtensionDevice]\n");
		  break;
	      default:
		  printf("invalid value]\n");
		  break;
	      }
	  }
	  else {
          if ((argc == 2) && devices[loop].name &&
              (StrCaseCmp(devices[loop].name, argv[1]) == 0))
            if (devices[loop].use == IsXExtensionDevice)
              {
                XDevice *device;
              
#ifdef DEBUG
                fprintf(stderr, "opening device %s\n",
                        devices[loop].name ? devices[loop].name : "<noname>");
#endif
                device = XOpenDevice(dpy, devices[loop].id);
                if (device)
                  {
                    XChangePointerDevice(dpy, device, 0, 1);
                    exit(0);
                  }
                else
                  {
                    fprintf(stderr, "error opening device\n");
                    exit(1);
                  }
              }
	  }
        }
      XFreeDeviceList(devices);
    }
  else
    {
      fprintf(stderr, "No XInput extension available\n");
      exit(1);
    }
  
  if (list) {
    exit(0);
  }
  else {
    fprintf(stderr, "Extended device %s not found\n", argv[1]);
    exit(1);
  }
}
Example #24
0
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;
}
Example #25
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);
}
Example #26
0
int
snoop_xinput(Window win)
{
	int opcode, event, error, numdevs, i, j;
	int major, minor, rc, rawmotion = 0;
	int ev = 0;
	unsigned char mask[(XI_LASTEVENT + 7)/8];
	XDeviceInfo *devinfo;
	XInputClassInfo *ici;
	XDevice *device;
	XIEventMask evmasks[1];

	if (!XQueryExtension(dpy, "XInputExtension", &opcode, &event, &error)) {
		if (debug)
			warn("XInput extension not available");

		return (0);
	}

	/*
	 * If we support xinput 2, use that for raw motion and button events to
	 * get pointer data when the cursor is over a Chromium window.  We
	 * could also use this to get raw key input and avoid the other XInput
	 * stuff, but we may need to be able to examine the key value later to
	 * filter out ignored keys.
	 */
	major = minor = 2;
	rc = XIQueryVersion(dpy, &major, &minor);
	if (rc != BadRequest) {
		memset(mask, 0, sizeof(mask));

		XISetMask(mask, XI_RawMotion);
		XISetMask(mask, XI_RawButtonPress);
		evmasks[0].deviceid = XIAllMasterDevices;
		evmasks[0].mask_len = sizeof(mask);
		evmasks[0].mask = mask;

		XISelectEvents(dpy, win, evmasks, 1);
		XFlush(dpy);

		rawmotion = 1;

		if (debug)
			printf("using xinput2 raw motion events\n");
	}

	devinfo = XListInputDevices(dpy, &numdevs);
	XEventClass event_list[numdevs * 2];
	for (i = 0; i < numdevs; i++) {
		if (devinfo[i].use != IsXExtensionKeyboard &&
		    devinfo[i].use != IsXExtensionPointer)
			continue;

		if (!(device = XOpenDevice(dpy, devinfo[i].id)))
			break;

		for (ici = device->classes, j = 0; j < devinfo[i].num_classes;
		ici++, j++) {
			switch (ici->input_class) {
			case KeyClass:
				if (debug)
					printf("attaching to keyboard device "
					    "%s (use %d)\n", devinfo[i].name,
					    devinfo[i].use);

				DeviceKeyPress(device, key_press_type,
				    event_list[ev]); ev++;
				DeviceKeyRelease(device, key_release_type,
				    event_list[ev]); ev++;
				break;

			case ButtonClass:
				if (rawmotion)
					continue;

				if (debug)
					printf("attaching to buttoned device "
					    "%s (use %d)\n", devinfo[i].name,
					    devinfo[i].use);

				DeviceButtonPress(device, button_press_type,
				    event_list[ev]); ev++;
				DeviceButtonRelease(device,
				    button_release_type, event_list[ev]); ev++;
				break;

			case ValuatorClass:
				if (rawmotion)
					continue;

				if (debug)
					printf("attaching to pointing device "
					    "%s (use %d)\n", devinfo[i].name,
					    devinfo[i].use);

				DeviceMotionNotify(device, motion_type,
				    event_list[ev]); ev++;
				break;
			}
		}

		if (XSelectExtensionEvent(dpy, win, event_list, ev)) {
			warn("error selecting extension events");
			return (0);
		}
	}

	return (ev);
}
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;
}
/**
 * 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;
}