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>
This commit is contained in:
Robert Beckett 2019-06-13 16:55:44 +01:00
parent 68d49d772c
commit 8d23ab78bd
3 changed files with 51 additions and 7 deletions

View File

@ -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

View File

@ -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);

View File

@ -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