mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	Use libudev for enumerating input devices.
This commit is contained in:
		
							parent
							
								
									94448c0ad7
								
							
						
					
					
						commit
						890bc05763
					
				
					 2 changed files with 70 additions and 34 deletions
				
			
		| 
						 | 
					@ -5,7 +5,7 @@ PKG_PROG_PKG_CONFIG()
 | 
				
			||||||
PKG_CHECK_MODULES(FFI, [libffi])
 | 
					PKG_CHECK_MODULES(FFI, [libffi])
 | 
				
			||||||
PKG_CHECK_MODULES(LIBDRM, [libdrm])
 | 
					PKG_CHECK_MODULES(LIBDRM, [libdrm])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PKG_CHECK_MODULES(EGL_COMPOSITOR, [eagle libpng cairo gdk-pixbuf-2.0])
 | 
					PKG_CHECK_MODULES(EGL_COMPOSITOR, [eagle libpng cairo gdk-pixbuf-2.0 libudev])
 | 
				
			||||||
PKG_CHECK_MODULES(GL_COMPOSITOR, [gl x11])
 | 
					PKG_CHECK_MODULES(GL_COMPOSITOR, [gl x11])
 | 
				
			||||||
PKG_CHECK_MODULES(CLIENT, [eagle cairo glib-2.0])
 | 
					PKG_CHECK_MODULES(CLIENT, [eagle cairo glib-2.0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,9 @@
 | 
				
			||||||
#include <fnmatch.h>
 | 
					#include <fnmatch.h>
 | 
				
			||||||
#include <dirent.h>
 | 
					#include <dirent.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
 | 
				
			||||||
 | 
					#include <libudev.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <GL/gl.h>
 | 
					#include <GL/gl.h>
 | 
				
			||||||
#include <eagle.h>
 | 
					#include <eagle.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,6 +108,8 @@ struct egl_compositor {
 | 
				
			||||||
	uint32_t crtc_id;
 | 
						uint32_t crtc_id;
 | 
				
			||||||
	uint32_t connector_id;
 | 
						uint32_t connector_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct udev *udev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Repaint state. */
 | 
						/* Repaint state. */
 | 
				
			||||||
	struct wl_event_source *timer_source;
 | 
						struct wl_event_source *timer_source;
 | 
				
			||||||
	int repaint_needed;
 | 
						int repaint_needed;
 | 
				
			||||||
| 
						 | 
					@ -687,18 +692,14 @@ struct evdev_input_device *
 | 
				
			||||||
evdev_input_device_create(struct wlsc_input_device *device,
 | 
					evdev_input_device_create(struct wlsc_input_device *device,
 | 
				
			||||||
			  struct wl_display *display, const char *path);
 | 
								  struct wl_display *display, const char *path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static struct wlsc_input_device *
 | 
				
			||||||
create_input_device(struct egl_compositor *ec, const char *glob)
 | 
					create_input_device(struct egl_compositor *ec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wlsc_input_device *device;
 | 
						struct wlsc_input_device *device;
 | 
				
			||||||
	struct dirent *de;
 | 
					 | 
				
			||||||
	char path[PATH_MAX];
 | 
					 | 
				
			||||||
	const char *by_path_dir = "/dev/input/by-path";
 | 
					 | 
				
			||||||
	DIR *dir;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	device = malloc(sizeof *device);
 | 
						device = malloc(sizeof *device);
 | 
				
			||||||
	if (device == NULL)
 | 
						if (device == NULL)
 | 
				
			||||||
		return;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(device, 0, sizeof *device);
 | 
						memset(device, 0, sizeof *device);
 | 
				
			||||||
	device->base.interface = &wl_input_device_interface;
 | 
						device->base.interface = &wl_input_device_interface;
 | 
				
			||||||
| 
						 | 
					@ -711,22 +712,9 @@ create_input_device(struct egl_compositor *ec, const char *glob)
 | 
				
			||||||
		pointer_create(ec, device->x, device->y, 64, 64);
 | 
							pointer_create(ec, device->x, device->y, 64, 64);
 | 
				
			||||||
	device->ec = ec;
 | 
						device->ec = ec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dir = opendir(by_path_dir);
 | 
					 | 
				
			||||||
	if (dir == NULL) {
 | 
					 | 
				
			||||||
		fprintf(stderr, "couldn't read dir %s\n", by_path_dir);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while (de = readdir(dir), de != NULL) {
 | 
					 | 
				
			||||||
		if (fnmatch(glob, de->d_name, 0))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		snprintf(path, sizeof path, "%s/%s", by_path_dir, de->d_name);
 | 
					 | 
				
			||||||
		evdev_input_device_create(device, ec->wl_display, path);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	closedir(dir);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_list_insert(ec->input_device_list.prev, &device->link);
 | 
						wl_list_insert(ec->input_device_list.prev, &device->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return device;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -859,19 +847,11 @@ post_output_geometry(struct wl_client *client, struct wl_object *global)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char gem_device[] = "/dev/dri/card0";
 | 
					static const char gem_device[] = "/dev/dri/card0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *default_input_device[] = {
 | 
					 | 
				
			||||||
	"*event*",
 | 
					 | 
				
			||||||
	NULL
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *option_background = "background.jpg";
 | 
					static const char *option_background = "background.jpg";
 | 
				
			||||||
static const char **option_input_devices = default_input_device;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const GOptionEntry option_entries[] = {
 | 
					static const GOptionEntry option_entries[] = {
 | 
				
			||||||
	{ "background", 'b', 0, G_OPTION_ARG_STRING,
 | 
						{ "background", 'b', 0, G_OPTION_ARG_STRING,
 | 
				
			||||||
	  &option_background, "Background image" },
 | 
						  &option_background, "Background image" },
 | 
				
			||||||
	{ "input-device", 'i', 0, G_OPTION_ARG_STRING_ARRAY, 
 | 
					 | 
				
			||||||
	  &option_input_devices, "Input device glob" },
 | 
					 | 
				
			||||||
	{ NULL }
 | 
						{ NULL }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -969,6 +949,64 @@ static int setup_tty(struct egl_compositor *ec, struct wl_event_loop *loop)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *
 | 
				
			||||||
 | 
					get_udev_property(struct udev_device *device, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					        struct udev_list_entry *entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(device))
 | 
				
			||||||
 | 
							if (strcmp(udev_list_entry_get_name(entry), name) == 0)
 | 
				
			||||||
 | 
								return udev_list_entry_get_value(entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					init_libudev(struct egl_compositor *ec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct udev_enumerate *e;
 | 
				
			||||||
 | 
					        struct udev_list_entry *entry;
 | 
				
			||||||
 | 
						struct udev_device *device;
 | 
				
			||||||
 | 
						const char *path, *seat;
 | 
				
			||||||
 | 
						struct wlsc_input_device *input_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* FIXME: Newer (version 135+) udev has two new features that
 | 
				
			||||||
 | 
						 * make all this much easier: 1) we can enumerate by a
 | 
				
			||||||
 | 
						 * specific property.  This lets us directly iterate through
 | 
				
			||||||
 | 
						 * the devices we care about. 2) We can attach properties to
 | 
				
			||||||
 | 
						 * sysfs nodes without a device file, which lets us configure
 | 
				
			||||||
 | 
						 * which connectors belong to a seat instead of tagging the
 | 
				
			||||||
 | 
						 * overall drm node.  I don't want to update my system udev,
 | 
				
			||||||
 | 
						 * so I'm going to stick with this until the new version is in
 | 
				
			||||||
 | 
						 * rawhide. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ec->udev = udev_new();
 | 
				
			||||||
 | 
						if (ec->udev == NULL) {
 | 
				
			||||||
 | 
							fprintf(stderr, "failed to initialize udev context\n");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						input_device = create_input_device(ec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						e = udev_enumerate_new(ec->udev);
 | 
				
			||||||
 | 
					        udev_enumerate_scan_devices(e);
 | 
				
			||||||
 | 
					        udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
 | 
				
			||||||
 | 
							path = udev_list_entry_get_name(entry);
 | 
				
			||||||
 | 
							device = udev_device_new_from_syspath(ec->udev, path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* FIXME: Should the property namespace be CK for console kit? */
 | 
				
			||||||
 | 
							seat = get_udev_property(device, "WAYLAND_SEAT");
 | 
				
			||||||
 | 
							if (!seat || strcmp(seat, "1") != 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (strcmp(udev_device_get_subsystem(device), "input") == 0) {
 | 
				
			||||||
 | 
								evdev_input_device_create(input_device, ec->wl_display,
 | 
				
			||||||
 | 
											  udev_device_get_devnode(device));
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					        udev_enumerate_unref(e);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct egl_compositor *
 | 
					static struct egl_compositor *
 | 
				
			||||||
egl_compositor_create(struct wl_display *display)
 | 
					egl_compositor_create(struct wl_display *display)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -988,7 +1026,6 @@ egl_compositor_create(struct wl_display *display)
 | 
				
			||||||
	struct egl_compositor *ec;
 | 
						struct egl_compositor *ec;
 | 
				
			||||||
	struct screenshooter *shooter;
 | 
						struct screenshooter *shooter;
 | 
				
			||||||
	uint32_t fb_name;
 | 
						uint32_t fb_name;
 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	struct wl_event_loop *loop;
 | 
						struct wl_event_loop *loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ec = malloc(sizeof *ec);
 | 
						ec = malloc(sizeof *ec);
 | 
				
			||||||
| 
						 | 
					@ -1047,8 +1084,7 @@ egl_compositor_create(struct wl_display *display)
 | 
				
			||||||
	add_visuals(ec);
 | 
						add_visuals(ec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_init(&ec->input_device_list);
 | 
						wl_list_init(&ec->input_device_list);
 | 
				
			||||||
	for (i = 0; option_input_devices[i]; i++)
 | 
						init_libudev(ec);
 | 
				
			||||||
		create_input_device(ec, option_input_devices[i]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_init(&ec->surface_list);
 | 
						wl_list_init(&ec->surface_list);
 | 
				
			||||||
	ec->background = background_create(ec, option_background,
 | 
						ec->background = background_create(ec, option_background,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue