diff options
author | Pekka Paalanen <pekka.paalanen@collabora.com> | 2023-04-27 16:04:58 +0300 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.com> | 2023-04-28 13:58:53 +0300 |
commit | dfdb1a71f8ddefe909b4996320bd198af55a6779 (patch) | |
tree | 600b932e4dcd5e03cf4d6671692519e3a2a0020f /libweston | |
parent | fefdd577c8284a8009e827c1481d223d9901a311 (diff) | |
download | weston-dfdb1a71f8ddefe909b4996320bd198af55a6779.tar.gz |
backend-drm: let EDID parser return malloc'd strings
This will make adding libdisplay-info as another EDID parser easier,
because libdisplay-info always returns malloc'd strings.
To make things easier to extend as well, I introduce struct
drm_head_info. The libdisplay-info case will likely return more
information than this in the future.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Diffstat (limited to 'libweston')
-rw-r--r-- | libweston/backend-drm/drm-internal.h | 2 | ||||
-rw-r--r-- | libweston/backend-drm/modes.c | 79 |
2 files changed, 46 insertions, 35 deletions
diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index 6af4bc8a..c8042f22 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -616,8 +616,6 @@ struct drm_head { struct weston_head base; struct drm_connector connector; - struct drm_edid edid; - struct backlight *backlight; drmModeModeInfo inherited_mode; /**< Original mode on the connector */ diff --git a/libweston/backend-drm/modes.c b/libweston/backend-drm/modes.c index ae3a35d8..9d1aa566 100644 --- a/libweston/backend-drm/modes.c +++ b/libweston/backend-drm/modes.c @@ -34,6 +34,27 @@ #include "drm-internal.h" #include "shared/weston-drm-fourcc.h" +#include "shared/xalloc.h" + +struct drm_head_info { + char *make; /* The monitor make (PNP ID or company name). */ + char *model; /* The monitor model (product name). */ + char *serial_number; + + /* The monitor supported EOTF modes, combination of + * enum weston_eotf_mode bits. + */ + uint32_t eotf_mask; +}; + +static void +drm_head_info_fini(struct drm_head_info *dhi) +{ + free(dhi->make); + free(dhi->model); + free(dhi->serial_number); + *dhi = (struct drm_head_info){}; +} static const char *const aspect_ratio_as_string[] = { [WESTON_MODE_PIC_AR_NONE] = "", @@ -302,27 +323,18 @@ edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length) * * \param head The head whose \c drm_edid to fill in. * \param props The DRM connector properties to get the EDID from. - * \param[out] make The monitor make (PNP ID). - * \param[out] model The monitor model (name). - * \param[out] serial_number The monitor serial number. - * \param[out] eotf_mask The monitor supported EOTF modes, combination of - * enum weston_eotf_mode bits. + * \param[out] dhi Receives information from EDID. * - * Each of \c *make, \c *model and \c *serial_number are set only if the - * information is found in the EDID. The pointers they are set to must not - * be free()'d explicitly, instead they get implicitly freed when the - * \c drm_head is destroyed. + * \c *dhi must be drm_head_info_fini()'d by the caller. */ static void find_and_parse_output_edid(struct drm_head *head, drmModeObjectPropertiesPtr props, - const char **make, - const char **model, - const char **serial_number, - uint32_t *eotf_mask) + struct drm_head_info *dhi) { struct drm_device *device = head->connector.device; drmModePropertyBlobPtr edid_blob = NULL; + struct drm_edid edid = {}; uint32_t blob_id; int rc; @@ -337,21 +349,19 @@ find_and_parse_output_edid(struct drm_head *head, if (!edid_blob) return; - rc = edid_parse(&head->edid, - edid_blob->data, - edid_blob->length); - if (!rc) { - if (head->edid.pnp_id[0] != '\0') - *make = head->edid.pnp_id; - if (head->edid.monitor_name[0] != '\0') - *model = head->edid.monitor_name; - if (head->edid.serial_number[0] != '\0') - *serial_number = head->edid.serial_number; + rc = edid_parse(&edid, edid_blob->data, edid_blob->length); + if (rc == 0) { + if (edid.pnp_id[0] != '\0') + dhi->make = xstrdup(edid.pnp_id); + if (edid.monitor_name[0] != '\0') + dhi->model = xstrdup(edid.monitor_name); + if (edid.serial_number[0] != '\0') + dhi->serial_number = xstrdup(edid.serial_number); } drmModeFreePropertyBlob(edid_blob); /* TODO: parse this from EDID */ - *eotf_mask = WESTON_EOTF_MODE_ALL_MASK; + dhi->eotf_mask = WESTON_EOTF_MODE_ALL_MASK; } static void @@ -532,15 +542,16 @@ update_head_from_connector(struct drm_head *head) struct drm_connector *connector = &head->connector; drmModeObjectProperties *props = connector->props_drm; drmModeConnector *conn = connector->conn; - const char *make = "unknown"; - const char *model = "unknown"; - const char *serial_number = "unknown"; - uint32_t eotf_mask = WESTON_EOTF_MODE_SDR; - - find_and_parse_output_edid(head, props, &make, &model, &serial_number, &eotf_mask); - weston_head_set_monitor_strings(&head->base, make, model, serial_number); - prune_eotf_modes_by_kms_support(head, &eotf_mask); - weston_head_set_supported_eotf_mask(&head->base, eotf_mask); + struct drm_head_info dhi = { .eotf_mask = WESTON_EOTF_MODE_SDR }; + + find_and_parse_output_edid(head, props, &dhi); + + weston_head_set_monitor_strings(&head->base, dhi.make ?: "unknown", + dhi.model ?: "unknown", + dhi.serial_number ?: "unknown"); + + prune_eotf_modes_by_kms_support(head, &dhi.eotf_mask); + weston_head_set_supported_eotf_mask(&head->base, dhi.eotf_mask); weston_head_set_non_desktop(&head->base, check_non_desktop(connector, props)); weston_head_set_subpixel(&head->base, @@ -554,6 +565,8 @@ update_head_from_connector(struct drm_head *head) /* Unknown connection status is assumed disconnected. */ weston_head_set_connection_status(&head->base, conn->connection == DRM_MODE_CONNECTED); + + drm_head_info_fini(&dhi); } /** |