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,6 +1157,143 @@ static struct wlr_drm_crtc *connector_get_current_crtc(
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void connect_drm_connector(struct wlr_drm_connector *wlr_conn,
 | 
				
			||||||
 | 
							const drmModeConnector *drm_conn) {
 | 
				
			||||||
 | 
						struct wlr_drm_backend *drm = wlr_conn->backend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_log(WLR_DEBUG, "Current CRTC: %d",
 | 
				
			||||||
 | 
							wlr_conn->crtc ? (int)wlr_conn->crtc->id : -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_output_init(&wlr_conn->output, &drm->backend, &output_impl,
 | 
				
			||||||
 | 
							drm->display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_output_set_name(&wlr_conn->output, wlr_conn->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_conn->output.phys_width = drm_conn->mmWidth;
 | 
				
			||||||
 | 
						wlr_conn->output.phys_height = drm_conn->mmHeight;
 | 
				
			||||||
 | 
						wlr_log(WLR_INFO, "Physical size: %"PRId32"x%"PRId32,
 | 
				
			||||||
 | 
							wlr_conn->output.phys_width, wlr_conn->output.phys_height);
 | 
				
			||||||
 | 
						wlr_conn->output.subpixel = subpixel_map[drm_conn->subpixel];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get_drm_connector_props(drm->fd, wlr_conn->id, &wlr_conn->props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t non_desktop;
 | 
				
			||||||
 | 
						if (get_drm_prop(drm->fd, wlr_conn->id,
 | 
				
			||||||
 | 
									wlr_conn->props.non_desktop, &non_desktop)) {
 | 
				
			||||||
 | 
							if (non_desktop == 1) {
 | 
				
			||||||
 | 
								wlr_log(WLR_INFO, "Non-desktop connector");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wlr_conn->output.non_desktop = non_desktop;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_conn->max_bpc = 0;
 | 
				
			||||||
 | 
						if (wlr_conn->props.max_bpc != 0) {
 | 
				
			||||||
 | 
							if (!introspect_drm_prop_range(drm->fd, wlr_conn->props.max_bpc,
 | 
				
			||||||
 | 
									NULL, &wlr_conn->max_bpc)) {
 | 
				
			||||||
 | 
								wlr_log(WLR_ERROR, "Failed to introspect 'max bpc' property");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t edid_len = 0;
 | 
				
			||||||
 | 
						uint8_t *edid = get_drm_prop_blob(drm->fd,
 | 
				
			||||||
 | 
							wlr_conn->id, wlr_conn->props.edid, &edid_len);
 | 
				
			||||||
 | 
						parse_edid(wlr_conn, edid_len, edid);
 | 
				
			||||||
 | 
						free(edid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *subconnector = NULL;
 | 
				
			||||||
 | 
						if (wlr_conn->props.subconnector) {
 | 
				
			||||||
 | 
							subconnector = get_drm_prop_enum(drm->fd,
 | 
				
			||||||
 | 
								wlr_conn->id, wlr_conn->props.subconnector);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (subconnector && strcmp(subconnector, "Native") == 0) {
 | 
				
			||||||
 | 
							free(subconnector);
 | 
				
			||||||
 | 
							subconnector = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_output *output = &wlr_conn->output;
 | 
				
			||||||
 | 
						char description[128];
 | 
				
			||||||
 | 
						snprintf(description, sizeof(description), "%s %s%s%s (%s%s%s)",
 | 
				
			||||||
 | 
							output->make, output->model,
 | 
				
			||||||
 | 
							output->serial ? " " : "",
 | 
				
			||||||
 | 
							output->serial ? output->serial : "",
 | 
				
			||||||
 | 
							output->name,
 | 
				
			||||||
 | 
							subconnector ? " via " : "",
 | 
				
			||||||
 | 
							subconnector ? subconnector : "");
 | 
				
			||||||
 | 
						wlr_output_set_description(output, description);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free(subconnector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Before iterating on the conn's modes, get the current KMS mode
 | 
				
			||||||
 | 
						// in use from the connector's CRTC.
 | 
				
			||||||
 | 
						drmModeModeInfo *current_modeinfo = NULL;
 | 
				
			||||||
 | 
						if (wlr_conn->crtc != NULL) {
 | 
				
			||||||
 | 
							if (wlr_conn->crtc->props.mode_id == 0) {
 | 
				
			||||||
 | 
								// Use the legacy drm interface.
 | 
				
			||||||
 | 
								if (wlr_conn->crtc->legacy_crtc->mode_valid) {
 | 
				
			||||||
 | 
									current_modeinfo = &wlr_conn->crtc->legacy_crtc->mode;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// Use the modern atomic drm interface.
 | 
				
			||||||
 | 
								size_t modeinfo_size = 0;
 | 
				
			||||||
 | 
								current_modeinfo = get_drm_prop_blob(drm->fd, wlr_conn->crtc->id,
 | 
				
			||||||
 | 
									wlr_conn->crtc->props.mode_id, &modeinfo_size);
 | 
				
			||||||
 | 
								assert(modeinfo_size == sizeof(drmModeModeInfo));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_log(WLR_INFO, "Detected modes:");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < drm_conn->count_modes; ++i) {
 | 
				
			||||||
 | 
							if (drm_conn->modes[i].flags & DRM_MODE_FLAG_INTERLACE) {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct wlr_drm_mode *mode = drm_mode_create(&drm_conn->modes[i]);
 | 
				
			||||||
 | 
							if (!mode) {
 | 
				
			||||||
 | 
								wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// If this is the current mode set on the conn's crtc,
 | 
				
			||||||
 | 
							// then set it as the conn's output current mode.
 | 
				
			||||||
 | 
							if (current_modeinfo != NULL && memcmp(&mode->drm_mode,
 | 
				
			||||||
 | 
									current_modeinfo, sizeof(*current_modeinfo)) == 0) {
 | 
				
			||||||
 | 
								// Update width, height, refresh, transform_matrix and current_mode
 | 
				
			||||||
 | 
								// of this connector's output.
 | 
				
			||||||
 | 
								wlr_output_update_mode(&wlr_conn->output, &mode->wlr_mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								uint64_t mode_id = 0;
 | 
				
			||||||
 | 
								get_drm_prop(drm->fd, wlr_conn->crtc->id,
 | 
				
			||||||
 | 
									wlr_conn->crtc->props.mode_id, &mode_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								wlr_conn->crtc->mode_id = mode_id;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wlr_log(WLR_INFO, "  %"PRId32"x%"PRId32"@%"PRId32" %s",
 | 
				
			||||||
 | 
								mode->wlr_mode.width, mode->wlr_mode.height,
 | 
				
			||||||
 | 
								mode->wlr_mode.refresh,
 | 
				
			||||||
 | 
								mode->wlr_mode.preferred ? "(preferred)" : "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wl_list_insert(wlr_conn->output.modes.prev, &mode->wlr_mode.link);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wlr_conn->crtc != NULL && wlr_conn->crtc->props.mode_id != 0) {
 | 
				
			||||||
 | 
							// free() the modeinfo pointer, but only
 | 
				
			||||||
 | 
							// if not using the legacy API.
 | 
				
			||||||
 | 
							free(current_modeinfo);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_conn->possible_crtcs =
 | 
				
			||||||
 | 
							drmModeConnectorGetPossibleCrtcs(drm->fd, drm_conn);
 | 
				
			||||||
 | 
						if (wlr_conn->possible_crtcs == 0) {
 | 
				
			||||||
 | 
							wlr_drm_conn_log(wlr_conn, WLR_ERROR, "No CRTC possible");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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);
 | 
					static void disconnect_drm_connector(struct wlr_drm_connector *conn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void scan_drm_connectors(struct wlr_drm_backend *drm,
 | 
					void scan_drm_connectors(struct wlr_drm_backend *drm,
 | 
				
			||||||
| 
						 | 
					@ -1261,137 +1398,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
 | 
				
			||||||
		if (wlr_conn->status == DRM_MODE_DISCONNECTED &&
 | 
							if (wlr_conn->status == DRM_MODE_DISCONNECTED &&
 | 
				
			||||||
				drm_conn->connection == DRM_MODE_CONNECTED) {
 | 
									drm_conn->connection == DRM_MODE_CONNECTED) {
 | 
				
			||||||
			wlr_log(WLR_INFO, "'%s' connected", wlr_conn->name);
 | 
								wlr_log(WLR_INFO, "'%s' connected", wlr_conn->name);
 | 
				
			||||||
			wlr_log(WLR_DEBUG, "Current CRTC: %d",
 | 
								connect_drm_connector(wlr_conn, drm_conn);
 | 
				
			||||||
				wlr_conn->crtc ? (int)wlr_conn->crtc->id : -1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wlr_output_init(&wlr_conn->output, &drm->backend, &output_impl,
 | 
					 | 
				
			||||||
				drm->display);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wlr_output_set_name(&wlr_conn->output, wlr_conn->name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wlr_conn->output.phys_width = drm_conn->mmWidth;
 | 
					 | 
				
			||||||
			wlr_conn->output.phys_height = drm_conn->mmHeight;
 | 
					 | 
				
			||||||
			wlr_log(WLR_INFO, "Physical size: %"PRId32"x%"PRId32,
 | 
					 | 
				
			||||||
				wlr_conn->output.phys_width, wlr_conn->output.phys_height);
 | 
					 | 
				
			||||||
			wlr_conn->output.subpixel = subpixel_map[drm_conn->subpixel];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			get_drm_connector_props(drm->fd, wlr_conn->id, &wlr_conn->props);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			uint64_t non_desktop;
 | 
					 | 
				
			||||||
			if (get_drm_prop(drm->fd, wlr_conn->id,
 | 
					 | 
				
			||||||
						wlr_conn->props.non_desktop, &non_desktop)) {
 | 
					 | 
				
			||||||
				if (non_desktop == 1) {
 | 
					 | 
				
			||||||
					wlr_log(WLR_INFO, "Non-desktop connector");
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				wlr_conn->output.non_desktop = non_desktop;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wlr_conn->max_bpc = 0;
 | 
					 | 
				
			||||||
			if (wlr_conn->props.max_bpc != 0) {
 | 
					 | 
				
			||||||
				if (!introspect_drm_prop_range(drm->fd, wlr_conn->props.max_bpc,
 | 
					 | 
				
			||||||
						NULL, &wlr_conn->max_bpc)) {
 | 
					 | 
				
			||||||
					wlr_log(WLR_ERROR, "Failed to introspect 'max bpc' property");
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			size_t edid_len = 0;
 | 
					 | 
				
			||||||
			uint8_t *edid = get_drm_prop_blob(drm->fd,
 | 
					 | 
				
			||||||
				wlr_conn->id, wlr_conn->props.edid, &edid_len);
 | 
					 | 
				
			||||||
			parse_edid(wlr_conn, edid_len, edid);
 | 
					 | 
				
			||||||
			free(edid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			char *subconnector = NULL;
 | 
					 | 
				
			||||||
			if (wlr_conn->props.subconnector) {
 | 
					 | 
				
			||||||
				subconnector = get_drm_prop_enum(drm->fd,
 | 
					 | 
				
			||||||
					wlr_conn->id, wlr_conn->props.subconnector);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (subconnector && strcmp(subconnector, "Native") == 0) {
 | 
					 | 
				
			||||||
				free(subconnector);
 | 
					 | 
				
			||||||
				subconnector = NULL;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			struct wlr_output *output = &wlr_conn->output;
 | 
					 | 
				
			||||||
			char description[128];
 | 
					 | 
				
			||||||
			snprintf(description, sizeof(description), "%s %s%s%s (%s%s%s)",
 | 
					 | 
				
			||||||
				output->make, output->model,
 | 
					 | 
				
			||||||
				output->serial ? " " : "",
 | 
					 | 
				
			||||||
				output->serial ? output->serial : "",
 | 
					 | 
				
			||||||
				output->name,
 | 
					 | 
				
			||||||
				subconnector ? " via " : "",
 | 
					 | 
				
			||||||
				subconnector ? subconnector : "");
 | 
					 | 
				
			||||||
			wlr_output_set_description(output, description);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			free(subconnector);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// Before iterating on the conn's modes, get the current KMS mode
 | 
					 | 
				
			||||||
			// in use from the connector's CRTC.
 | 
					 | 
				
			||||||
			drmModeModeInfo *current_modeinfo = NULL;
 | 
					 | 
				
			||||||
			if (wlr_conn->crtc != NULL) {
 | 
					 | 
				
			||||||
				if (wlr_conn->crtc->props.mode_id == 0) {
 | 
					 | 
				
			||||||
					// Use the legacy drm interface.
 | 
					 | 
				
			||||||
					if (wlr_conn->crtc->legacy_crtc->mode_valid) {
 | 
					 | 
				
			||||||
						current_modeinfo = &wlr_conn->crtc->legacy_crtc->mode;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					// Use the modern atomic drm interface.
 | 
					 | 
				
			||||||
			 		size_t modeinfo_size = 0;
 | 
					 | 
				
			||||||
					current_modeinfo = get_drm_prop_blob(drm->fd, wlr_conn->crtc->id,
 | 
					 | 
				
			||||||
						wlr_conn->crtc->props.mode_id, &modeinfo_size);
 | 
					 | 
				
			||||||
					assert(modeinfo_size == sizeof(drmModeModeInfo));
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wlr_log(WLR_INFO, "Detected modes:");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			for (int i = 0; i < drm_conn->count_modes; ++i) {
 | 
					 | 
				
			||||||
				if (drm_conn->modes[i].flags & DRM_MODE_FLAG_INTERLACE) {
 | 
					 | 
				
			||||||
					continue;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				struct wlr_drm_mode *mode = drm_mode_create(&drm_conn->modes[i]);
 | 
					 | 
				
			||||||
				if (!mode) {
 | 
					 | 
				
			||||||
					wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
					 | 
				
			||||||
					continue;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// If this is the current mode set on the conn's crtc,
 | 
					 | 
				
			||||||
				// then set it as the conn's output current mode.
 | 
					 | 
				
			||||||
				if (current_modeinfo != NULL && memcmp(&mode->drm_mode,
 | 
					 | 
				
			||||||
						current_modeinfo, sizeof(*current_modeinfo)) == 0) {
 | 
					 | 
				
			||||||
					// Update width, height, refresh, transform_matrix and current_mode
 | 
					 | 
				
			||||||
					// of this connector's output.
 | 
					 | 
				
			||||||
					wlr_output_update_mode(&wlr_conn->output, &mode->wlr_mode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					uint64_t mode_id = 0;
 | 
					 | 
				
			||||||
					get_drm_prop(drm->fd, wlr_conn->crtc->id,
 | 
					 | 
				
			||||||
						wlr_conn->crtc->props.mode_id, &mode_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					wlr_conn->crtc->mode_id = mode_id;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				wlr_log(WLR_INFO, "  %"PRId32"x%"PRId32"@%"PRId32" %s",
 | 
					 | 
				
			||||||
					mode->wlr_mode.width, mode->wlr_mode.height,
 | 
					 | 
				
			||||||
					mode->wlr_mode.refresh,
 | 
					 | 
				
			||||||
					mode->wlr_mode.preferred ? "(preferred)" : "");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				wl_list_insert(wlr_conn->output.modes.prev, &mode->wlr_mode.link);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (wlr_conn->crtc != NULL && wlr_conn->crtc->props.mode_id != 0) {
 | 
					 | 
				
			||||||
				// free() the modeinfo pointer, but only
 | 
					 | 
				
			||||||
				// if not using the legacy API.
 | 
					 | 
				
			||||||
				free(current_modeinfo);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wlr_conn->possible_crtcs =
 | 
					 | 
				
			||||||
				drmModeConnectorGetPossibleCrtcs(drm->fd, drm_conn);
 | 
					 | 
				
			||||||
			if (wlr_conn->possible_crtcs == 0) {
 | 
					 | 
				
			||||||
				wlr_drm_conn_log(wlr_conn, WLR_ERROR, "No CRTC possible");
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wlr_output_update_enabled(&wlr_conn->output, wlr_conn->crtc != NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wlr_conn->status = DRM_MODE_CONNECTED;
 | 
					 | 
				
			||||||
			new_outputs[new_outputs_len++] = wlr_conn;
 | 
								new_outputs[new_outputs_len++] = wlr_conn;
 | 
				
			||||||
		} else if (wlr_conn->status == DRM_MODE_CONNECTED &&
 | 
							} else if (wlr_conn->status == DRM_MODE_CONNECTED &&
 | 
				
			||||||
				drm_conn->connection != DRM_MODE_CONNECTED) {
 | 
									drm_conn->connection != DRM_MODE_CONNECTED) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue