Use libudev for enumerating input devices.

dev
Kristian Høgsberg 16 years ago
parent 94448c0ad7
commit 890bc05763
  1. 2
      configure.ac
  2. 102
      wayland-system-compositor.c

@ -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…
Cancel
Save