summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Beckett <bob.beckett@collabora.com>2019-06-13 16:55:44 +0100
committerRobert Beckett <bob.beckett@collabora.com>2019-06-13 18:40:56 +0100
commit8d23ab78bdbca420c63125648a483a65851970b1 (patch)
tree7f579c200f9dfad3e639c370430f26e8e462b5cf
parent68d49d772cfba6c53033cb009b0f490fd38f24ad (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.h13
-rw-r--r--libweston/backend-drm/drm.c28
-rw-r--r--libweston/launcher-logind.c17
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