Commit 8d23ab78 authored by Robert Beckett's avatar Robert Beckett
Browse files

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's avatarRobert Beckett <>
parent 68d49d77
......@@ -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
......@@ -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)
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-> = id;
b->drm.filename = strdup(filename);
b->drm.devnum = devnum;
......@@ -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;
......@@ -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)
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_UINT32, &minor,
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)
static DBusHandlerResult
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment