summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornerdopolis <bluescreen_avenger@verizon.net>2018-06-29 08:17:50 -0400
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2018-07-02 15:29:38 +0300
commit4381040dc644f2f82b4698646672ae2be2ec5688 (patch)
tree86ef68f47934bf7a0b385775254c1ce0d4207075
parent92a06a96e4adff21bcf3b746def202d155ab5377 (diff)
compositor-fbdev: detect the first fb device in the seat
This adds a function to detect the first framebuffer device in the current seat. Instead of hardcoding /dev/fb0, detect the device with udev, favoring the boot_vga device, and falling back to the first framebuffer device in the seat if there is none. This is very similar to what compositor-drm does to find display devices Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
-rw-r--r--libweston/compositor-fbdev.c85
1 files changed, 82 insertions, 3 deletions
diff --git a/libweston/compositor-fbdev.c b/libweston/compositor-fbdev.c
index 74971c35..a71b7bdc 100644
--- a/libweston/compositor-fbdev.c
+++ b/libweston/compositor-fbdev.c
@@ -778,6 +778,77 @@ session_notify(struct wl_listener *listener, void *data)
}
}
+static char *
+find_framebuffer_device(struct fbdev_backend *b, const char *seat)
+{
+ struct udev_enumerate *e;
+ struct udev_list_entry *entry;
+ const char *path, *device_seat, *id;
+ char *fb_device_path = NULL;
+ struct udev_device *device, *fb_device, *pci;
+
+ e = udev_enumerate_new(b->udev);
+ udev_enumerate_add_match_subsystem(e, "graphics");
+ udev_enumerate_add_match_sysname(e, "fb[0-9]*");
+
+ udev_enumerate_scan_devices(e);
+ fb_device = NULL;
+ udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
+ bool is_boot_vga = false;
+
+ path = udev_list_entry_get_name(entry);
+ device = udev_device_new_from_syspath(b->udev, path);
+ if (!device)
+ continue;
+ device_seat = udev_device_get_property_value(device, "ID_SEAT");
+ if (!device_seat)
+ device_seat = default_seat;
+ if (strcmp(device_seat, seat)) {
+ udev_device_unref(device);
+ continue;
+ }
+
+ pci = udev_device_get_parent_with_subsystem_devtype(device,
+ "pci", NULL);
+ if (pci) {
+ id = udev_device_get_sysattr_value(pci, "boot_vga");
+ if (id && !strcmp(id, "1"))
+ is_boot_vga = true;
+ }
+
+ /* If a framebuffer device was found, and this device isn't
+ * the boot-VGA device, don't use it. */
+ if (!is_boot_vga && fb_device) {
+ udev_device_unref(device);
+ continue;
+ }
+
+ /* There can only be one boot_vga device. Try to use it
+ * at all costs. */
+ if (is_boot_vga) {
+ if (fb_device)
+ udev_device_unref(fb_device);
+ fb_device = device;
+ break;
+ }
+
+ /* Per the (!is_boot_vga && fb_device) test above, only
+ * trump existing saved devices with boot-VGA devices, so if
+ * the test ends up here, this must be the first device seen. */
+ assert(!fb_device);
+ fb_device = device;
+ }
+
+ udev_enumerate_unref(e);
+
+ if (fb_device) {
+ fb_device_path = strdup(udev_device_get_devnode(fb_device));
+ udev_device_unref(fb_device);
+ }
+
+ return fb_device_path;
+}
+
static struct fbdev_backend *
fbdev_backend_create(struct weston_compositor *compositor,
struct weston_fbdev_backend_config *param)
@@ -810,6 +881,13 @@ fbdev_backend_create(struct weston_compositor *compositor,
goto out_compositor;
}
+ if (!param->device)
+ param->device = find_framebuffer_device(backend, seat_id);
+ if (!param->device) {
+ weston_log("fatal: no framebuffer devices detected.\n");
+ goto out_udev;
+ }
+
/* Set up the TTY. */
backend->session_listener.notify = session_notify;
wl_signal_add(&compositor->session_signal,
@@ -836,12 +914,15 @@ fbdev_backend_create(struct weston_compositor *compositor,
if (!fbdev_head_create(backend, param->device))
goto out_launcher;
+ free(param->device);
+
udev_input_init(&backend->input, compositor, backend->udev,
seat_id, param->configure_device);
return backend;
out_launcher:
+ free(param->device);
weston_launcher_destroy(compositor->launcher);
out_udev:
@@ -857,10 +938,8 @@ out_compositor:
static void
config_init_to_defaults(struct weston_fbdev_backend_config *config)
{
- /* TODO: Ideally, available frame buffers should be enumerated using
- * udev, rather than passing a device node in as a parameter. */
config->tty = 0; /* default to current tty */
- config->device = "/dev/fb0"; /* default frame buffer */
+ config->device = NULL;
config->seat_id = NULL;
}