mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-25 22:25:58 +01: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…
Reference in a new issue