#include <fnmatch.h>
#include <dirent.h>
+#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
+#include <libudev.h>
+
#include <GL/gl.h>
#include <eagle.h>
uint32_t crtc_id;
uint32_t connector_id;
+ struct udev *udev;
+
/* Repaint state. */
struct wl_event_source *timer_source;
int repaint_needed;
evdev_input_device_create(struct wlsc_input_device *device,
struct wl_display *display, const char *path);
-static void
-create_input_device(struct egl_compositor *ec, const char *glob)
+static struct wlsc_input_device *
+create_input_device(struct egl_compositor *ec)
{
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);
if (device == NULL)
- return;
+ return NULL;
memset(device, 0, sizeof *device);
device->base.interface = &wl_input_device_interface;
pointer_create(ec, device->x, device->y, 64, 64);
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);
+
+ return device;
}
void
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_input_devices = default_input_device;
static const GOptionEntry option_entries[] = {
{ "background", 'b', 0, G_OPTION_ARG_STRING,
&option_background, "Background image" },
- { "input-device", 'i', 0, G_OPTION_ARG_STRING_ARRAY,
- &option_input_devices, "Input device glob" },
{ NULL }
};
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 *
egl_compositor_create(struct wl_display *display)
{
struct egl_compositor *ec;
struct screenshooter *shooter;
uint32_t fb_name;
- int i;
struct wl_event_loop *loop;
ec = malloc(sizeof *ec);
add_visuals(ec);
wl_list_init(&ec->input_device_list);
- for (i = 0; option_input_devices[i]; i++)
- create_input_device(ec, option_input_devices[i]);
+ init_libudev(ec);
wl_list_init(&ec->surface_list);
ec->background = background_create(ec, option_background,