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:
parent
68d49d772c
commit
8d23ab78bd
|
@ -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)
|
||||
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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue