diff options
author | Robert Beckett <bob.beckett@collabora.com> | 2019-06-13 16:55:44 +0100 |
---|---|---|
committer | Robert Beckett <bob.beckett@collabora.com> | 2019-06-13 18:40:56 +0100 |
commit | 8d23ab78bdbca420c63125648a483a65851970b1 (patch) | |
tree | 7f579c200f9dfad3e639c370430f26e8e462b5cf | |
parent | 68d49d772cfba6c53033cb009b0f490fd38f24ad (diff) |
backend-drm: handle multiple drm nodes with logind
When using logind launcher, we receive a PauseDevice "gone" message
from logind session management for each device we close while looking
for KMS devices.
Make logind notify the backend of the device add/remove so that the
backend can decide what to do, instead of assuming that if it is a
DRM_MAJOR device the session should be (de)activated. The backend can
then react to its specific device.
Fixes #251
Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
-rw-r--r-- | include/libweston/libweston.h | 13 | ||||
-rw-r--r-- | libweston/backend-drm/drm.c | 28 | ||||
-rw-r--r-- | libweston/launcher-logind.c | 17 |
3 files changed, 51 insertions, 7 deletions
diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index ccd662ce..253baeb4 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -1034,6 +1034,19 @@ struct weston_backend { struct weston_output * (*create_output)(struct weston_compositor *compositor, const char *name); + + /** Notify of device addition/removal + * + * @param compositor The compositor. + * @param device The device that has changed. + * @param added Where it was added (or removed) + * + * Called when a device has been added/removed from the session. + * The backend can decide what to do based on whether it is a + * device that it is controlling or not. + */ + void (*device_changed)(struct weston_compositor *compositor, + dev_t device, bool added); }; /** Callback for saving calibration diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index ed9756b5..cde19507 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -310,6 +310,7 @@ struct drm_backend { int id; int fd; char *filename; + dev_t devnum; } drm; struct gbm_device *gbm; struct wl_listener session_listener; @@ -6840,6 +6841,30 @@ session_notify(struct wl_listener *listener, void *data) } } + +/** + * Handle KMS GPU being added/removed + * + * If the device being added/removed is the KMS device, we activate/deactivate + * the compositor session. + * + * @param compositor The compositor instance. + * @param device The device being added/removed. + * @param added Whether the device is being added (or removed) + */ +static void +drm_device_changed(struct weston_compositor *compositor, + dev_t device, bool added) +{ + struct drm_backend *b = to_drm_backend(compositor); + + if (b->drm.fd < 0 || b->drm.devnum != device) + return; + + compositor->session_active = added; + wl_signal_emit(&compositor->session_signal, compositor); +} + /** * Determines whether or not a device is capable of modesetting. If successful, * sets b->drm.fd and b->drm.filename to the opened device. @@ -6849,6 +6874,7 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device) { const char *filename = udev_device_get_devnode(device); const char *sysnum = udev_device_get_sysnum(device); + dev_t devnum = udev_device_get_devnum(device); drmModeRes *res; int id = -1, fd; @@ -6883,6 +6909,7 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device) b->drm.fd = fd; b->drm.id = id; b->drm.filename = strdup(filename); + b->drm.devnum = devnum; drmModeFreeResources(res); @@ -7558,6 +7585,7 @@ drm_backend_create(struct weston_compositor *compositor, b->base.repaint_flush = drm_repaint_flush; b->base.repaint_cancel = drm_repaint_cancel; b->base.create_output = drm_output_create; + b->base.device_changed = drm_device_changed; weston_setup_vt_switch_bindings(compositor); diff --git a/libweston/launcher-logind.c b/libweston/launcher-logind.c index 9893cca1..3b0a10d8 100644 --- a/libweston/launcher-logind.c +++ b/libweston/launcher-logind.c @@ -488,20 +488,21 @@ device_paused(struct launcher_logind *wl, DBusMessage *m) if (!strcmp(type, "pause")) launcher_logind_pause_device_complete(wl, major, minor); - if (wl->sync_drm && major == DRM_MAJOR) - launcher_logind_set_active(wl, false); + if (wl->sync_drm && wl->compositor->backend->device_changed) + wl->compositor->backend->device_changed(wl->compositor, + makedev(major,minor), + false); } static void device_resumed(struct launcher_logind *wl, DBusMessage *m) { bool r; - uint32_t major; + uint32_t major, minor; r = dbus_message_get_args(m, NULL, DBUS_TYPE_UINT32, &major, - /*DBUS_TYPE_UINT32, &minor, - DBUS_TYPE_UNIX_FD, &fd,*/ + DBUS_TYPE_UINT32, &minor, DBUS_TYPE_INVALID); if (!r) { weston_log("logind: cannot parse ResumeDevice dbus signal\n"); @@ -514,8 +515,10 @@ device_resumed(struct launcher_logind *wl, DBusMessage *m) * there is no need for us to handle this event for evdev. For DRM, we * notify the compositor to wake up. */ - if (wl->sync_drm && major == DRM_MAJOR) - launcher_logind_set_active(wl, true); + if (wl->sync_drm && wl->compositor->backend->device_changed) + wl->compositor->backend->device_changed(wl->compositor, + makedev(major,minor), + true); } static DBusHandlerResult |