From 35da9970019be6580394d5d6234b8ede0b2f0d5a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 2 Feb 2023 12:14:11 +0100 Subject: backend/drm: use libdisplay-info to parse EDID --- backend/drm/util.c | 67 +++++++++++++----------------------------------------- 1 file changed, 16 insertions(+), 51 deletions(-) (limited to 'backend/drm/util.c') diff --git a/backend/drm/util.c b/backend/drm/util.c index adb9306e..d4ece1f9 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include #include @@ -48,9 +50,6 @@ enum wlr_output_mode_aspect_ratio get_picture_aspect_ratio(const drmModeModeInfo } } -/* See https://en.wikipedia.org/wiki/Extended_Display_Identification_Data for layout of EDID data. - * We don't parse the EDID properly. We just expect to receive valid data. - */ void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) { struct wlr_output *output = &conn->output; @@ -61,62 +60,28 @@ void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) output->model = NULL; output->serial = NULL; - if (!data || len < 128) { + struct di_info *info = di_info_parse_edid(data, len); + if (info == NULL) { + wlr_log(WLR_ERROR, "Failed to parse EDID"); return; } - uint16_t id = (data[8] << 8) | data[9]; - const char *manu = get_pnp_manufacturer(id); - char pnp_id[4]; + const struct di_edid *edid = di_info_get_edid(info); + const struct di_edid_vendor_product *vendor_product = di_edid_get_vendor_product(edid); + char pnp_id[] = { + vendor_product->manufacturer[0], + vendor_product->manufacturer[1], + vendor_product->manufacturer[2], + '\0', + }; + const char *manu = get_pnp_manufacturer(vendor_product->manufacturer); if (!manu) { - // The ASCII 3-letter manufacturer PnP ID is encoded in 5-bit codes - pnp_id[0] = ((id >> 10) & 0x1F) + '@'; - pnp_id[1] = ((id >> 5) & 0x1F) + '@'; - pnp_id[2] = ((id >> 0) & 0x1F) + '@'; - pnp_id[3] = '\0'; manu = pnp_id; } output->make = strdup(manu); - uint16_t model = data[10] | (data[11] << 8); - char model_str[32]; - snprintf(model_str, sizeof(model_str), "0x%04" PRIX16, model); - - uint32_t serial = data[12] | (data[13] << 8) | (data[14] << 8) | (data[15] << 8); - char serial_str[32]; - if (serial != 0) { - snprintf(serial_str, sizeof(serial_str), "0x%08" PRIX32, serial); - } else { - serial_str[0] = '\0'; - } - - for (size_t i = 72; i <= 108; i += 18) { - uint16_t flag = (data[i] << 8) | data[i + 1]; - if (flag == 0 && data[i + 3] == 0xFC) { - snprintf(model_str, sizeof(model_str), "%.13s", &data[i + 5]); - - // Monitor names are terminated by newline if they're too short - char *nl = strchr(model_str, '\n'); - if (nl) { - *nl = '\0'; - } - } else if (flag == 0 && data[i + 3] == 0xFF) { - snprintf(serial_str, sizeof(serial_str), "%.13s", &data[i + 5]); - - // Monitor serial numbers are terminated by newline if they're too - // short - char* nl = strchr(serial_str, '\n'); - - if (nl) { - *nl = '\0'; - } - } - } - - output->model = strdup(model_str); - if (serial_str[0] != '\0') { - output->serial = strdup(serial_str); - } + output->model = di_info_get_model(info); + output->serial = di_info_get_serial(info); } const char *drm_connector_status_str(drmModeConnection status) { -- cgit v1.2.3