mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-26 06:35: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,110 +1157,10 @@ static struct wlr_drm_crtc *connector_get_current_crtc(
|
||||||
return NULL;
|
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_log(WLR_DEBUG, "Current CRTC: %d",
|
||||||
wlr_conn->crtc ? (int)wlr_conn->crtc->id : -1);
|
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_output_update_enabled(&wlr_conn->output, wlr_conn->crtc != NULL);
|
||||||
|
|
||||||
wlr_conn->status = DRM_MODE_CONNECTED;
|
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;
|
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