diff --git a/src/backends/native/meta-kms-connector-private.h b/src/backends/native/meta-kms-connector-private.h index 6ae8b18c3..3dd2b8440 100644 --- a/src/backends/native/meta-kms-connector-private.h +++ b/src/backends/native/meta-kms-connector-private.h @@ -48,7 +48,8 @@ typedef enum _MetaKmsConnectorDpms META_KMS_CONNECTOR_DPMS_STANDBY, META_KMS_CONNECTOR_DPMS_SUSPEND, META_KMS_CONNECTOR_DPMS_OFF, - META_KMS_CONNECTOR_DPMS_N_PROPS + META_KMS_CONNECTOR_DPMS_N_PROPS, + META_KMS_CONNECTOR_DPMS_UNKNOWN, } MetaKmsConnectorDpms; typedef enum _MetaKmsConnectorUnderscan @@ -56,7 +57,8 @@ typedef enum _MetaKmsConnectorUnderscan META_KMS_CONNECTOR_UNDERSCAN_OFF = 0, META_KMS_CONNECTOR_UNDERSCAN_ON, META_KMS_CONNECTOR_UNDERSCAN_AUTO, - META_KMS_CONNECTOR_UNDERSCAN_N_PROPS + META_KMS_CONNECTOR_UNDERSCAN_N_PROPS, + META_KMS_CONNECTOR_UNDERSCAN_UNKNOWN, } MetaKmsConnectorUnderscan; typedef enum _MetaKmsConnectorPrivacyScreen @@ -66,6 +68,7 @@ typedef enum _MetaKmsConnectorPrivacyScreen META_KMS_CONNECTOR_PRIVACY_SCREEN_ENABLED_LOCKED, META_KMS_CONNECTOR_PRIVACY_SCREEN_DISABLED_LOCKED, META_KMS_CONNECTOR_PRIVACY_SCREEN_N_PROPS, + META_KMS_CONNECTOR_PRIVACY_SCREEN_UNKNOWN, } MetaKmsConnectorPrivacyScreen; typedef enum _MetaKmsConnectorScalingMode @@ -75,6 +78,7 @@ typedef enum _MetaKmsConnectorScalingMode META_KMS_CONNECTOR_SCALING_MODE_CENTER, META_KMS_CONNECTOR_SCALING_MODE_FULL_ASPECT, META_KMS_CONNECTOR_SCALING_MODE_N_PROPS, + META_KMS_CONNECTOR_SCALING_MODE_UNKNOWN, } MetaKmsConnectorScalingMode; typedef enum _MetaKmsConnectorPanelOrientation @@ -84,6 +88,7 @@ typedef enum _MetaKmsConnectorPanelOrientation META_KMS_CONNECTOR_PANEL_ORIENTATION_LEFT_SIDE_UP, META_KMS_CONNECTOR_PANEL_ORIENTATION_RIGHT_SIDE_UP, META_KMS_CONNECTOR_PANEL_ORIENTATION_N_PROPS, + META_KMS_CONNECTOR_PANEL_ORIENTATION_UNKNOWN, } MetaKmsConnectorPanelOrientation; uint32_t meta_kms_connector_get_prop_id (MetaKmsConnector *connector, diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c index 6804fb6d3..b582dd4c6 100644 --- a/src/backends/native/meta-kms-connector.c +++ b/src/backends/native/meta-kms-connector.c @@ -868,6 +868,7 @@ init_properties (MetaKmsConnector *connector, .type = DRM_MODE_PROP_ENUM, .enum_values = prop_table->underscan_enum, .num_enum_values = META_KMS_CONNECTOR_UNDERSCAN_N_PROPS, + .default_value = META_KMS_CONNECTOR_UNDERSCAN_UNKNOWN, }, [META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER] = { @@ -885,6 +886,7 @@ init_properties (MetaKmsConnector *connector, .type = DRM_MODE_PROP_ENUM, .enum_values = prop_table->privacy_screen_sw_enum, .num_enum_values = META_KMS_CONNECTOR_PRIVACY_SCREEN_N_PROPS, + .default_value = META_KMS_CONNECTOR_PRIVACY_SCREEN_UNKNOWN, }, [META_KMS_CONNECTOR_PROP_PRIVACY_SCREEN_HW_STATE] = { @@ -892,6 +894,7 @@ init_properties (MetaKmsConnector *connector, .type = DRM_MODE_PROP_ENUM, .enum_values = prop_table->privacy_screen_hw_enum, .num_enum_values = META_KMS_CONNECTOR_PRIVACY_SCREEN_N_PROPS, + .default_value = META_KMS_CONNECTOR_PRIVACY_SCREEN_UNKNOWN, }, [META_KMS_CONNECTOR_PROP_EDID] = { @@ -924,6 +927,7 @@ init_properties (MetaKmsConnector *connector, .type = DRM_MODE_PROP_ENUM, .enum_values = prop_table->scaling_mode_enum, .num_enum_values = META_KMS_CONNECTOR_SCALING_MODE_N_PROPS, + .default_value = META_KMS_CONNECTOR_SCALING_MODE_UNKNOWN, }, [META_KMS_CONNECTOR_PROP_PANEL_ORIENTATION] = { @@ -931,6 +935,7 @@ init_properties (MetaKmsConnector *connector, .type = DRM_MODE_PROP_ENUM, .enum_values = prop_table->panel_orientation_enum, .num_enum_values = META_KMS_CONNECTOR_PANEL_ORIENTATION_N_PROPS, + .default_value = META_KMS_CONNECTOR_PANEL_ORIENTATION_UNKNOWN, }, [META_KMS_CONNECTOR_PROP_NON_DESKTOP] = { diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index ec1a0e5a4..4e0faab56 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -486,6 +486,122 @@ meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device, return plane; } +uint64_t +meta_kms_prop_convert_value (MetaKmsProp *prop, + uint64_t value) +{ + switch (prop->type) + { + case DRM_MODE_PROP_RANGE: + case DRM_MODE_PROP_SIGNED_RANGE: + case DRM_MODE_PROP_BLOB: + case DRM_MODE_PROP_OBJECT: + return value; + case DRM_MODE_PROP_ENUM: + g_assert (prop->enum_values[value].valid); + return prop->enum_values[value].value; + case DRM_MODE_PROP_BITMASK: + { + int i; + uint64_t result = 0; + + for (i = 0; i < prop->num_enum_values; i++) + { + if (!prop->enum_values[i].valid) + continue; + + if (value & prop->enum_values[i].bitmask) + { + result |= (1 << prop->enum_values[i].value); + value &= ~(prop->enum_values[i].bitmask); + } + } + + g_assert (value == 0); + return result; + } + default: + g_assert_not_reached (); + } + + return 0; +} + +static void +update_prop_value (MetaKmsProp *prop, + uint64_t drm_value) +{ + switch (prop->type) + { + case DRM_MODE_PROP_RANGE: + case DRM_MODE_PROP_SIGNED_RANGE: + case DRM_MODE_PROP_BLOB: + case DRM_MODE_PROP_OBJECT: + prop->value = drm_value; + return; + case DRM_MODE_PROP_ENUM: + { + int i; + + for (i = 0; i < prop->num_enum_values; i++) + { + if (prop->enum_values[i].valid && + prop->enum_values[i].value == drm_value) + { + prop->value = i; + return; + } + } + + prop->value = prop->default_value; + return; + } + case DRM_MODE_PROP_BITMASK: + { + int i; + uint64_t result = 0; + + for (i = 0; i < prop->num_enum_values; i++) + { + if (!prop->enum_values[i].valid) + continue; + + if (drm_value & (1 << prop->enum_values[i].value)) + { + result |= prop->enum_values[i].bitmask; + drm_value &= ~(1 << prop->enum_values[i].value); + } + } + if (drm_value != 0) + result |= prop->default_value; + + prop->value = result; + return; + } + default: + g_assert_not_reached (); + } +} + +static void +update_prop_enum_value(MetaKmsEnum *prop_enum, + drmModePropertyRes *drm_prop) +{ + int i; + + for (i = 0; i < drm_prop->count_enums; i++) + { + if (strcmp (prop_enum->name, drm_prop->enums[i].name) == 0) + { + prop_enum->value = drm_prop->enums[i].value; + prop_enum->valid = TRUE; + return; + } + } + + prop_enum->valid = FALSE; +} + static MetaKmsProp * find_prop (MetaKmsProp *props, int n_props, @@ -516,16 +632,35 @@ meta_kms_impl_device_init_prop_table (MetaKmsImplDevice *impl_device, gpointer user_data) { int fd; - uint32_t i; + uint32_t i, j; fd = meta_kms_impl_device_get_fd (impl_device); + for (i = 0; i < n_props; i++) + { + MetaKmsProp *prop = &props[i]; + + prop->prop_id = 0; + prop->value = 0; + + for (j = 0; j < prop->num_enum_values; j++) + { + prop->enum_values[j].valid = FALSE; + prop->enum_values[j].value = 0; + } + } + for (i = 0; i < n_drm_props; i++) { + uint32_t prop_id; + uint64_t prop_value; drmModePropertyRes *drm_prop; MetaKmsProp *prop; - drm_prop = drmModeGetProperty (fd, drm_props[i]); + prop_id = drm_props[i]; + prop_value = drm_prop_values[i]; + + drm_prop = drmModeGetProperty (fd, prop_id); if (!drm_prop) continue; @@ -540,17 +675,26 @@ meta_kms_impl_device_init_prop_table (MetaKmsImplDevice *impl_device, { g_warning ("DRM property '%s' (%u) had unexpected flags (0x%x), " "ignoring", - drm_prop->name, drm_props[i], drm_prop->flags); + drm_prop->name, prop_id, drm_prop->flags); drmModeFreeProperty (drm_prop); continue; } - prop->prop_id = drm_props[i]; + prop->prop_id = prop_id; + + if (prop->type == DRM_MODE_PROP_BITMASK || + prop->type == DRM_MODE_PROP_ENUM) + { + for (j = 0; j < prop->num_enum_values; j++) + update_prop_enum_value (&prop->enum_values[j], drm_prop); + } + + update_prop_value (prop, prop_value); if (prop->parse) { prop->parse (impl_device, prop, - drm_prop, drm_prop_values[i], + drm_prop, prop_value, user_data); } diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h index f50b1b637..015268f5a 100644 --- a/src/backends/native/meta-kms-impl-device.h +++ b/src/backends/native/meta-kms-impl-device.h @@ -62,6 +62,7 @@ struct _MetaKmsProp unsigned int num_enum_values; MetaKmsEnum *enum_values; + uint64_t default_value; uint32_t prop_id; uint64_t value; @@ -192,4 +193,7 @@ gboolean meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device void meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device); +uint64_t meta_kms_prop_convert_value (MetaKmsProp *prop, + uint64_t value); + #endif /* META_KMS_IMPL_DEVICE_H */ diff --git a/src/backends/native/meta-kms-plane-private.h b/src/backends/native/meta-kms-plane-private.h index 215a4754f..7dcb7f0c0 100644 --- a/src/backends/native/meta-kms-plane-private.h +++ b/src/backends/native/meta-kms-plane-private.h @@ -64,6 +64,7 @@ typedef enum _MetaKmsPlaneRotation META_KMS_PLANE_ROTATION_ROTATE_270 = (1 << 3), META_KMS_PLANE_ROTATION_REFLECT_X = (1 << 4), META_KMS_PLANE_ROTATION_REFLECT_Y = (1 << 5), + META_KMS_PLANE_ROTATION_UNKNOWN = (1 << 6), } MetaKmsPlaneRotation; MetaKmsPlane * meta_kms_plane_new (MetaKmsPlaneType type, diff --git a/src/backends/native/meta-kms-plane.c b/src/backends/native/meta-kms-plane.c index 6742ccd11..5ee163c1a 100644 --- a/src/backends/native/meta-kms-plane.c +++ b/src/backends/native/meta-kms-plane.c @@ -387,6 +387,7 @@ init_properties (MetaKmsPlane *plane, .type = DRM_MODE_PROP_BITMASK, .enum_values = prop_table->rotation_bitmask, .num_enum_values = META_KMS_PLANE_ROTATION_BIT_N_PROPS, + .default_value = META_KMS_PLANE_ROTATION_UNKNOWN, .parse = parse_rotations, }, [META_KMS_PLANE_PROP_IN_FORMATS] =