aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/drm/backend.c7
-rw-r--r--backend/drm/drm.c30
-rw-r--r--include/backend/drm/drm.h1
3 files changed, 36 insertions, 2 deletions
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,