summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.com>2023-04-27 16:04:58 +0300
committerPekka Paalanen <pekka.paalanen@collabora.com>2023-04-28 13:58:53 +0300
commitdfdb1a71f8ddefe909b4996320bd198af55a6779 (patch)
tree600b932e4dcd5e03cf4d6671692519e3a2a0020f
parentfefdd577c8284a8009e827c1481d223d9901a311 (diff)
downloadweston-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>
-rw-r--r--libweston/backend-drm/drm-internal.h2
-rw-r--r--libweston/backend-drm/modes.c79
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);
}
/**