mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	backend/drm: extract connect_drm_connector() logic
We already have disconnect_drm_connector() to handle the CONNECTED → DISCONNECTED transition. Let's add connect_drm_connector() to handle DISCONNECTED → CONNECTED. This makes scan_drm_connectors() shorter and easier to follow. No functional change, literally just moving code around.
This commit is contained in:
		
							parent
							
								
									c07424411a
								
							
						
					
					
						commit
						eeb7a81138
					
				
					 1 changed files with 138 additions and 131 deletions
				
			
		| 
						 | 
				
			
			@ -1157,110 +1157,10 @@ static struct wlr_drm_crtc *connector_get_current_crtc(
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void disconnect_drm_connector(struct wlr_drm_connector *conn);
 | 
			
		||||
static void connect_drm_connector(struct wlr_drm_connector *wlr_conn,
 | 
			
		||||
		const drmModeConnector *drm_conn) {
 | 
			
		||||
	struct wlr_drm_backend *drm = wlr_conn->backend;
 | 
			
		||||
 | 
			
		||||
void scan_drm_connectors(struct wlr_drm_backend *drm,
 | 
			
		||||
		struct wlr_device_hotplug_event *event) {
 | 
			
		||||
	if (event != NULL && event->connector_id != 0) {
 | 
			
		||||
		wlr_log(WLR_INFO, "Scanning DRM connector %"PRIu32" on %s",
 | 
			
		||||
			event->connector_id, drm->name);
 | 
			
		||||
	} else {
 | 
			
		||||
		wlr_log(WLR_INFO, "Scanning DRM connectors on %s", drm->name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drmModeRes *res = drmModeGetResources(drm->fd);
 | 
			
		||||
	if (!res) {
 | 
			
		||||
		wlr_log_errno(WLR_ERROR, "Failed to get DRM resources");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t seen_len = wl_list_length(&drm->outputs);
 | 
			
		||||
	// +1 so length can never be 0, which is undefined behaviour.
 | 
			
		||||
	// Last element isn't used.
 | 
			
		||||
	bool seen[seen_len + 1];
 | 
			
		||||
	memset(seen, false, sizeof(seen));
 | 
			
		||||
	size_t new_outputs_len = 0;
 | 
			
		||||
	struct wlr_drm_connector *new_outputs[res->count_connectors + 1];
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < res->count_connectors; ++i) {
 | 
			
		||||
		uint32_t conn_id = res->connectors[i];
 | 
			
		||||
 | 
			
		||||
		ssize_t index = -1;
 | 
			
		||||
		struct wlr_drm_connector *c, *wlr_conn = NULL;
 | 
			
		||||
		wl_list_for_each(c, &drm->outputs, link) {
 | 
			
		||||
			index++;
 | 
			
		||||
			if (c->id == conn_id) {
 | 
			
		||||
				wlr_conn = c;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the hotplug event contains a connector ID, ignore any other
 | 
			
		||||
		// connector.
 | 
			
		||||
		if (event != NULL && event->connector_id != 0 &&
 | 
			
		||||
				event->connector_id != conn_id) {
 | 
			
		||||
			if (wlr_conn != NULL) {
 | 
			
		||||
				seen[index] = true;
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		drmModeConnector *drm_conn = drmModeGetConnector(drm->fd, conn_id);
 | 
			
		||||
		if (!drm_conn) {
 | 
			
		||||
			wlr_log_errno(WLR_ERROR, "Failed to get DRM connector");
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!wlr_conn) {
 | 
			
		||||
			wlr_conn = calloc(1, sizeof(*wlr_conn));
 | 
			
		||||
			if (!wlr_conn) {
 | 
			
		||||
				wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
			
		||||
				drmModeFreeConnector(drm_conn);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			wlr_conn->backend = drm;
 | 
			
		||||
			wlr_conn->status = DRM_MODE_DISCONNECTED;
 | 
			
		||||
			wlr_conn->id = drm_conn->connector_id;
 | 
			
		||||
 | 
			
		||||
			const char *conn_name =
 | 
			
		||||
				drmModeGetConnectorTypeName(drm_conn->connector_type);
 | 
			
		||||
			if (conn_name == NULL) {
 | 
			
		||||
				conn_name = "Unknown";
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			snprintf(wlr_conn->name, sizeof(wlr_conn->name),
 | 
			
		||||
				"%s-%"PRIu32, conn_name, drm_conn->connector_type_id);
 | 
			
		||||
 | 
			
		||||
			wl_list_insert(drm->outputs.prev, &wlr_conn->link);
 | 
			
		||||
			wlr_log(WLR_INFO, "Found connector '%s'", wlr_conn->name);
 | 
			
		||||
		} else {
 | 
			
		||||
			seen[index] = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		wlr_conn->crtc = connector_get_current_crtc(wlr_conn, drm_conn);
 | 
			
		||||
 | 
			
		||||
		// This can only happen *after* hotplug, since we haven't read the
 | 
			
		||||
		// connector properties yet
 | 
			
		||||
		if (wlr_conn->props.link_status != 0) {
 | 
			
		||||
			uint64_t link_status;
 | 
			
		||||
			if (!get_drm_prop(drm->fd, wlr_conn->id,
 | 
			
		||||
					wlr_conn->props.link_status, &link_status)) {
 | 
			
		||||
				wlr_drm_conn_log(wlr_conn, WLR_ERROR,
 | 
			
		||||
					"Failed to get link status prop");
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (link_status == DRM_MODE_LINK_STATUS_BAD) {
 | 
			
		||||
				// We need to reload our list of modes and force a modeset
 | 
			
		||||
				wlr_drm_conn_log(wlr_conn, WLR_INFO, "Bad link detected");
 | 
			
		||||
				disconnect_drm_connector(wlr_conn);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (wlr_conn->status == DRM_MODE_DISCONNECTED &&
 | 
			
		||||
				drm_conn->connection == DRM_MODE_CONNECTED) {
 | 
			
		||||
			wlr_log(WLR_INFO, "'%s' connected", wlr_conn->name);
 | 
			
		||||
	wlr_log(WLR_DEBUG, "Current CRTC: %d",
 | 
			
		||||
		wlr_conn->crtc ? (int)wlr_conn->crtc->id : -1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1392,6 +1292,113 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
 | 
			
		|||
	wlr_output_update_enabled(&wlr_conn->output, wlr_conn->crtc != NULL);
 | 
			
		||||
 | 
			
		||||
	wlr_conn->status = DRM_MODE_CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void disconnect_drm_connector(struct wlr_drm_connector *conn);
 | 
			
		||||
 | 
			
		||||
void scan_drm_connectors(struct wlr_drm_backend *drm,
 | 
			
		||||
		struct wlr_device_hotplug_event *event) {
 | 
			
		||||
	if (event != NULL && event->connector_id != 0) {
 | 
			
		||||
		wlr_log(WLR_INFO, "Scanning DRM connector %"PRIu32" on %s",
 | 
			
		||||
			event->connector_id, drm->name);
 | 
			
		||||
	} else {
 | 
			
		||||
		wlr_log(WLR_INFO, "Scanning DRM connectors on %s", drm->name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drmModeRes *res = drmModeGetResources(drm->fd);
 | 
			
		||||
	if (!res) {
 | 
			
		||||
		wlr_log_errno(WLR_ERROR, "Failed to get DRM resources");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t seen_len = wl_list_length(&drm->outputs);
 | 
			
		||||
	// +1 so length can never be 0, which is undefined behaviour.
 | 
			
		||||
	// Last element isn't used.
 | 
			
		||||
	bool seen[seen_len + 1];
 | 
			
		||||
	memset(seen, false, sizeof(seen));
 | 
			
		||||
	size_t new_outputs_len = 0;
 | 
			
		||||
	struct wlr_drm_connector *new_outputs[res->count_connectors + 1];
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < res->count_connectors; ++i) {
 | 
			
		||||
		uint32_t conn_id = res->connectors[i];
 | 
			
		||||
 | 
			
		||||
		ssize_t index = -1;
 | 
			
		||||
		struct wlr_drm_connector *c, *wlr_conn = NULL;
 | 
			
		||||
		wl_list_for_each(c, &drm->outputs, link) {
 | 
			
		||||
			index++;
 | 
			
		||||
			if (c->id == conn_id) {
 | 
			
		||||
				wlr_conn = c;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the hotplug event contains a connector ID, ignore any other
 | 
			
		||||
		// connector.
 | 
			
		||||
		if (event != NULL && event->connector_id != 0 &&
 | 
			
		||||
				event->connector_id != conn_id) {
 | 
			
		||||
			if (wlr_conn != NULL) {
 | 
			
		||||
				seen[index] = true;
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		drmModeConnector *drm_conn = drmModeGetConnector(drm->fd, conn_id);
 | 
			
		||||
		if (!drm_conn) {
 | 
			
		||||
			wlr_log_errno(WLR_ERROR, "Failed to get DRM connector");
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!wlr_conn) {
 | 
			
		||||
			wlr_conn = calloc(1, sizeof(*wlr_conn));
 | 
			
		||||
			if (!wlr_conn) {
 | 
			
		||||
				wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
			
		||||
				drmModeFreeConnector(drm_conn);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			wlr_conn->backend = drm;
 | 
			
		||||
			wlr_conn->status = DRM_MODE_DISCONNECTED;
 | 
			
		||||
			wlr_conn->id = drm_conn->connector_id;
 | 
			
		||||
 | 
			
		||||
			const char *conn_name =
 | 
			
		||||
				drmModeGetConnectorTypeName(drm_conn->connector_type);
 | 
			
		||||
			if (conn_name == NULL) {
 | 
			
		||||
				conn_name = "Unknown";
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			snprintf(wlr_conn->name, sizeof(wlr_conn->name),
 | 
			
		||||
				"%s-%"PRIu32, conn_name, drm_conn->connector_type_id);
 | 
			
		||||
 | 
			
		||||
			wl_list_insert(drm->outputs.prev, &wlr_conn->link);
 | 
			
		||||
			wlr_log(WLR_INFO, "Found connector '%s'", wlr_conn->name);
 | 
			
		||||
		} else {
 | 
			
		||||
			seen[index] = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		wlr_conn->crtc = connector_get_current_crtc(wlr_conn, drm_conn);
 | 
			
		||||
 | 
			
		||||
		// This can only happen *after* hotplug, since we haven't read the
 | 
			
		||||
		// connector properties yet
 | 
			
		||||
		if (wlr_conn->props.link_status != 0) {
 | 
			
		||||
			uint64_t link_status;
 | 
			
		||||
			if (!get_drm_prop(drm->fd, wlr_conn->id,
 | 
			
		||||
					wlr_conn->props.link_status, &link_status)) {
 | 
			
		||||
				wlr_drm_conn_log(wlr_conn, WLR_ERROR,
 | 
			
		||||
					"Failed to get link status prop");
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (link_status == DRM_MODE_LINK_STATUS_BAD) {
 | 
			
		||||
				// We need to reload our list of modes and force a modeset
 | 
			
		||||
				wlr_drm_conn_log(wlr_conn, WLR_INFO, "Bad link detected");
 | 
			
		||||
				disconnect_drm_connector(wlr_conn);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (wlr_conn->status == DRM_MODE_DISCONNECTED &&
 | 
			
		||||
				drm_conn->connection == DRM_MODE_CONNECTED) {
 | 
			
		||||
			wlr_log(WLR_INFO, "'%s' connected", wlr_conn->name);
 | 
			
		||||
			connect_drm_connector(wlr_conn, drm_conn);
 | 
			
		||||
			new_outputs[new_outputs_len++] = wlr_conn;
 | 
			
		||||
		} else if (wlr_conn->status == DRM_MODE_CONNECTED &&
 | 
			
		||||
				drm_conn->connection != DRM_MODE_CONNECTED) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue