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>
This commit is contained in:
committed by
Pekka Paalanen
parent
92a06a96e4
commit
4381040dc6
@@ -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 *
|
static struct fbdev_backend *
|
||||||
fbdev_backend_create(struct weston_compositor *compositor,
|
fbdev_backend_create(struct weston_compositor *compositor,
|
||||||
struct weston_fbdev_backend_config *param)
|
struct weston_fbdev_backend_config *param)
|
||||||
@@ -810,6 +881,13 @@ fbdev_backend_create(struct weston_compositor *compositor,
|
|||||||
goto out_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. */
|
/* Set up the TTY. */
|
||||||
backend->session_listener.notify = session_notify;
|
backend->session_listener.notify = session_notify;
|
||||||
wl_signal_add(&compositor->session_signal,
|
wl_signal_add(&compositor->session_signal,
|
||||||
@@ -836,12 +914,15 @@ fbdev_backend_create(struct weston_compositor *compositor,
|
|||||||
if (!fbdev_head_create(backend, param->device))
|
if (!fbdev_head_create(backend, param->device))
|
||||||
goto out_launcher;
|
goto out_launcher;
|
||||||
|
|
||||||
|
free(param->device);
|
||||||
|
|
||||||
udev_input_init(&backend->input, compositor, backend->udev,
|
udev_input_init(&backend->input, compositor, backend->udev,
|
||||||
seat_id, param->configure_device);
|
seat_id, param->configure_device);
|
||||||
|
|
||||||
return backend;
|
return backend;
|
||||||
|
|
||||||
out_launcher:
|
out_launcher:
|
||||||
|
free(param->device);
|
||||||
weston_launcher_destroy(compositor->launcher);
|
weston_launcher_destroy(compositor->launcher);
|
||||||
|
|
||||||
out_udev:
|
out_udev:
|
||||||
@@ -857,10 +938,8 @@ out_compositor:
|
|||||||
static void
|
static void
|
||||||
config_init_to_defaults(struct weston_fbdev_backend_config *config)
|
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->tty = 0; /* default to current tty */
|
||||||
config->device = "/dev/fb0"; /* default frame buffer */
|
config->device = NULL;
|
||||||
config->seat_id = NULL;
|
config->seat_id = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user