From cb6f58449683f7b30a6a8718bac5475c39b291d8 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 13 Jan 2021 00:33:19 +0100 Subject: [PATCH] backend/drm: add support for the subconnector property The subconnector property indicates the connector sub-type. This is useful because that usually indicates what kind of connector the user has plugged in to their monitor, e.g. a DisplayPort-to-DVI cable will indicate a DVI subconnector. Also some laptops have non-DP connectors that are internally linked to a DP port on the GPU. Set the output description accordingly. See https://drmdb.emersion.fr/properties/3233857728/subconnector --- backend/drm/drm.c | 17 +++++++++++++++-- backend/drm/properties.c | 26 ++++++++++++++++++++++++++ include/backend/drm/properties.h | 2 ++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index a045bd53..0bf51209 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -1349,12 +1349,25 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { parse_edid(&wlr_conn->output, 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)", - output->make, output->model, output->serial, output->name); + snprintf(description, sizeof(description), "%s %s %s (%s%s%s)", + output->make, output->model, output->serial, output->name, + subconnector ? " via " : "", subconnector ? subconnector : ""); wlr_output_set_description(output, description); + free(subconnector); + wlr_log(WLR_INFO, "Detected modes:"); for (int i = 0; i < drm_conn->count_modes; ++i) { diff --git a/backend/drm/properties.c b/backend/drm/properties.c index de51a3de..5581a130 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include #include #include @@ -24,6 +25,7 @@ static const struct prop_info connector_info[] = { { "EDID", INDEX(edid) }, { "PATH", INDEX(path) }, { "link-status", INDEX(link_status) }, + { "subconnector", INDEX(subconnector) }, { "vrr_capable", INDEX(vrr_capable) }, #undef INDEX }; @@ -151,3 +153,27 @@ void *get_drm_prop_blob(int fd, uint32_t obj, uint32_t prop, size_t *ret_len) { drmModeFreePropertyBlob(blob); return ptr; } + +char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop_id) { + uint64_t value; + if (!get_drm_prop(fd, obj, prop_id, &value)) { + return NULL; + } + + drmModePropertyRes *prop = drmModeGetProperty(fd, prop_id); + if (!prop) { + return NULL; + } + + char *str = NULL; + for (int i = 0; i < prop->count_enums; i++) { + if (prop->enums[i].value == value) { + str = strdup(prop->enums[i].name); + break; + } + } + + drmModeFreeProperty(prop); + + return str; +} diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index c2027c4f..9e1fe0b6 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -17,6 +17,7 @@ union wlr_drm_connector_props { uint32_t link_status; // not guaranteed to exist uint32_t path; uint32_t vrr_capable; // not guaranteed to exist + uint32_t subconnector; // not guaranteed to exist // atomic-modesetting only @@ -69,5 +70,6 @@ bool get_drm_plane_props(int fd, uint32_t id, union wlr_drm_plane_props *out); bool get_drm_prop(int fd, uint32_t obj, uint32_t prop, uint64_t *ret); void *get_drm_prop_blob(int fd, uint32_t obj, uint32_t prop, size_t *ret_len); +char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop); #endif