aboutsummaryrefslogtreecommitdiff
path: root/backend/drm
diff options
context:
space:
mode:
Diffstat (limited to 'backend/drm')
-rw-r--r--backend/drm/drm.c269
1 files changed, 138 insertions, 131 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 77555aa2..2ebdbdc6 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -1157,6 +1157,143 @@ static struct wlr_drm_crtc *connector_get_current_crtc(
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);
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 &&
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);
-
- 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;
+ 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) {