aboutsummaryrefslogtreecommitdiff
path: root/backend/drm/drm.c
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-12-09 10:05:03 +0100
committeremersion <contact@emersion.fr>2018-12-09 10:12:52 +0100
commitf8056a0350ba3d13bdcc9168740c11b9356f626d (patch)
tree195843dee3f611e915c2fa2d7647727832fbc3c8 /backend/drm/drm.c
parent3699496256cd7a7c381dbc2cd6afe39cda9390dc (diff)
backend/drm: fix disappeared output indices
This commit changes `scan_drm_connectors` to add new outputs to the end of the list. That way, it's easier to understand what's going on with indices. When we need to destroy outputs, we now walk the list in reverse order. This ensures indices remain correct while iterating and removing items from the list. We now also make outputs without a CRTC disappear (those are in WLR_DRM_CONN_NEEDS_MODESET state).
Diffstat (limited to 'backend/drm/drm.c')
-rw-r--r--backend/drm/drm.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 97028dc7..f14e3bb0 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -1050,7 +1050,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
drmModeEncoder *curr_enc = drmModeGetEncoder(drm->fd,
drm_conn->encoder_id);
- int index = -1;
+ ssize_t index = -1;
struct wlr_drm_connector *c, *wlr_conn = NULL;
wl_list_for_each(c, &drm->outputs, link) {
index++;
@@ -1086,7 +1086,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
wlr_conn->old_crtc = drmModeGetCrtc(drm->fd, curr_enc->crtc_id);
}
- wl_list_insert(&drm->outputs, &wlr_conn->link);
+ wl_list_insert(drm->outputs.prev, &wlr_conn->link);
wlr_log(WLR_INFO, "Found connector '%s'", wlr_conn->output.name);
} else {
seen[index] = true;
@@ -1178,7 +1178,8 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET;
new_outputs[new_outputs_len++] = wlr_conn;
- } else if (wlr_conn->state == WLR_DRM_CONN_CONNECTED &&
+ } else if ((wlr_conn->state == WLR_DRM_CONN_CONNECTED ||
+ wlr_conn->state == WLR_DRM_CONN_NEEDS_MODESET) &&
drm_conn->connection != DRM_MODE_CONNECTED) {
wlr_log(WLR_INFO, "'%s' disconnected", wlr_conn->output.name);
@@ -1191,9 +1192,11 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
drmModeFreeResources(res);
+ // Iterate in reverse order because we'll remove items from the list and
+ // still want indices to remain correct.
struct wlr_drm_connector *conn, *tmp_conn;
size_t index = wl_list_length(&drm->outputs);
- wl_list_for_each_safe(conn, tmp_conn, &drm->outputs, link) {
+ wl_list_for_each_reverse_safe(conn, tmp_conn, &drm->outputs, link) {
index--;
if (index >= seen_len || seen[index]) {
continue;