From e636990de3031d477fa6f955eebc096cfef92c5c Mon Sep 17 00:00:00 2001 From: Leandro Ribeiro Date: Wed, 17 Jun 2020 11:09:47 -0300 Subject: [PATCH] drm-backend: move connector data from struct drm_head to struct drm_connector This is the first step in order to add support for writeback connector in Weston. We don't want writeback connectors data to be stored in 'struct drm_head' objects, as these objects are used to output content and we should not use writeback connectors for this purpose. The writeback connectors will be stored in a new 'struct drm_writeback', but the connector data is common between 'struct drm_head' and 'struct drm_writeback'. So move connector data from 'struct drm_head' to 'struct drm_connector'. This helps to avoid code duplication and makes the code clearer. Signed-off-by: Leandro Ribeiro --- libweston/backend-drm/drm-internal.h | 17 ++- libweston/backend-drm/drm.c | 171 ++++++++++++++++----------- libweston/backend-drm/kms.c | 70 ++++++----- libweston/backend-drm/modes.c | 33 +++--- 4 files changed, 168 insertions(+), 123 deletions(-) diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index 833cf6e1..98e2ca73 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -466,16 +466,23 @@ struct drm_plane { } formats[]; }; -struct drm_head { - struct weston_head base; +struct drm_connector { struct drm_backend *backend; + struct drm_head *head; - drmModeConnector *connector; + drmModeConnector *conn; uint32_t connector_id; - struct drm_edid edid; /* Holds the properties for the connector */ - struct drm_property_info props_conn[WDRM_CONNECTOR__COUNT]; + struct drm_property_info props[WDRM_CONNECTOR__COUNT]; +}; + +struct drm_head { + struct weston_head base; + struct drm_backend *backend; + struct drm_connector connector; + + struct drm_edid edid; struct backlight *backlight; diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index b9b04d01..76820dc3 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -213,7 +213,7 @@ drm_head_find_by_connector(struct drm_backend *backend, uint32_t connector_id) wl_list_for_each(base, &backend->compositor->head_list, compositor_link) { head = to_drm_head(base); - if (head->connector_id == connector_id) + if (head->connector.connector_id == connector_id) return head; } @@ -1362,12 +1362,13 @@ static int drm_head_read_current_setup(struct drm_head *head, struct drm_backend *backend) { int drm_fd = backend->drm.fd; + drmModeConnector *conn = head->connector.conn; drmModeEncoder *encoder; drmModeCrtc *crtc; /* Get the current mode on the crtc that's currently driving * this connector. */ - encoder = drmModeGetEncoder(drm_fd, head->connector->encoder_id); + encoder = drmModeGetEncoder(drm_fd, conn->encoder_id); if (encoder != NULL) { head->inherited_crtc_id = encoder->crtc_id; @@ -1426,15 +1427,16 @@ drm_output_init_gamma_size(struct drm_output *output) } static uint32_t -drm_head_get_possible_crtcs_mask(struct drm_head *head) +drm_connector_get_possible_crtcs_mask(struct drm_connector *connector) { uint32_t possible_crtcs = 0; + drmModeConnector *conn = connector->conn; drmModeEncoder *encoder; int i; - for (i = 0; i < head->connector->count_encoders; i++) { - encoder = drmModeGetEncoder(head->backend->drm.fd, - head->connector->encoders[i]); + for (i = 0; i < conn->count_encoders; i++) { + encoder = drmModeGetEncoder(connector->backend->drm.fd, + conn->encoders[i]); if (!encoder) continue; @@ -1475,7 +1477,8 @@ drm_output_pick_crtc(struct drm_output *output) wl_list_for_each(base, &output->base.head_list, output_link) { head = to_drm_head(base); - possible_crtcs &= drm_head_get_possible_crtcs_mask(head); + possible_crtcs &= + drm_connector_get_possible_crtcs_mask(&head->connector); crtc_id = head->inherited_crtc_id; if (crtc_id > 0 && n < ARRAY_LENGTH(existing_crtc)) @@ -1957,14 +1960,14 @@ drm_head_get_current_protection(struct drm_head *head, enum wdrm_hdcp_content_type type; enum weston_hdcp_protection weston_hdcp = WESTON_HDCP_DISABLE; - info = &head->props_conn[WDRM_CONNECTOR_CONTENT_PROTECTION]; + info = &head->connector.props[WDRM_CONNECTOR_CONTENT_PROTECTION]; protection = drm_property_get_value(info, props, WDRM_CONTENT_PROTECTION__COUNT); if (protection == WDRM_CONTENT_PROTECTION__COUNT) return WESTON_HDCP_DISABLE; - info = &head->props_conn[WDRM_CONNECTOR_HDCP_CONTENT_TYPE]; + info = &head->connector.props[WDRM_CONNECTOR_HDCP_CONTENT_TYPE]; type = drm_property_get_value(info, props, WDRM_HDCP_CONTENT_TYPE__COUNT); @@ -1981,7 +1984,7 @@ drm_head_get_current_protection(struct drm_head *head, &weston_hdcp) == -1) { weston_log("Invalid drm protection:%d type:%d, for head:%s connector-id:%d\n", protection, type, head->base.name, - head->connector_id); + head->connector.connector_id); return WESTON_HDCP_DISABLE; } @@ -1990,62 +1993,87 @@ drm_head_get_current_protection(struct drm_head *head, /** Replace connector data and monitor information * - * @param head The head to update. - * @param connector The connector data to be owned by the head, must match - * the head's connector ID. + * @param connector The drm_connector object to be updated. + * @param conn The connector data to be owned by the drm_connector, must match + * the current drm_connector ID. * @return 0 on success, -1 on failure. * * Takes ownership of @c connector on success, not on failure. * - * May schedule a heads changed call. + * May schedule a heads changed call if this connector is owned by a head */ static int -drm_head_assign_connector_info(struct drm_head *head, - drmModeConnector *connector) +drm_connector_assign_connector_info(struct drm_connector *connector, + drmModeConnector *conn) { drmModeObjectProperties *props; - assert(connector); - assert(head->connector_id == connector->connector_id); + assert(connector->connector_id == conn->connector_id); - props = drmModeObjectGetProperties(head->backend->drm.fd, - head->connector_id, + props = drmModeObjectGetProperties(connector->backend->drm.fd, + connector->connector_id, DRM_MODE_OBJECT_CONNECTOR); if (!props) { - weston_log("Error: failed to get connector '%s' properties\n", - head->base.name); + weston_log("Error: failed to get connector properties\n"); return -1; } - if (head->connector) - drmModeFreeConnector(head->connector); - head->connector = connector; + if (connector->conn && connector->conn != conn) + drmModeFreeConnector(connector->conn); + connector->conn = conn; - drm_property_info_free(head->props_conn, WDRM_CONNECTOR__COUNT); - drm_property_info_populate(head->backend, connector_props, - head->props_conn, + drm_property_info_free(connector->props, WDRM_CONNECTOR__COUNT); + drm_property_info_populate(connector->backend, connector_props, + connector->props, WDRM_CONNECTOR__COUNT, props); - update_head_from_connector(head, props); - weston_head_set_content_protection_status(&head->base, - drm_head_get_current_protection(head, props)); + if (connector->head != NULL) { + update_head_from_connector(connector->head, props); + weston_head_set_content_protection_status(&connector->head->base, + drm_head_get_current_protection(connector->head, props)); + } + drmModeFreeObjectProperties(props); return 0; } +static int +drm_connector_init(struct drm_backend *b, struct drm_connector *connector, + uint32_t connector_id) +{ + connector->backend = b; + connector->connector_id = connector_id; + connector->head = NULL; + + connector->conn = drmModeGetConnector(b->drm.fd, connector_id); + if (!connector->conn) { + weston_log("DRM: Could not retrieve connector.\n"); + return -1; + } + + return 0; +} + +static void +drm_connector_fini(struct drm_connector *connector) +{ + drmModeFreeConnector(connector->conn); + drm_property_info_free(connector->props, WDRM_CONNECTOR__COUNT); +} + static void drm_head_log_info(struct drm_head *head, const char *msg) { if (head->base.connected) { weston_log("DRM: head '%s' %s, connector %d is connected, " "EDID make '%s', model '%s', serial '%s'\n", - head->base.name, msg, head->connector_id, + head->base.name, msg, head->connector.connector_id, head->base.make, head->base.model, head->base.serial_number ?: ""); } else { weston_log("DRM: head '%s' %s, connector %d is disconnected.\n", - head->base.name, msg, head->connector_id); + head->base.name, msg, head->connector.connector_id); } } @@ -2060,18 +2088,18 @@ drm_head_log_info(struct drm_head *head, const char *msg) static void drm_head_update_info(struct drm_head *head) { - drmModeConnector *connector; + drmModeConnector *conn; - connector = drmModeGetConnector(head->backend->drm.fd, - head->connector_id); - if (!connector) { + conn = drmModeGetConnector(head->backend->drm.fd, + head->connector.connector_id); + if (!conn) { weston_log("DRM: getting connector info for '%s' failed.\n", head->base.name); return; } - if (drm_head_assign_connector_info(head, connector) < 0) - drmModeFreeConnector(connector); + if (drm_connector_assign_connector_info(&head->connector, conn) < 0) + drmModeFreeConnector(conn); if (head->base.device_changed) drm_head_log_info(head, "updated"); @@ -2093,39 +2121,42 @@ drm_head_create(struct drm_backend *backend, uint32_t connector_id, struct udev_device *drm_device) { struct drm_head *head; - drmModeConnector *connector; + drmModeConnector *conn; char *name; + int ret; head = zalloc(sizeof *head); if (!head) return NULL; - connector = drmModeGetConnector(backend->drm.fd, connector_id); - if (!connector) - goto err_alloc; + head->backend = backend; + + ret = drm_connector_init(backend, &head->connector, connector_id); + if (ret < 0) + goto err; + head->connector.head = head; + conn = head->connector.conn; - name = make_connector_name(connector); + name = make_connector_name(conn); if (!name) - goto err_alloc; + goto err_name; weston_head_init(&head->base, name); free(name); - head->connector_id = connector_id; - head->backend = backend; - - head->backlight = backlight_init(drm_device, connector->connector_type); + ret = drm_connector_assign_connector_info(&head->connector, conn); + if (ret < 0) + goto err_assign; - if (drm_head_assign_connector_info(head, connector) < 0) - goto err_init; + head->backlight = backlight_init(drm_device, conn->connector_type); - if (head->connector->connector_type == DRM_MODE_CONNECTOR_LVDS || - head->connector->connector_type == DRM_MODE_CONNECTOR_eDP) + if (conn->connector_type == DRM_MODE_CONNECTOR_LVDS || + conn->connector_type == DRM_MODE_CONNECTOR_eDP) weston_head_set_internal(&head->base); if (drm_head_read_current_setup(head, backend) < 0) { weston_log("Failed to retrieve current mode from connector %d.\n", - head->connector_id); + head->connector.connector_id); /* Not fatal. */ } @@ -2134,15 +2165,12 @@ drm_head_create(struct drm_backend *backend, uint32_t connector_id, return head; -err_init: +err_assign: weston_head_release(&head->base); - -err_alloc: - if (connector) - drmModeFreeConnector(connector); - +err_name: + drm_connector_fini(&head->connector); +err: free(head); - return NULL; } @@ -2151,8 +2179,7 @@ drm_head_destroy(struct drm_head *head) { weston_head_release(&head->base); - drm_property_info_free(head->props_conn, WDRM_CONNECTOR__COUNT); - drmModeFreeConnector(head->connector); + drm_connector_fini(&head->connector); if (head->backlight) backlight_destroy(head->backlight); @@ -2247,6 +2274,7 @@ drm_backend_update_heads(struct drm_backend *b, struct udev_device *drm_device) drmModeRes *resources; struct weston_head *base, *next; struct drm_head *head; + uint32_t connector_id; int i; resources = drmModeGetResources(b->drm.fd); @@ -2257,7 +2285,7 @@ drm_backend_update_heads(struct drm_backend *b, struct udev_device *drm_device) /* collect new connectors that have appeared, e.g. MST */ for (i = 0; i < resources->count_connectors; i++) { - uint32_t connector_id = resources->connectors[i]; + connector_id = resources->connectors[i]; head = drm_head_find_by_connector(b, connector_id); if (head) { @@ -2274,11 +2302,11 @@ drm_backend_update_heads(struct drm_backend *b, struct udev_device *drm_device) wl_list_for_each_safe(base, next, &b->compositor->head_list, compositor_link) { bool removed = true; - head = to_drm_head(base); + connector_id = head->connector.connector_id; for (i = 0; i < resources->count_connectors; i++) { - if (resources->connectors[i] == head->connector_id) { + if (resources->connectors[i] == connector_id) { removed = false; break; } @@ -2288,7 +2316,7 @@ drm_backend_update_heads(struct drm_backend *b, struct udev_device *drm_device) continue; weston_log("DRM: head '%s' (connector %d) disappeared.\n", - head->base.name, head->connector_id); + head->base.name, connector_id); drm_head_destroy(head); } @@ -2296,16 +2324,17 @@ drm_backend_update_heads(struct drm_backend *b, struct udev_device *drm_device) } static enum wdrm_connector_property -drm_head_find_property_by_id(struct drm_head *head, uint32_t property_id) +drm_connector_find_property_by_id(struct drm_connector *connector, + uint32_t property_id) { int i; enum wdrm_connector_property prop = WDRM_CONNECTOR__COUNT; - if (!head || !property_id) + if (!connector || !property_id) return WDRM_CONNECTOR__COUNT; for (i = 0; i < WDRM_CONNECTOR__COUNT; i++) - if (head->props_conn[i].prop_id == property_id) { + if (connector->props[i].prop_id == property_id) { prop = (enum wdrm_connector_property) i; break; } @@ -2328,7 +2357,7 @@ drm_backend_update_conn_props(struct drm_backend *b, return; } - conn_prop = drm_head_find_property_by_id(head, property_id); + conn_prop = drm_connector_find_property_by_id(&head->connector, property_id); if (conn_prop >= WDRM_CONNECTOR__COUNT) return; diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c index 0f6993fa..d508ab5c 100644 --- a/libweston/backend-drm/kms.c +++ b/libweston/backend-drm/kms.c @@ -676,7 +676,7 @@ drm_output_apply_state_legacy(struct drm_output_state *state) wl_list_for_each(head, &output->base.head_list, base.output_link) { assert(n_conn < MAX_CLONED_CONNECTORS); - connectors[n_conn++] = head->connector_id; + connectors[n_conn++] = head->connector.connector_id; } /* If disable_planes is set then assign_planes() wasn't @@ -772,14 +772,14 @@ drm_output_apply_state_legacy(struct drm_output_state *state) if (state->dpms != output->state_cur->dpms) { wl_list_for_each(head, &output->base.head_list, base.output_link) { - dpms_prop = &head->props_conn[WDRM_CONNECTOR_DPMS]; + dpms_prop = &head->connector.props[WDRM_CONNECTOR_DPMS]; if (dpms_prop->prop_id == 0) continue; ret = drmModeConnectorSetProperty(backend->drm.fd, - head->connector_id, - dpms_prop->prop_id, - state->dpms); + head->connector.connector_id, + dpms_prop->prop_id, + state->dpms); if (ret) { weston_log("DRM: DPMS: failed property set for %s\n", head->base.name); @@ -817,19 +817,19 @@ crtc_add_prop(drmModeAtomicReq *req, struct drm_crtc *crtc, } static int -connector_add_prop(drmModeAtomicReq *req, struct drm_head *head, +connector_add_prop(drmModeAtomicReq *req, struct drm_connector *connector, enum wdrm_connector_property prop, uint64_t val) { - struct drm_property_info *info = &head->props_conn[prop]; + struct drm_property_info *info = &connector->props[prop]; + uint32_t connector_id = connector->connector_id; int ret; if (info->prop_id == 0) return -1; - ret = drmModeAtomicAddProperty(req, head->connector_id, - info->prop_id, val); - drm_debug(head->backend, "\t\t\t[CONN:%lu] %lu (%s) -> %llu (0x%llx)\n", - (unsigned long) head->connector_id, + ret = drmModeAtomicAddProperty(req, connector_id, info->prop_id, val); + drm_debug(connector->backend, "\t\t\t[CONN:%lu] %lu (%s) -> %llu (0x%llx)\n", + (unsigned long) connector_id, (unsigned long) info->prop_id, info->name, (unsigned long long) val, (unsigned long long) val); return (ret <= 0) ? -1 : 0; @@ -855,10 +855,10 @@ plane_add_prop(drmModeAtomicReq *req, struct drm_plane *plane, } static bool -drm_head_has_prop(struct drm_head *head, - enum wdrm_connector_property prop) +drm_connector_has_prop(struct drm_connector *connector, + enum wdrm_connector_property prop) { - if (head && head->props_conn[prop].prop_id != 0) + if (connector->props[prop].prop_id != 0) return true; return false; @@ -894,20 +894,21 @@ get_drm_protection_from_weston(enum weston_hdcp_protection weston_protection, } static void -drm_head_set_hdcp_property(struct drm_head *head, - enum weston_hdcp_protection protection, - drmModeAtomicReq *req) +drm_connector_set_hdcp_property(struct drm_connector *connector, + enum weston_hdcp_protection protection, + drmModeAtomicReq *req) { int ret; enum wdrm_content_protection_state drm_protection; enum wdrm_hdcp_content_type drm_cp_type; struct drm_property_enum_info *enum_info; uint64_t prop_val; + struct drm_property_info *props = connector->props; get_drm_protection_from_weston(protection, &drm_protection, &drm_cp_type); - if (!drm_head_has_prop(head, WDRM_CONNECTOR_CONTENT_PROTECTION)) + if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_CONTENT_PROTECTION)) return; /* @@ -915,23 +916,23 @@ drm_head_set_hdcp_property(struct drm_head *head, * HDCP2.2, therefore, type-1 cannot be supported. The type-0 content * still can be supported if the content-protection property is exposed. */ - if (!drm_head_has_prop(head, WDRM_CONNECTOR_HDCP_CONTENT_TYPE) && + if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_HDCP_CONTENT_TYPE) && drm_cp_type != WDRM_HDCP_CONTENT_TYPE0) return; - enum_info = head->props_conn[WDRM_CONNECTOR_CONTENT_PROTECTION].enum_values; + enum_info = props[WDRM_CONNECTOR_CONTENT_PROTECTION].enum_values; prop_val = enum_info[drm_protection].value; - ret = connector_add_prop(req, head, WDRM_CONNECTOR_CONTENT_PROTECTION, - prop_val); + ret = connector_add_prop(req, connector, + WDRM_CONNECTOR_CONTENT_PROTECTION, prop_val); assert(ret == 0); - if (!drm_head_has_prop(head, WDRM_CONNECTOR_HDCP_CONTENT_TYPE)) + if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_HDCP_CONTENT_TYPE)) return; - enum_info = head->props_conn[WDRM_CONNECTOR_HDCP_CONTENT_TYPE].enum_values; + enum_info = props[WDRM_CONNECTOR_HDCP_CONTENT_TYPE].enum_values; prop_val = enum_info[drm_cp_type].value; - ret = connector_add_prop(req, head, WDRM_CONNECTOR_HDCP_CONTENT_TYPE, - prop_val); + ret = connector_add_prop(req, connector, + WDRM_CONNECTOR_HDCP_CONTENT_TYPE, prop_val); assert(ret == 0); } @@ -969,7 +970,8 @@ drm_output_apply_state_atomic(struct drm_output_state *state, /* No need for the DPMS property, since it is implicit in * routing and CRTC activity. */ wl_list_for_each(head, &output->base.head_list, base.output_link) { - ret |= connector_add_prop(req, head, WDRM_CONNECTOR_CRTC_ID, + ret |= connector_add_prop(req, &head->connector, + WDRM_CONNECTOR_CRTC_ID, crtc->crtc_id); } } else { @@ -979,11 +981,13 @@ drm_output_apply_state_atomic(struct drm_output_state *state, /* No need for the DPMS property, since it is implicit in * routing and CRTC activity. */ wl_list_for_each(head, &output->base.head_list, base.output_link) - ret |= connector_add_prop(req, head, WDRM_CONNECTOR_CRTC_ID, 0); + ret |= connector_add_prop(req, &head->connector, + WDRM_CONNECTOR_CRTC_ID, 0); } wl_list_for_each(head, &output->base.head_list, base.output_link) - drm_head_set_hdcp_property(head, state->protection, req); + drm_connector_set_hdcp_property(&head->connector, + state->protection, req); if (ret != 0) { weston_log("couldn't set atomic CRTC/connector state\n"); @@ -1081,6 +1085,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, struct weston_head *head_base; struct drm_head *head; struct drm_crtc *crtc; + uint32_t connector_id; int err; drm_debug(b, "\t\t[atomic] previous state invalid; " @@ -1097,15 +1102,16 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, continue; head = to_drm_head(head_base); + connector_id = head->connector.connector_id; drm_debug(b, "\t\t[atomic] disabling inactive head %s\n", head_base->name); - info = &head->props_conn[WDRM_CONNECTOR_CRTC_ID]; - err = drmModeAtomicAddProperty(req, head->connector_id, + info = &head->connector.props[WDRM_CONNECTOR_CRTC_ID]; + err = drmModeAtomicAddProperty(req, connector_id, info->prop_id, 0); drm_debug(b, "\t\t\t[CONN:%lu] %lu (%s) -> 0\n", - (unsigned long) head->connector_id, + (unsigned long) connector_id, (unsigned long) info->prop_id, info->name); if (err <= 0) diff --git a/libweston/backend-drm/modes.c b/libweston/backend-drm/modes.c index 69611b08..2915aae6 100644 --- a/libweston/backend-drm/modes.c +++ b/libweston/backend-drm/modes.c @@ -120,19 +120,19 @@ drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode) } static bool -check_non_desktop(struct drm_head *head, drmModeObjectPropertiesPtr props) +check_non_desktop(struct drm_connector *connector, drmModeObjectPropertiesPtr props) { struct drm_property_info *non_desktop_info = - &head->props_conn[WDRM_CONNECTOR_NON_DESKTOP]; + &connector->props[WDRM_CONNECTOR_NON_DESKTOP]; return drm_property_get_value(non_desktop_info, props, 0); } static uint32_t -get_panel_orientation(struct drm_head *head, drmModeObjectPropertiesPtr props) +get_panel_orientation(struct drm_connector *connector, drmModeObjectPropertiesPtr props) { struct drm_property_info *orientation = - &head->props_conn[WDRM_CONNECTOR_PANEL_ORIENTATION]; + &connector->props[WDRM_CONNECTOR_PANEL_ORIENTATION]; uint64_t kms_val = drm_property_get_value(orientation, props, WDRM_PANEL_ORIENTATION_NORMAL); @@ -322,8 +322,9 @@ find_and_parse_output_edid(struct drm_head *head, int rc; blob_id = - drm_property_get_value(&head->props_conn[WDRM_CONNECTOR_EDID], - props, 0); + drm_property_get_value( + &head->connector.props[WDRM_CONNECTOR_EDID], + props, 0); if (!blob_id) return; @@ -509,6 +510,8 @@ void update_head_from_connector(struct drm_head *head, drmModeObjectProperties *props) { + struct drm_connector *connector = &head->connector; + drmModeConnector *conn = connector->conn; const char *make = "unknown"; const char *model = "unknown"; const char *serial_number = "unknown"; @@ -516,19 +519,18 @@ update_head_from_connector(struct drm_head *head, find_and_parse_output_edid(head, props, &make, &model, &serial_number); weston_head_set_monitor_strings(&head->base, make, model, serial_number); weston_head_set_non_desktop(&head->base, - check_non_desktop(head, props)); + check_non_desktop(connector, props)); weston_head_set_subpixel(&head->base, - drm_subpixel_to_wayland(head->connector->subpixel)); + drm_subpixel_to_wayland(conn->subpixel)); - weston_head_set_physical_size(&head->base, head->connector->mmWidth, - head->connector->mmHeight); + weston_head_set_physical_size(&head->base, conn->mmWidth, conn->mmHeight); weston_head_set_transform(&head->base, - get_panel_orientation(head, props)); + get_panel_orientation(connector, props)); /* Unknown connection status is assumed disconnected. */ weston_head_set_connection_status(&head->base, - head->connector->connection == DRM_MODE_CONNECTED); + conn->connection == DRM_MODE_CONNECTED); } /** @@ -757,6 +759,7 @@ drm_output_update_modelist_from_heads(struct drm_output *output) struct drm_backend *backend = to_drm_backend(output->base.compositor); struct weston_head *head_base; struct drm_head *head; + drmModeConnector *conn; int i; int ret; @@ -766,9 +769,9 @@ drm_output_update_modelist_from_heads(struct drm_output *output) wl_list_for_each(head_base, &output->base.head_list, output_link) { head = to_drm_head(head_base); - for (i = 0; i < head->connector->count_modes; i++) { - ret = drm_output_try_add_mode(output, - &head->connector->modes[i]); + conn = head->connector.conn; + for (i = 0; i < conn->count_modes; i++) { + ret = drm_output_try_add_mode(output, &conn->modes[i]); if (ret < 0) return -1; }