diff --git a/backend/drm/backend.c b/backend/drm/backend.c index ca91be15..10f324a0 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -133,12 +133,15 @@ static void handle_dev_change(struct wl_listener *listener, void *data) { return; } - // TODO: add and handle lease uevents switch (change->type) { - case WLR_DEVICE_HOTPLUG:; + case WLR_DEVICE_HOTPLUG: wlr_log(WLR_DEBUG, "Received hotplug event for %s", drm->name); scan_drm_connectors(drm, &change->hotplug); break; + case WLR_DEVICE_LEASE: + wlr_log(WLR_DEBUG, "Received lease event for %s", drm->name); + scan_drm_leases(drm); + break; default: wlr_log(WLR_DEBUG, "Received unknown change event for %s", drm->name); } diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 64db81f5..40506cd4 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -1425,6 +1425,36 @@ void scan_drm_connectors(struct wlr_drm_backend *drm, } } +void scan_drm_leases(struct wlr_drm_backend *drm) { + drmModeLesseeListRes *list = drmModeListLessees(drm->fd); + if (list == NULL) { + wlr_log_errno(WLR_ERROR, "drmModeListLessees failed"); + return; + } + + struct wlr_drm_connector *conn; + wl_list_for_each(conn, &drm->outputs, link) { + if (conn->lease == NULL) { + continue; + } + + bool found = false; + for (size_t i = 0; i < list->count; i++) { + if (list->lessees[i] == conn->lease->lessee_id) { + found = true; + break; + } + } + if (!found) { + wlr_log(WLR_DEBUG, "DRM lease %"PRIu32" has been terminated", + conn->lease->lessee_id); + drm_lease_destroy(conn->lease); + } + } + + drmFree(list); +} + static int mhz_to_nsec(int mhz) { return 1000000000000LL / mhz; } diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index d3640afb..c5d3358f 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -149,6 +149,7 @@ bool init_drm_resources(struct wlr_drm_backend *drm); void finish_drm_resources(struct wlr_drm_backend *drm); void scan_drm_connectors(struct wlr_drm_backend *state, struct wlr_device_hotplug_event *event); +void scan_drm_leases(struct wlr_drm_backend *drm); int handle_drm_event(int fd, uint32_t mask, void *data); void destroy_drm_connector(struct wlr_drm_connector *conn); bool drm_connector_commit_state(struct wlr_drm_connector *conn,