From 1406348be4c7cdbbc1f0481c120cad976ecad2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 26 Feb 2020 09:45:07 +0100 Subject: [PATCH] output: Move output info to MetaOutputInfo struct The output info is established during construction and will stay the same for the lifetime of the MetaOutput object. Moving it out of the main struct enables us to eventually clean up the MetaOutput type inheritence to use proper GObject types. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287 --- src/backends/meta-gpu.c | 3 +- src/backends/meta-monitor-config-manager.c | 11 +- src/backends/meta-monitor-manager-dummy.c | 109 ++++---- src/backends/meta-monitor-manager.c | 143 ++++++---- src/backends/meta-monitor.c | 231 +++++++++------- src/backends/meta-output.c | 99 ++++++- src/backends/meta-output.h | 39 ++- src/backends/native/meta-gpu-kms.c | 16 +- src/backends/native/meta-output-kms.c | 136 +++++----- src/backends/x11/meta-gpu-xrandr.c | 14 +- src/backends/x11/meta-output-xrandr.c | 296 ++++++++++++--------- src/tests/headless-start-test.c | 26 +- src/tests/monitor-test-utils.c | 70 ++--- 13 files changed, 705 insertions(+), 488 deletions(-) diff --git a/src/backends/meta-gpu.c b/src/backends/meta-gpu.c index cc67fa718..ce4353bf0 100644 --- a/src/backends/meta-gpu.c +++ b/src/backends/meta-gpu.c @@ -57,8 +57,9 @@ meta_gpu_has_hotplug_mode_update (MetaGpu *gpu) for (l = priv->outputs; l; l = l->next) { MetaOutput *output = l->data; + const MetaOutputInfo *output_info = meta_output_get_info (output); - if (output->hotplug_mode_update) + if (output_info->hotplug_mode_update) return TRUE; } diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c index cb11eba71..55053276b 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -118,16 +118,19 @@ find_unassigned_crtc (MetaOutput *output, GArray *reserved_crtcs) { MetaCrtc *crtc; + const MetaOutputInfo *output_info; unsigned int i; crtc = meta_output_get_assigned_crtc (output); if (crtc && !is_crtc_assigned (crtc, crtc_assignments)) return crtc; + output_info = meta_output_get_info (output); + /* then try to assign a CRTC that wasn't used */ - for (i = 0; i < output->n_possible_crtcs; i++) + for (i = 0; i < output_info->n_possible_crtcs; i++) { - crtc = output->possible_crtcs[i]; + crtc = output_info->possible_crtcs[i]; if (is_crtc_assigned (crtc, crtc_assignments)) continue; @@ -139,9 +142,9 @@ find_unassigned_crtc (MetaOutput *output, } /* finally just give a CRTC that we haven't assigned */ - for (i = 0; i < output->n_possible_crtcs; i++) + for (i = 0; i < output_info->n_possible_crtcs; i++) { - crtc = output->possible_crtcs[i]; + crtc = output_info->possible_crtcs[i]; if (is_crtc_assigned (crtc, crtc_assignments)) continue; diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c index d7f07b012..6547f9dcd 100644 --- a/src/backends/meta-monitor-manager-dummy.c +++ b/src/backends/meta-monitor-manager-dummy.c @@ -142,6 +142,7 @@ append_monitor (MetaMonitorManager *manager, MetaOutput *output; unsigned int i; unsigned int number; + g_autoptr (MetaOutputInfo) output_info = NULL; const char *mode_specs_str; GList *l; @@ -207,44 +208,46 @@ append_monitor (MetaMonitorManager *manager, number = g_list_length (*outputs) + 1; + output_info = meta_output_info_new (); + output_info->name = g_strdup_printf ("LVDS%d", number); + output_info->vendor = g_strdup ("MetaProducts Inc."); + output_info->product = g_strdup ("MetaMonitor"); + output_info->serial = g_strdup_printf ("0xC0FFEE-%d", number); + output_info->suggested_x = -1; + output_info->suggested_y = -1; + output_info->width_mm = 222; + output_info->height_mm = 125; + output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + output_info->preferred_mode = g_list_last (*modes)->data; + output_info->n_possible_clones = 0; + output_info->connector_type = META_CONNECTOR_TYPE_LVDS; + + output_info->modes = g_new0 (MetaCrtcMode *, n_mode_specs); + for (l = new_modes, i = 0; l; l = l->next, i++) + { + MetaCrtcMode *mode = l->data; + + output_info->modes[i] = mode; + } + output_info->n_modes = n_mode_specs; + output_info->possible_crtcs = g_new0 (MetaCrtc *, 1); + output_info->possible_crtcs[0] = g_list_last (*crtcs)->data; + output_info->n_possible_crtcs = 1; + output = g_object_new (META_TYPE_OUTPUT, "id", number, "gpu", gpu, + "info", output_info, NULL); output_dummy = g_new0 (MetaOutputDummy, 1); *output_dummy = (MetaOutputDummy) { .scale = scale }; - - output->name = g_strdup_printf ("LVDS%d", number); - output->vendor = g_strdup ("MetaProducts Inc."); - output->product = g_strdup ("MetaMonitor"); - output->serial = g_strdup_printf ("0xC0FFEE-%d", number); - output->suggested_x = -1; - output->suggested_y = -1; - output->width_mm = 222; - output->height_mm = 125; - output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; - output->preferred_mode = g_list_last (*modes)->data; - output->n_possible_clones = 0; - output->connector_type = META_CONNECTOR_TYPE_LVDS; output->driver_private = output_dummy; output->driver_notify = (GDestroyNotify) meta_output_dummy_notify_destroy; - output->modes = g_new0 (MetaCrtcMode *, n_mode_specs); - for (l = new_modes, i = 0; l; l = l->next, i++) - { - MetaCrtcMode *mode = l->data; - - output->modes[i] = mode; - } - output->n_modes = n_mode_specs; - output->possible_crtcs = g_new0 (MetaCrtc *, 1); - output->possible_crtcs[0] = g_list_last (*crtcs)->data; - output->n_possible_crtcs = 1; - *outputs = g_list_append (*outputs, output); } @@ -307,6 +310,7 @@ append_tiled_monitor (MetaMonitorManager *manager, MetaCrtcMode *preferred_mode; unsigned int j; unsigned int number; + g_autoptr (MetaOutputInfo) output_info = NULL; GList *l; output_dummy = g_new0 (MetaOutputDummy, 1); @@ -319,24 +323,21 @@ append_tiled_monitor (MetaMonitorManager *manager, preferred_mode = g_list_last (*modes)->data; - output = g_object_new (META_TYPE_OUTPUT, - "id", number, - "gpu", gpu, - NULL); + output_info = meta_output_info_new (); - output->name = g_strdup_printf ("LVDS%d", number); - output->vendor = g_strdup ("MetaProducts Inc."); - output->product = g_strdup ("MetaMonitor"); - output->serial = g_strdup_printf ("0xC0FFEE-%d", number); - output->suggested_x = -1; - output->suggested_y = -1; - output->width_mm = 222; - output->height_mm = 125; - output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; - output->preferred_mode = preferred_mode; - output->n_possible_clones = 0; - output->connector_type = META_CONNECTOR_TYPE_LVDS; - output->tile_info = (MetaTileInfo) { + output_info->name = g_strdup_printf ("LVDS%d", number); + output_info->vendor = g_strdup ("MetaProducts Inc."); + output_info->product = g_strdup ("MetaMonitor"); + output_info->serial = g_strdup_printf ("0xC0FFEE-%d", number); + output_info->suggested_x = -1; + output_info->suggested_y = -1; + output_info->width_mm = 222; + output_info->height_mm = 125; + output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + output_info->preferred_mode = preferred_mode; + output_info->n_possible_clones = 0; + output_info->connector_type = META_CONNECTOR_TYPE_LVDS; + output_info->tile_info = (MetaTileInfo) { .group_id = tile_group_id, .max_h_tiles = n_tiles, .max_v_tiles = 1, @@ -345,27 +346,33 @@ append_tiled_monitor (MetaMonitorManager *manager, .tile_w = preferred_mode->width, .tile_h = preferred_mode->height }, - output->driver_private = output_dummy; - output->driver_notify = - (GDestroyNotify) meta_output_dummy_notify_destroy; - output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs)); + output_info->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs)); for (l = new_modes, j = 0; l; l = l->next, j++) { MetaCrtcMode *mode = l->data; - output->modes[j] = mode; + output_info->modes[j] = mode; } - output->n_modes = G_N_ELEMENTS (mode_specs); + output_info->n_modes = G_N_ELEMENTS (mode_specs); - output->possible_crtcs = g_new0 (MetaCrtc *, n_tiles); + output_info->possible_crtcs = g_new0 (MetaCrtc *, n_tiles); for (l = new_crtcs, j = 0; l; l = l->next, j++) { MetaCrtc *crtc = l->data; - output->possible_crtcs[j] = crtc; + output_info->possible_crtcs[j] = crtc; } - output->n_possible_crtcs = n_tiles; + output_info->n_possible_crtcs = n_tiles; + + output = g_object_new (META_TYPE_OUTPUT, + "id", number, + "gpu", gpu, + "info", output_info, + NULL); + output->driver_private = output_dummy; + output->driver_notify = + (GDestroyNotify) meta_output_dummy_notify_destroy; *outputs = g_list_append (*outputs, output); } diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index aba071f25..d76e4348b 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -140,7 +140,10 @@ meta_monitor_manager_set_primary_logical_monitor (MetaMonitorManager *manager, static gboolean is_main_tiled_monitor_output (MetaOutput *output) { - return output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0; + const MetaOutputInfo *output_info = meta_output_get_info (output); + + return (output_info->tile_info.loc_h_tile == 0 && + output_info->tile_info.loc_v_tile == 0); } static MetaLogicalMonitor * @@ -1059,15 +1062,23 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, for (l = combined_outputs, i = 0; l; l = l->next, i++) { MetaOutput *output = l->data; + const MetaOutputInfo *output_info = meta_output_get_info (output); GVariantBuilder crtcs, modes, clones, properties; GBytes *edid; MetaCrtc *crtc; int crtc_index; + int backlight; + int min_backlight_step; + gboolean is_primary; + gboolean is_presentation; + const char * connector_type_name; + gboolean is_underscanning; + gboolean supports_underscanning; g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au")); - for (j = 0; j < output->n_possible_crtcs; j++) + for (j = 0; j < output_info->n_possible_crtcs; j++) { - MetaCrtc *possible_crtc = output->possible_crtcs[j]; + MetaCrtc *possible_crtc = output_info->possible_crtcs[j]; unsigned possible_crtc_index; possible_crtc_index = g_list_index (combined_crtcs, possible_crtc); @@ -1075,52 +1086,62 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, } g_variant_builder_init (&modes, G_VARIANT_TYPE ("au")); - for (j = 0; j < output->n_modes; j++) + for (j = 0; j < output_info->n_modes; j++) { unsigned mode_index; - mode_index = g_list_index (combined_modes, output->modes[j]); + mode_index = g_list_index (combined_modes, output_info->modes[j]); g_variant_builder_add (&modes, "u", mode_index); } g_variant_builder_init (&clones, G_VARIANT_TYPE ("au")); - for (j = 0; j < output->n_possible_clones; j++) + for (j = 0; j < output_info->n_possible_clones; j++) { unsigned int possible_clone_index; possible_clone_index = g_list_index (combined_outputs, - output->possible_clones[j]); + output_info->possible_clones[j]); g_variant_builder_add (&clones, "u", possible_clone_index); } + backlight = meta_output_get_backlight (output); + min_backlight_step = + output_info->backlight_max - output_info->backlight_min + ? 100 / (output_info->backlight_max - output_info->backlight_min) + : -1; + is_primary = meta_output_is_primary (output); + is_presentation = meta_output_is_presentation (output); + is_underscanning = meta_output_is_underscanning (output); + connector_type_name = get_connector_type_name (output_info->connector_type); + supports_underscanning = output_info->supports_underscanning; + g_variant_builder_init (&properties, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&properties, "{sv}", "vendor", - g_variant_new_string (output->vendor)); + g_variant_new_string (output_info->vendor)); g_variant_builder_add (&properties, "{sv}", "product", - g_variant_new_string (output->product)); + g_variant_new_string (output_info->product)); g_variant_builder_add (&properties, "{sv}", "serial", - g_variant_new_string (output->serial)); + g_variant_new_string (output_info->serial)); g_variant_builder_add (&properties, "{sv}", "width-mm", - g_variant_new_int32 (output->width_mm)); + g_variant_new_int32 (output_info->width_mm)); g_variant_builder_add (&properties, "{sv}", "height-mm", - g_variant_new_int32 (output->height_mm)); + g_variant_new_int32 (output_info->height_mm)); g_variant_builder_add (&properties, "{sv}", "display-name", - g_variant_new_string (output->name)); + g_variant_new_string (output_info->name)); g_variant_builder_add (&properties, "{sv}", "backlight", - g_variant_new_int32 (meta_output_get_backlight (output))); + g_variant_new_int32 (backlight)); g_variant_builder_add (&properties, "{sv}", "min-backlight-step", - g_variant_new_int32 ((output->backlight_max - output->backlight_min) ? - 100 / (output->backlight_max - output->backlight_min) : -1)); + g_variant_new_int32 (min_backlight_step)); g_variant_builder_add (&properties, "{sv}", "primary", - g_variant_new_boolean (meta_output_is_primary (output))); + g_variant_new_boolean (is_primary)); g_variant_builder_add (&properties, "{sv}", "presentation", - g_variant_new_boolean (meta_output_is_presentation (output))); + g_variant_new_boolean (is_presentation)); g_variant_builder_add (&properties, "{sv}", "connector-type", - g_variant_new_string (get_connector_type_name (output->connector_type))); + g_variant_new_string (connector_type_name)); g_variant_builder_add (&properties, "{sv}", "underscanning", - g_variant_new_boolean (meta_output_is_underscanning (output))); + g_variant_new_boolean (is_underscanning)); g_variant_builder_add (&properties, "{sv}", "supports-underscanning", - g_variant_new_boolean (output->supports_underscanning)); + g_variant_new_boolean (supports_underscanning)); edid = manager_class->read_edid (manager, output); if (edid) @@ -1131,18 +1152,20 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, g_bytes_unref (edid); } - if (output->tile_info.group_id) + if (output_info->tile_info.group_id) { - g_variant_builder_add (&properties, "{sv}", "tile", - g_variant_new ("(uuuuuuuu)", - output->tile_info.group_id, - output->tile_info.flags, - output->tile_info.max_h_tiles, - output->tile_info.max_v_tiles, - output->tile_info.loc_h_tile, - output->tile_info.loc_v_tile, - output->tile_info.tile_w, - output->tile_info.tile_h)); + GVariant *tile_variant; + + tile_variant = g_variant_new ("(uuuuuuuu)", + output_info->tile_info.group_id, + output_info->tile_info.flags, + output_info->tile_info.max_h_tiles, + output_info->tile_info.max_v_tiles, + output_info->tile_info.loc_h_tile, + output_info->tile_info.loc_v_tile, + output_info->tile_info.tile_w, + output_info->tile_info.tile_h); + g_variant_builder_add (&properties, "{sv}", "tile", tile_variant); } crtc = meta_output_get_assigned_crtc (output); @@ -1152,7 +1175,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, meta_output_get_id (output), crtc_index, &crtcs, - output->name, + meta_output_get_name (output), &modes, &clones, &properties); @@ -2103,6 +2126,7 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton, { GList *combined_outputs; MetaOutput *output; + const MetaOutputInfo *output_info; int new_backlight; if (serial != manager->serial) @@ -2134,8 +2158,10 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton, return TRUE; } + output_info = meta_output_get_info (output); if (meta_output_get_backlight (output) == -1 || - (output->backlight_min == 0 && output->backlight_max == 0)) + (output_info->backlight_min == 0 && + output_info->backlight_max == 0)) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, @@ -2653,8 +2679,9 @@ rebuild_monitors (MetaMonitorManager *manager) for (k = meta_gpu_get_outputs (gpu); k; k = k->next) { MetaOutput *output = k->data; + const MetaOutputInfo *output_info = meta_output_get_info (output); - if (output->tile_info.group_id) + if (output_info->tile_info.group_id) { if (is_main_tiled_monitor_output (output)) { @@ -2886,8 +2913,8 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager, } void -meta_output_parse_edid (MetaOutput *output, - GBytes *edid) +meta_output_info_parse_edid (MetaOutputInfo *output_info, + GBytes *edid) { MonitorInfo *parsed_edid; gsize len; @@ -2899,42 +2926,44 @@ meta_output_parse_edid (MetaOutput *output, if (parsed_edid) { - output->vendor = g_strndup (parsed_edid->manufacturer_code, 4); - if (!g_utf8_validate (output->vendor, -1, NULL)) - g_clear_pointer (&output->vendor, g_free); + output_info->vendor = g_strndup (parsed_edid->manufacturer_code, 4); + if (!g_utf8_validate (output_info->vendor, -1, NULL)) + g_clear_pointer (&output_info->vendor, g_free); - output->product = g_strndup (parsed_edid->dsc_product_name, 14); - if (!g_utf8_validate (output->product, -1, NULL) || - output->product[0] == '\0') + output_info->product = g_strndup (parsed_edid->dsc_product_name, 14); + if (!g_utf8_validate (output_info->product, -1, NULL) || + output_info->product[0] == '\0') { - g_clear_pointer (&output->product, g_free); - output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code); + g_clear_pointer (&output_info->product, g_free); + output_info->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code); } - output->serial = g_strndup (parsed_edid->dsc_serial_number, 14); - if (!g_utf8_validate (output->serial, -1, NULL) || - output->serial[0] == '\0') + output_info->serial = g_strndup (parsed_edid->dsc_serial_number, 14); + if (!g_utf8_validate (output_info->serial, -1, NULL) || + output_info->serial[0] == '\0') { - g_clear_pointer (&output->serial, g_free); - output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number); + g_clear_pointer (&output_info->serial, g_free); + output_info->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number); } g_free (parsed_edid); } out: - if (!output->vendor) - output->vendor = g_strdup ("unknown"); - if (!output->product) - output->product = g_strdup ("unknown"); - if (!output->serial) - output->serial = g_strdup ("unknown"); + if (!output_info->vendor) + output_info->vendor = g_strdup ("unknown"); + if (!output_info->product) + output_info->product = g_strdup ("unknown"); + if (!output_info->serial) + output_info->serial = g_strdup ("unknown"); } gboolean meta_output_is_laptop (MetaOutput *output) { - switch (output->connector_type) + const MetaOutputInfo *output_info = meta_output_get_info (output); + + switch (output_info->connector_type) { case META_CONNECTOR_TYPE_eDP: case META_CONNECTOR_TYPE_LVDS: diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c index c6817d470..5887b6e16 100644 --- a/src/backends/meta-monitor.c +++ b/src/backends/meta-monitor.c @@ -168,19 +168,28 @@ meta_monitor_spec_free (MetaMonitorSpec *monitor_spec) g_free (monitor_spec); } +static const MetaOutputInfo * +meta_monitor_get_main_output_info (MetaMonitor *monitor) +{ + MetaOutput *output = meta_monitor_get_main_output (monitor); + + return meta_output_get_info (output); +} + static void meta_monitor_generate_spec (MetaMonitor *monitor) { MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); - MetaOutput *output = meta_monitor_get_main_output (monitor); + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); MetaMonitorSpec *monitor_spec; monitor_spec = g_new0 (MetaMonitorSpec, 1); *monitor_spec = (MetaMonitorSpec) { - .connector = g_strdup (output->name), - .vendor = g_strdup (output->vendor), - .product = g_strdup (output->product), - .serial = g_strdup (output->serial), + .connector = g_strdup (output_info->name), + .vendor = g_strdup (output_info->vendor), + .product = g_strdup (output_info->product), + .serial = g_strdup (output_info->serial), }; priv->spec = monitor_spec; @@ -322,11 +331,10 @@ meta_monitor_is_primary (MetaMonitor *monitor) gboolean meta_monitor_supports_underscanning (MetaMonitor *monitor) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - - return output->supports_underscanning; + return output_info->supports_underscanning; } gboolean @@ -342,11 +350,10 @@ meta_monitor_is_underscanning (MetaMonitor *monitor) gboolean meta_monitor_is_laptop_panel (MetaMonitor *monitor) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - - switch (output->connector_type) + switch (output_info->connector_type) { case META_CONNECTOR_TYPE_eDP: case META_CONNECTOR_TYPE_LVDS: @@ -392,65 +399,65 @@ meta_monitor_get_physical_dimensions (MetaMonitor *monitor, int *width_mm, int *height_mm) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - *width_mm = output->width_mm; - *height_mm = output->height_mm; + *width_mm = output_info->width_mm; + *height_mm = output_info->height_mm; } CoglSubpixelOrder meta_monitor_get_subpixel_order (MetaMonitor *monitor) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - return output->subpixel_order; + return output_info->subpixel_order; } const char * meta_monitor_get_connector (MetaMonitor *monitor) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - return output->name; + return output_info->name; } const char * meta_monitor_get_vendor (MetaMonitor *monitor) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - return output->vendor; + return output_info->vendor; } const char * meta_monitor_get_product (MetaMonitor *monitor) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - return output->product; + return output_info->product; } const char * meta_monitor_get_serial (MetaMonitor *monitor) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - return output->serial; + return output_info->serial; } MetaConnectorType meta_monitor_get_connector_type (MetaMonitor *monitor) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - return output->connector_type; + return output_info->connector_type; } MetaMonitorTransform @@ -562,9 +569,10 @@ meta_monitor_create_spec (MetaMonitor *monitor, int height, MetaCrtcMode *crtc_mode) { - MetaOutput *output = meta_monitor_get_main_output (monitor); + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - if (meta_monitor_transform_is_rotated (output->panel_orientation_transform)) + if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform)) { int temp = width; width = height; @@ -586,15 +594,17 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal) MetaMonitorPrivate *monitor_priv = meta_monitor_get_instance_private (monitor); MetaOutput *output; + const MetaOutputInfo *output_info; MetaCrtcModeFlag preferred_mode_flags; unsigned int i; output = meta_monitor_get_main_output (monitor); - preferred_mode_flags = output->preferred_mode->flags; + output_info = meta_output_get_info (output); + preferred_mode_flags = output_info->preferred_mode->flags; - for (i = 0; i < output->n_modes; i++) + for (i = 0; i < output_info->n_modes; i++) { - MetaCrtcMode *crtc_mode = output->modes[i]; + MetaCrtcMode *crtc_mode = output_info->modes[i]; MetaCrtc *crtc; MetaMonitorMode *mode; gboolean replace; @@ -623,12 +633,12 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal) if (!meta_monitor_add_mode (monitor, mode, replace)) { - g_assert (crtc_mode != output->preferred_mode); + g_assert (crtc_mode != output_info->preferred_mode); meta_monitor_mode_free (mode); continue; } - if (crtc_mode == output->preferred_mode) + if (crtc_mode == output_info->preferred_mode) monitor_priv->preferred_mode = mode; crtc = meta_output_get_assigned_crtc (output); @@ -697,14 +707,14 @@ meta_monitor_normal_get_suggested_position (MetaMonitor *monitor, int *x, int *y) { - MetaOutput *output; + const MetaOutputInfo *output_info = + meta_monitor_get_main_output_info (monitor); - output = meta_monitor_get_main_output (monitor); - if (output->suggested_x < 0 && output->suggested_y < 0) + if (output_info->suggested_x < 0 && output_info->suggested_y < 0) return FALSE; - *x = output->suggested_x; - *y = output->suggested_y; + *x = output_info->suggested_x; + *y = output_info->suggested_y; return TRUE; } @@ -765,12 +775,15 @@ add_tiled_monitor_outputs (MetaGpu *gpu, for (l = outputs; l; l = l->next) { MetaOutput *output = l->data; + const MetaOutputInfo *output_info = meta_output_get_info (output); + const MetaOutputInfo *origin_output_info; - if (output->tile_info.group_id != monitor_tiled->tile_group_id) + if (output_info->tile_info.group_id != monitor_tiled->tile_group_id) continue; - g_warn_if_fail (output->subpixel_order == - monitor_tiled->origin_output->subpixel_order); + origin_output_info = meta_output_get_info (monitor_tiled->origin_output); + g_warn_if_fail (output_info->subpixel_order == + origin_output_info->subpixel_order); monitor_priv->outputs = g_list_append (monitor_priv->outputs, g_object_ref (output)); @@ -786,51 +799,68 @@ calculate_tile_coordinate (MetaMonitor *monitor, { MetaMonitorPrivate *monitor_priv = meta_monitor_get_instance_private (monitor); + const MetaOutputInfo *output_info = meta_output_get_info (output); GList *l; int x = 0; int y = 0; for (l = monitor_priv->outputs; l; l = l->next) { - MetaOutput *other_output = l->data; + const MetaOutputInfo *other_output_info = meta_output_get_info (l->data); switch (crtc_transform) { case META_MONITOR_TRANSFORM_NORMAL: case META_MONITOR_TRANSFORM_FLIPPED: - if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && - other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile) - x += other_output->tile_info.tile_w; - if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && - other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile) - y += other_output->tile_info.tile_h; + if ((other_output_info->tile_info.loc_v_tile == + output_info->tile_info.loc_v_tile) && + (other_output_info->tile_info.loc_h_tile < + output_info->tile_info.loc_h_tile)) + x += other_output_info->tile_info.tile_w; + if ((other_output_info->tile_info.loc_h_tile == + output_info->tile_info.loc_h_tile) && + (other_output_info->tile_info.loc_v_tile < + output_info->tile_info.loc_v_tile)) + y += other_output_info->tile_info.tile_h; break; case META_MONITOR_TRANSFORM_180: case META_MONITOR_TRANSFORM_FLIPPED_180: - if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && - other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile) - x += other_output->tile_info.tile_w; - if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && - other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile) - y += other_output->tile_info.tile_h; + if ((other_output_info->tile_info.loc_v_tile == + output_info->tile_info.loc_v_tile) && + (other_output_info->tile_info.loc_h_tile > + output_info->tile_info.loc_h_tile)) + x += other_output_info->tile_info.tile_w; + if ((other_output_info->tile_info.loc_h_tile == + output_info->tile_info.loc_h_tile) && + (other_output_info->tile_info.loc_v_tile > + output_info->tile_info.loc_v_tile)) + y += other_output_info->tile_info.tile_h; break; case META_MONITOR_TRANSFORM_270: case META_MONITOR_TRANSFORM_FLIPPED_270: - if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && - other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile) - y += other_output->tile_info.tile_w; - if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && - other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile) - x += other_output->tile_info.tile_h; + if ((other_output_info->tile_info.loc_v_tile == + output_info->tile_info.loc_v_tile) && + (other_output_info->tile_info.loc_h_tile > + output_info->tile_info.loc_h_tile)) + y += other_output_info->tile_info.tile_w; + if ((other_output_info->tile_info.loc_h_tile == + output_info->tile_info.loc_h_tile) && + (other_output_info->tile_info.loc_v_tile > + output_info->tile_info.loc_v_tile)) + x += other_output_info->tile_info.tile_h; break; case META_MONITOR_TRANSFORM_90: case META_MONITOR_TRANSFORM_FLIPPED_90: - if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && - other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile) - y += other_output->tile_info.tile_w; - if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && - other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile) - x += other_output->tile_info.tile_h; + if ((other_output_info->tile_info.loc_v_tile == + output_info->tile_info.loc_v_tile) && + (other_output_info->tile_info.loc_h_tile < + output_info->tile_info.loc_h_tile)) + y += other_output_info->tile_info.tile_w; + if ((other_output_info->tile_info.loc_h_tile == + output_info->tile_info.loc_h_tile) && + (other_output_info->tile_info.loc_v_tile < + output_info->tile_info.loc_v_tile)) + x += other_output_info->tile_info.tile_h; break; } } @@ -854,13 +884,13 @@ meta_monitor_tiled_calculate_tiled_size (MetaMonitor *monitor, height = 0; for (l = monitor_priv->outputs; l; l = l->next) { - MetaOutput *output = l->data; + const MetaOutputInfo *output_info = meta_output_get_info (l->data); - if (output->tile_info.loc_v_tile == 0) - width += output->tile_info.tile_w; + if (output_info->tile_info.loc_v_tile == 0) + width += output_info->tile_info.tile_w; - if (output->tile_info.loc_h_tile == 0) - height += output->tile_info.tile_h; + if (output_info->tile_info.loc_h_tile == 0) + height += output_info->tile_info.tile_h; } *out_width = width; @@ -897,24 +927,27 @@ static gboolean is_crtc_mode_tiled (MetaOutput *output, MetaCrtcMode *crtc_mode) { - return (crtc_mode->width == (int) output->tile_info.tile_w && - crtc_mode->height == (int) output->tile_info.tile_h); + const MetaOutputInfo *output_info = meta_output_get_info (output); + + return (crtc_mode->width == (int) output_info->tile_info.tile_w && + crtc_mode->height == (int) output_info->tile_info.tile_h); } static MetaCrtcMode * find_tiled_crtc_mode (MetaOutput *output, MetaCrtcMode *reference_crtc_mode) { + const MetaOutputInfo *output_info = meta_output_get_info (output); MetaCrtcMode *crtc_mode; unsigned int i; - crtc_mode = output->preferred_mode; + crtc_mode = output_info->preferred_mode; if (is_crtc_mode_tiled (output, crtc_mode)) return crtc_mode; - for (i = 0; i < output->n_modes; i++) + for (i = 0; i < output_info->n_modes; i++) { - crtc_mode = output->modes[i]; + crtc_mode = output_info->modes[i]; if (!is_crtc_mode_tiled (output, crtc_mode)) continue; @@ -958,12 +991,13 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled, for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) { MetaOutput *output = l->data; + const MetaOutputInfo *output_info = meta_output_get_info (output); MetaCrtcMode *tiled_crtc_mode; tiled_crtc_mode = find_tiled_crtc_mode (output, reference_crtc_mode); if (!tiled_crtc_mode) { - g_warning ("No tiled mode found on %s", output->name); + g_warning ("No tiled mode found on %s", meta_output_get_name (output)); meta_monitor_mode_free ((MetaMonitorMode *) mode); return NULL; } @@ -973,7 +1007,8 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled, .crtc_mode = tiled_crtc_mode }; - is_preferred = is_preferred && tiled_crtc_mode == output->preferred_mode; + is_preferred = (is_preferred && + tiled_crtc_mode == output_info->preferred_mode); } *out_is_preferred = is_preferred; @@ -988,16 +1023,18 @@ generate_tiled_monitor_modes (MetaMonitorTiled *monitor_tiled) MetaMonitorPrivate *monitor_priv = meta_monitor_get_instance_private (monitor); MetaOutput *main_output; + const MetaOutputInfo *main_output_info; GList *tiled_modes = NULL; unsigned int i; MetaMonitorMode *best_mode = NULL; GList *l; main_output = meta_monitor_get_main_output (META_MONITOR (monitor_tiled)); + main_output_info = meta_output_get_info (main_output); - for (i = 0; i < main_output->n_modes; i++) + for (i = 0; i < main_output_info->n_modes; i++) { - MetaCrtcMode *reference_crtc_mode = main_output->modes[i]; + MetaCrtcMode *reference_crtc_mode = main_output_info->modes[i]; MetaMonitorMode *mode; gboolean is_preferred; @@ -1094,13 +1131,14 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled, static int count_untiled_crtc_modes (MetaOutput *output) { + const MetaOutputInfo *output_info = meta_output_get_info (output); int count; unsigned int i; count = 0; - for (i = 0; i < output->n_modes; i++) + for (i = 0; i < output_info->n_modes; i++) { - MetaCrtcMode *crtc_mode = output->modes[i]; + MetaCrtcMode *crtc_mode = output_info->modes[i]; if (!is_crtc_mode_tiled (output, crtc_mode)) count++; @@ -1149,13 +1187,15 @@ generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled) MetaMonitorPrivate *monitor_priv = meta_monitor_get_instance_private (monitor); MetaOutput *main_output; + const MetaOutputInfo *main_output_info; unsigned int i; main_output = meta_monitor_get_main_output (monitor); + main_output_info = meta_output_get_info (main_output); - for (i = 0; i < main_output->n_modes; i++) + for (i = 0; i < main_output_info->n_modes; i++) { - MetaCrtcMode *crtc_mode = main_output->modes[i]; + MetaCrtcMode *crtc_mode = main_output_info->modes[i]; MetaMonitorMode *mode; mode = create_untiled_monitor_mode (monitor_tiled, @@ -1177,7 +1217,7 @@ generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled) } if (!monitor_priv->preferred_mode && - crtc_mode == main_output->preferred_mode) + crtc_mode == main_output_info->preferred_mode) monitor_priv->preferred_mode = mode; } } @@ -1281,6 +1321,7 @@ meta_monitor_tiled_new (MetaGpu *gpu, MetaMonitorManager *monitor_manager, MetaOutput *output) { + const MetaOutputInfo *output_info = meta_output_get_info (output); MetaMonitorTiled *monitor_tiled; MetaMonitor *monitor; MetaMonitorPrivate *monitor_priv; @@ -1291,7 +1332,7 @@ meta_monitor_tiled_new (MetaGpu *gpu, monitor_priv->gpu = gpu; - monitor_tiled->tile_group_id = output->tile_info.group_id; + monitor_tiled->tile_group_id = output_info->tile_info.group_id; monitor_priv->winsys_id = meta_output_get_id (output); monitor_tiled->origin_output = output; diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c index 4e6e1f197..55ac61c76 100644 --- a/src/backends/meta-output.c +++ b/src/backends/meta-output.c @@ -27,6 +27,7 @@ enum PROP_ID, PROP_GPU, + PROP_INFO, N_PROPS }; @@ -39,6 +40,8 @@ typedef struct _MetaOutputPrivate MetaGpu *gpu; + MetaOutputInfo *info; + /* The CRTC driving this output, NULL if the output is not enabled */ MetaCrtc *crtc; @@ -52,6 +55,44 @@ typedef struct _MetaOutputPrivate G_DEFINE_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT) +G_DEFINE_BOXED_TYPE (MetaOutputInfo, meta_output_info, + meta_output_info_ref, + meta_output_info_unref) + +MetaOutputInfo * +meta_output_info_new (void) +{ + MetaOutputInfo *output_info; + + output_info = g_new0 (MetaOutputInfo, 1); + g_ref_count_init (&output_info->ref_count); + + return output_info; +} + +MetaOutputInfo * +meta_output_info_ref (MetaOutputInfo *output_info) +{ + g_ref_count_inc (&output_info->ref_count); + return output_info; +} + +void +meta_output_info_unref (MetaOutputInfo *output_info) +{ + if (g_ref_count_dec (&output_info->ref_count)) + { + g_free (output_info->name); + g_free (output_info->vendor); + g_free (output_info->product); + g_free (output_info->serial); + g_free (output_info->modes); + g_free (output_info->possible_crtcs); + g_free (output_info->possible_clones); + g_free (output_info); + } +} + uint64_t meta_output_get_id (MetaOutput *output) { @@ -71,7 +112,9 @@ meta_output_get_gpu (MetaOutput *output) const char * meta_output_get_name (MetaOutput *output) { - return output->name; + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + + return priv->info->name; } gboolean @@ -115,6 +158,29 @@ meta_output_get_backlight (MetaOutput *output) return priv->backlight; } +void +meta_output_add_possible_clone (MetaOutput *output, + MetaOutput *possible_clone) +{ + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + MetaOutputInfo *output_info = priv->info; + + output_info->n_possible_clones++; + output_info->possible_clones = g_renew (MetaOutput *, + output_info->possible_clones, + output_info->n_possible_clones); + output_info->possible_clones[output_info->n_possible_clones - 1] = + possible_clone; +} + +const MetaOutputInfo * +meta_output_get_info (MetaOutput *output) +{ + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + + return priv->info; +} + void meta_output_assign_crtc (MetaOutput *output, MetaCrtc *crtc, @@ -154,9 +220,10 @@ MetaMonitorTransform meta_output_logical_to_crtc_transform (MetaOutput *output, MetaMonitorTransform transform) { + MetaOutputPrivate *priv = meta_output_get_instance_private (output); MetaMonitorTransform panel_orientation_transform; - panel_orientation_transform = output->panel_orientation_transform; + panel_orientation_transform = priv->info->panel_orientation_transform; return meta_monitor_transform_transform (transform, panel_orientation_transform); } @@ -165,10 +232,11 @@ MetaMonitorTransform meta_output_crtc_to_logical_transform (MetaOutput *output, MetaMonitorTransform transform) { + MetaOutputPrivate *priv = meta_output_get_instance_private (output); MetaMonitorTransform inverted_panel_orientation_transform; inverted_panel_orientation_transform = - meta_monitor_transform_invert (output->panel_orientation_transform); + meta_monitor_transform_invert (priv->info->panel_orientation_transform); return meta_monitor_transform_transform (transform, inverted_panel_orientation_transform); } @@ -190,6 +258,9 @@ meta_output_set_property (GObject *object, case PROP_GPU: priv->gpu = g_value_get_object (value); break; + case PROP_INFO: + priv->info = meta_output_info_ref (g_value_get_boxed (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -212,6 +283,9 @@ meta_output_get_property (GObject *object, case PROP_GPU: g_value_set_object (value, priv->gpu); break; + case PROP_INFO: + g_value_set_boxed (value, priv->info); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -232,18 +306,13 @@ static void meta_output_finalize (GObject *object) { MetaOutput *output = META_OUTPUT (object); - - g_free (output->name); - g_free (output->vendor); - g_free (output->product); - g_free (output->serial); - g_free (output->modes); - g_free (output->possible_crtcs); - g_free (output->possible_clones); + MetaOutputPrivate *priv = meta_output_get_instance_private (output); if (output->driver_notify) output->driver_notify (output); + g_clear_pointer (&priv->info, meta_output_info_unref); + G_OBJECT_CLASS (meta_output_parent_class)->finalize (object); } @@ -281,5 +350,13 @@ meta_output_class_init (MetaOutputClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_props[PROP_INFO] = + g_param_spec_boxed ("info", + "info", + "MetaOutputInfo", + META_TYPE_OUTPUT_INFO, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPS, obj_props); } diff --git a/src/backends/meta-output.h b/src/backends/meta-output.h index 75b6ca189..88d6dfc64 100644 --- a/src/backends/meta-output.h +++ b/src/backends/meta-output.h @@ -60,9 +60,9 @@ typedef enum META_CONNECTOR_TYPE_DSI = 16, } MetaConnectorType; -struct _MetaOutput +typedef struct _MetaOutputInfo { - GObject parent; + grefcount ref_count; char *name; char *vendor; @@ -90,9 +90,6 @@ struct _MetaOutput gboolean supports_underscanning; - gpointer driver_private; - GDestroyNotify driver_notify; - /* * Get a new preferred mode on hotplug events, to handle dynamic guest * resizing. @@ -102,8 +99,35 @@ struct _MetaOutput int suggested_y; MetaTileInfo tile_info; +} MetaOutputInfo; + +struct _MetaOutput +{ + GObject parent; + + gpointer driver_private; + GDestroyNotify driver_notify; }; +#define META_TYPE_OUTPUT_INFO (meta_output_info_get_type ()) +META_EXPORT_TEST +GType meta_output_info_get_type (void); + +META_EXPORT_TEST +MetaOutputInfo * meta_output_info_new (void); + +META_EXPORT_TEST +MetaOutputInfo * meta_output_info_ref (MetaOutputInfo *output_info); + +META_EXPORT_TEST +void meta_output_info_unref (MetaOutputInfo *output_info); + +META_EXPORT_TEST +void meta_output_info_parse_edid (MetaOutputInfo *output_info, + GBytes *edid); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaOutputInfo, meta_output_info_unref) + #define META_TYPE_OUTPUT (meta_output_get_type ()) META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject) @@ -129,6 +153,11 @@ void meta_output_set_backlight (MetaOutput *output, int meta_output_get_backlight (MetaOutput *output); +void meta_output_add_possible_clone (MetaOutput *output, + MetaOutput *possible_clone); + +const MetaOutputInfo * meta_output_get_info (MetaOutput *output); + META_EXPORT_TEST void meta_output_assign_crtc (MetaOutput *output, MetaCrtc *crtc, diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c index 4d3aa25df..6b79a7a54 100644 --- a/src/backends/native/meta-gpu-kms.c +++ b/src/backends/native/meta-gpu-kms.c @@ -264,9 +264,12 @@ static int compare_outputs (gconstpointer one, gconstpointer two) { - const MetaOutput *o_one = one, *o_two = two; + MetaOutput *o_one = (MetaOutput *) one; + MetaOutput *o_two = (MetaOutput *) two; + const MetaOutputInfo *output_info_one = meta_output_get_info (o_one); + const MetaOutputInfo *output_info_two = meta_output_get_info (o_two); - return strcmp (o_one->name, o_two->name); + return strcmp (output_info_one->name, output_info_two->name); } static void @@ -389,14 +392,7 @@ setup_output_clones (MetaGpu *gpu) continue; if (meta_output_kms_can_clone (output, other_output)) - { - output->n_possible_clones++; - output->possible_clones = g_renew (MetaOutput *, - output->possible_clones, - output->n_possible_clones); - output->possible_clones[output->n_possible_clones - 1] = - other_output; - } + meta_output_add_possible_clone (output, other_output); } } } diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index 545df55ec..61665b0bd 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -57,8 +57,9 @@ meta_output_kms_set_underscan (MetaOutput *output, MetaKmsUpdate *kms_update) { MetaOutputKms *output_kms = output->driver_private; + const MetaOutputInfo *output_info = meta_output_get_info (output); - if (!output->supports_underscanning) + if (!output_info->supports_underscanning) return; if (meta_output_is_underscanning (output)) @@ -153,8 +154,8 @@ meta_output_destroy_notify (MetaOutput *output) } static void -add_common_modes (MetaOutput *output, - MetaGpuKms *gpu_kms) +add_common_modes (MetaOutputInfo *output_info, + MetaGpuKms *gpu_kms) { const drmModeModeInfo *drm_mode; MetaCrtcMode *crtc_mode; @@ -165,9 +166,9 @@ add_common_modes (MetaOutput *output, unsigned max_vdisplay = 0; float max_refresh_rate = 0.0; - for (i = 0; i < output->n_modes; i++) + for (i = 0; i < output_info->n_modes; i++) { - drm_mode = output->modes[i]->driver_private; + drm_mode = output_info->modes[i]->driver_private; refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); max_hdisplay = MAX (max_hdisplay, drm_mode->hdisplay); max_vdisplay = MAX (max_vdisplay, drm_mode->vdisplay); @@ -211,11 +212,11 @@ add_common_modes (MetaOutput *output, } } - output->modes = g_renew (MetaCrtcMode *, output->modes, - output->n_modes + array->len); - memcpy (output->modes + output->n_modes, array->pdata, + output_info->modes = g_renew (MetaCrtcMode *, output_info->modes, + output_info->n_modes + array->len); + memcpy (output_info->modes + output_info->n_modes, array->pdata, array->len * sizeof (MetaCrtcMode *)); - output->n_modes += array->len; + output_info->n_modes += array->len; g_ptr_array_free (array, TRUE); } @@ -238,30 +239,29 @@ compare_modes (const void *one, } static gboolean -init_output_modes (MetaOutput *output, - MetaGpuKms *gpu_kms, - GError **error) +init_output_modes (MetaOutputInfo *output_info, + MetaGpuKms *gpu_kms, + MetaKmsConnector *kms_connector, + GError **error) { - MetaOutputKms *output_kms = output->driver_private; const MetaKmsConnectorState *connector_state; int i; - connector_state = - meta_kms_connector_get_current_state (output_kms->kms_connector); + connector_state = meta_kms_connector_get_current_state (kms_connector); - output->preferred_mode = NULL; + output_info->preferred_mode = NULL; - output->n_modes = connector_state->n_modes; - output->modes = g_new0 (MetaCrtcMode *, output->n_modes); + output_info->n_modes = connector_state->n_modes; + output_info->modes = g_new0 (MetaCrtcMode *, output_info->n_modes); for (i = 0; i < connector_state->n_modes; i++) { drmModeModeInfo *drm_mode = &connector_state->modes[i]; MetaCrtcMode *crtc_mode; crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, drm_mode); - output->modes[i] = crtc_mode; + output_info->modes[i] = crtc_mode; if (drm_mode->type & DRM_MODE_TYPE_PREFERRED) - output->preferred_mode = output->modes[i]; + output_info->preferred_mode = output_info->modes[i]; } /* FIXME: MSC feature bit? */ @@ -269,20 +269,20 @@ init_output_modes (MetaOutput *output, * a panel fitter capable of adjusting any mode to suit. */ if (connector_state->has_scaling) - add_common_modes (output, gpu_kms); + add_common_modes (output_info, gpu_kms); - if (!output->modes) + if (!output_info->modes) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No modes available"); return FALSE; } - qsort (output->modes, output->n_modes, + qsort (output_info->modes, output_info->n_modes, sizeof (MetaCrtcMode *), compare_modes); - if (!output->preferred_mode) - output->preferred_mode = output->modes[0]; + if (!output_info->preferred_mode) + output_info->preferred_mode = output_info->modes[0]; return TRUE; } @@ -296,6 +296,7 @@ meta_create_kms_output (MetaGpuKms *gpu_kms, MetaGpu *gpu = META_GPU (gpu_kms); uint32_t connector_id; uint32_t gpu_id; + g_autoptr (MetaOutputInfo) output_info = NULL; MetaOutput *output; MetaOutputKms *output_kms; const MetaKmsConnectorState *connector_state; @@ -305,39 +306,26 @@ meta_create_kms_output (MetaGpuKms *gpu_kms, gpu_id = meta_gpu_kms_get_id (gpu_kms); connector_id = meta_kms_connector_get_id (kms_connector); - output = g_object_new (META_TYPE_OUTPUT, - "id", ((uint64_t) gpu_id << 32) | connector_id, - "gpu", gpu, - NULL); - - output_kms = g_slice_new0 (MetaOutputKms); - output->driver_private = output_kms; - output->driver_notify = (GDestroyNotify) meta_output_destroy_notify; - - output->name = g_strdup (meta_kms_connector_get_name (kms_connector)); - - output_kms->kms_connector = kms_connector; + output_info = meta_output_info_new (); + output_info->name = g_strdup (meta_kms_connector_get_name (kms_connector)); connector_state = meta_kms_connector_get_current_state (kms_connector); - output->panel_orientation_transform = + output_info->panel_orientation_transform = connector_state->panel_orientation_transform; - if (meta_monitor_transform_is_rotated (output->panel_orientation_transform)) + if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform)) { - output->width_mm = connector_state->height_mm; - output->height_mm = connector_state->width_mm; + output_info->width_mm = connector_state->height_mm; + output_info->height_mm = connector_state->width_mm; } else { - output->width_mm = connector_state->width_mm; - output->height_mm = connector_state->height_mm; + output_info->width_mm = connector_state->width_mm; + output_info->height_mm = connector_state->height_mm; } - if (!init_output_modes (output, gpu_kms, error)) - { - g_object_unref (output); - return NULL; - } + if (!init_output_modes (output_info, gpu_kms, kms_connector, error)) + return NULL; crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCrtc *)); @@ -352,8 +340,32 @@ meta_create_kms_output (MetaGpuKms *gpu_kms, g_array_append_val (crtcs, crtc); } - output->n_possible_crtcs = crtcs->len; - output->possible_crtcs = (MetaCrtc **) g_array_free (crtcs, FALSE); + output_info->n_possible_crtcs = crtcs->len; + output_info->possible_crtcs = (MetaCrtc **) g_array_free (crtcs, FALSE); + + output_info->suggested_x = connector_state->suggested_x; + output_info->suggested_y = connector_state->suggested_y; + output_info->hotplug_mode_update = connector_state->hotplug_mode_update; + output_info->supports_underscanning = + meta_kms_connector_is_underscanning_supported (kms_connector); + + meta_output_info_parse_edid (output_info, connector_state->edid_data); + + output_info->connector_type = meta_kms_connector_get_connector_type (kms_connector); + + output_info->tile_info = connector_state->tile_info; + + output = g_object_new (META_TYPE_OUTPUT, + "id", ((uint64_t) gpu_id << 32) | connector_id, + "gpu", gpu, + "info", output_info, + NULL); + + output_kms = g_slice_new0 (MetaOutputKms); + output->driver_private = output_kms; + output->driver_notify = (GDestroyNotify) meta_output_destroy_notify; + + output_kms->kms_connector = kms_connector; if (connector_state->current_crtc_id) { @@ -389,29 +401,5 @@ meta_create_kms_output (MetaGpuKms *gpu_kms, meta_output_unassign_crtc (output); } - output->suggested_x = connector_state->suggested_x; - output->suggested_y = connector_state->suggested_y; - output->hotplug_mode_update = connector_state->hotplug_mode_update; - output->supports_underscanning = - meta_kms_connector_is_underscanning_supported (kms_connector); - - meta_output_parse_edid (output, connector_state->edid_data); - - output->connector_type = meta_kms_connector_get_connector_type (kms_connector); - - output->tile_info = connector_state->tile_info; - - /* FIXME: backlight is a very driver specific thing unfortunately, - every DDX does its own thing, and the dumb KMS API does not include it. - - For example, xf86-video-intel has a list of paths to probe in /sys/class/backlight - (one for each major HW maker, and then some). - We can't do the same because we're not root. - It might be best to leave backlight out of the story and rely on the setuid - helper in gnome-settings-daemon. - */ - output->backlight_min = 0; - output->backlight_max = 0; - return output; } diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c index 12fd90925..ad1f8dce2 100644 --- a/src/backends/x11/meta-gpu-xrandr.c +++ b/src/backends/x11/meta-gpu-xrandr.c @@ -69,9 +69,12 @@ static int compare_outputs (const void *one, const void *two) { - const MetaOutput *o_one = one, *o_two = two; + MetaOutput *o_one = (MetaOutput *) one; + MetaOutput *o_two = (MetaOutput *) two; + const MetaOutputInfo *output_info_one = meta_output_get_info (o_one); + const MetaOutputInfo *output_info_two = meta_output_get_info (o_two); - return strcmp (o_one->name, o_two->name); + return strcmp (output_info_one->name, output_info_two->name); } static char * @@ -210,11 +213,12 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu, for (l = outputs; l; l = l->next) { MetaOutput *output = l->data; + const MetaOutputInfo *output_info = meta_output_get_info (output); GList *k; - for (j = 0; j < output->n_possible_clones; j++) + for (j = 0; j < output_info->n_possible_clones; j++) { - RROutput clone = GPOINTER_TO_INT (output->possible_clones[j]); + RROutput clone = GPOINTER_TO_INT (output_info->possible_clones[j]); for (k = outputs; k; k = k->next) { @@ -222,7 +226,7 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu, if (clone == (XID) meta_output_get_id (possible_clone)) { - output->possible_clones[j] = possible_clone; + output_info->possible_clones[j] = possible_clone; break; } } diff --git a/src/backends/x11/meta-output-xrandr.c b/src/backends/x11/meta-output-xrandr.c index bafb93f8f..588fac220 100644 --- a/src/backends/x11/meta-output-xrandr.c +++ b/src/backends/x11/meta-output-xrandr.c @@ -47,9 +47,8 @@ #include "meta/util.h" static Display * -xdisplay_from_output (MetaOutput *output) +xdisplay_from_gpu (MetaGpu *gpu) { - MetaGpu *gpu = meta_output_get_gpu (output); MetaBackend *backend = meta_gpu_get_backend (gpu); MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); @@ -59,6 +58,12 @@ xdisplay_from_output (MetaOutput *output) return meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr); } +static Display * +xdisplay_from_output (MetaOutput *output) +{ + return xdisplay_from_gpu (meta_output_get_gpu (output)); +} + static void output_set_presentation_xrandr (MetaOutput *output, gboolean presentation) @@ -140,7 +145,7 @@ meta_output_xrandr_apply_mode (MetaOutput *output) output_set_presentation_xrandr (output, meta_output_is_presentation (output)); - if (output->supports_underscanning) + if (meta_output_get_info (output)->supports_underscanning) { output_set_underscanning_xrandr (output, meta_output_is_underscanning (output)); @@ -151,20 +156,23 @@ static int normalize_backlight (MetaOutput *output, int hw_value) { - return round ((double)(hw_value - output->backlight_min) / - (output->backlight_max - output->backlight_min) * 100.0); + const MetaOutputInfo *output_info = meta_output_get_info (output); + + return round ((double) (hw_value - output_info->backlight_min) / + (output_info->backlight_max - output_info->backlight_min) * 100.0); } void meta_output_xrandr_change_backlight (MetaOutput *output, int value) { + const MetaOutputInfo *output_info = meta_output_get_info (output); Display *xdisplay = xdisplay_from_output (output); Atom atom; int hw_value; - hw_value = round ((double) value / 100.0 * output->backlight_max + - output->backlight_min); + hw_value = round ((double) value / 100.0 * output_info->backlight_max + + output_info->backlight_min); atom = XInternAtom (xdisplay, "Backlight", False); @@ -179,11 +187,11 @@ meta_output_xrandr_change_backlight (MetaOutput *output, } static gboolean -output_get_integer_property (MetaOutput *output, +output_get_integer_property (Display *xdisplay, + RROutput output_id, const char *propname, gint *value) { - Display *xdisplay = xdisplay_from_output (output); gboolean exists = FALSE; Atom atom, actual_type; int actual_format; @@ -192,7 +200,7 @@ output_get_integer_property (MetaOutput *output, atom = XInternAtom (xdisplay, propname, False); XRRGetOutputProperty (xdisplay, - (XID) meta_output_get_id (output), + (XID) output_id, atom, 0, G_MAXLONG, False, False, XA_INTEGER, &actual_type, &actual_format, @@ -208,10 +216,10 @@ output_get_integer_property (MetaOutput *output, } static gboolean -output_get_property_exists (MetaOutput *output, +output_get_property_exists (Display *xdisplay, + RROutput output_id, const char *propname) { - Display *xdisplay = xdisplay_from_output (output); gboolean exists = FALSE; Atom atom, actual_type; int actual_format; @@ -220,7 +228,7 @@ output_get_property_exists (MetaOutput *output, atom = XInternAtom (xdisplay, propname, False); XRRGetOutputProperty (xdisplay, - (XID) meta_output_get_id (output), + (XID) output_id, atom, 0, G_MAXLONG, False, False, AnyPropertyType, &actual_type, &actual_format, @@ -288,9 +296,9 @@ output_get_underscanning_xrandr (MetaOutput *output) } static gboolean -output_get_supports_underscanning_xrandr (MetaOutput *output) +output_get_supports_underscanning_xrandr (Display *xdisplay, + RROutput output_id) { - Display *xdisplay = xdisplay_from_output (output); Atom atom, actual_type; int actual_format, i; unsigned long nitems, bytes_after; @@ -301,7 +309,7 @@ output_get_supports_underscanning_xrandr (MetaOutput *output) atom = XInternAtom (xdisplay, "underscan", False); XRRGetOutputProperty (xdisplay, - (XID) meta_output_get_id (output), + (XID) output_id, atom, 0, G_MAXLONG, False, False, XA_ATOM, &actual_type, &actual_format, @@ -311,7 +319,7 @@ output_get_supports_underscanning_xrandr (MetaOutput *output) return FALSE; property_info = XRRQueryOutputProperty (xdisplay, - (XID) meta_output_get_id (output), + (XID) output_id, atom); values = (Atom *) property_info->values; @@ -361,19 +369,18 @@ output_get_backlight_xrandr (MetaOutput *output) } static void -output_get_backlight_limits_xrandr (MetaOutput *output) +output_info_init_backlight_limits_xrandr (MetaOutputInfo *output_info, + Display *xdisplay, + xcb_randr_output_t output_id) { - Display *xdisplay = xdisplay_from_output (output); Atom atom; xcb_connection_t *xcb_conn; - xcb_randr_output_t output_id; xcb_randr_query_output_property_cookie_t cookie; g_autofree xcb_randr_query_output_property_reply_t *reply = NULL; atom = XInternAtom (xdisplay, "Backlight", False); xcb_conn = XGetXCBConnection (xdisplay); - output_id = meta_output_get_id (output); cookie = xcb_randr_query_output_property (xcb_conn, output_id, (xcb_atom_t) atom); @@ -387,13 +394,13 @@ output_get_backlight_limits_xrandr (MetaOutput *output) if (!reply->range || reply->length != 2) { - meta_verbose ("backlight %s was not range\n", output->name); + meta_verbose ("backlight %s was not range\n", output_info->name); return; } int32_t *values = xcb_randr_query_output_property_valid_values (reply); - output->backlight_min = values[0]; - output->backlight_max = values[1]; + output_info->backlight_min = values[0]; + output_info->backlight_max = values[1]; } static guint8 * @@ -430,27 +437,21 @@ get_edid_property (Display *xdisplay, return result; } -GBytes * -meta_output_xrandr_read_edid (MetaOutput *output) +static GBytes * +read_xrandr_edid (Display *xdisplay, + RROutput output_id) { - Display *xdisplay = xdisplay_from_output (output); Atom edid_atom; guint8 *result; gsize len; edid_atom = XInternAtom (xdisplay, "EDID", FALSE); - result = get_edid_property (xdisplay, - meta_output_get_id (output), - edid_atom, - &len); + result = get_edid_property (xdisplay, output_id, edid_atom, &len); if (!result) { edid_atom = XInternAtom (xdisplay, "EDID_DATA", FALSE); - result = get_edid_property (xdisplay, - meta_output_get_id (output), - edid_atom, - &len); + result = get_edid_property (xdisplay, output_id, edid_atom, &len); } if (result) @@ -464,27 +465,39 @@ meta_output_xrandr_read_edid (MetaOutput *output) return NULL; } -static gboolean -output_get_hotplug_mode_update (MetaOutput *output) +GBytes * +meta_output_xrandr_read_edid (MetaOutput *output) { - return output_get_property_exists (output, "hotplug_mode_update"); + Display *xdisplay = xdisplay_from_output (output); + RROutput output_id = (RROutput) meta_output_get_id (output); + + return read_xrandr_edid (xdisplay, output_id); +} + +static gboolean +output_get_hotplug_mode_update (Display *xdisplay, + RROutput output_id) +{ + return output_get_property_exists (xdisplay, output_id, "hotplug_mode_update"); } static gint -output_get_suggested_x (MetaOutput *output) +output_get_suggested_x (Display *xdisplay, + RROutput output_id) { gint val; - if (output_get_integer_property (output, "suggested X", &val)) + if (output_get_integer_property (xdisplay, output_id, "suggested X", &val)) return val; return -1; } static gint -output_get_suggested_y (MetaOutput *output) +output_get_suggested_y (Display *xdisplay, + RROutput output_id) { gint val; - if (output_get_integer_property (output, "suggested Y", &val)) + if (output_get_integer_property (xdisplay, output_id, "suggested Y", &val)) return val; return -1; @@ -528,9 +541,9 @@ connector_type_from_atom (Display *xdisplay, } static MetaConnectorType -output_get_connector_type_from_prop (MetaOutput *output) +output_get_connector_type_from_prop (Display *xdisplay, + RROutput output_id) { - Display *xdisplay = xdisplay_from_output (output); Atom atom, actual_type, connector_type_atom; int actual_format; unsigned long nitems, bytes_after; @@ -538,7 +551,7 @@ output_get_connector_type_from_prop (MetaOutput *output) atom = XInternAtom (xdisplay, "ConnectorType", False); XRRGetOutputProperty (xdisplay, - (XID) meta_output_get_id (output), + (XID) output_id, atom, 0, G_MAXLONG, False, False, XA_ATOM, &actual_type, &actual_format, @@ -552,9 +565,9 @@ output_get_connector_type_from_prop (MetaOutput *output) } static MetaConnectorType -output_get_connector_type_from_name (MetaOutput *output) +output_info_get_connector_type_from_name (const MetaOutputInfo *output_info) { - const char *name = output->name; + const char *name = output_info->name; /* drmmode_display.c, which was copy/pasted across all the FOSS * xf86-video-* drivers, seems to name its outputs based on the @@ -600,7 +613,9 @@ output_get_connector_type_from_name (MetaOutput *output) } static MetaConnectorType -output_get_connector_type (MetaOutput *output) +output_info_get_connector_type (MetaOutputInfo *output_info, + Display *xdisplay, + RROutput output_id) { MetaConnectorType ret; @@ -611,12 +626,12 @@ output_get_connector_type (MetaOutput *output) * Try poking it first, without any expectations that it will work. * If it's not there, we thankfully have other bonghits to try next. */ - ret = output_get_connector_type_from_prop (output); + ret = output_get_connector_type_from_prop (xdisplay, output_id); if (ret != META_CONNECTOR_TYPE_Unknown) return ret; /* Fall back to heuristics based on the output name. */ - ret = output_get_connector_type_from_name (output); + ret = output_info_get_connector_type_from_name (output_info); if (ret != META_CONNECTOR_TYPE_Unknown) return ret; @@ -624,9 +639,9 @@ output_get_connector_type (MetaOutput *output) } static gint -output_get_panel_orientation_transform (MetaOutput *output) +output_get_panel_orientation_transform (Display *xdisplay, + RROutput output_id) { - Display *xdisplay = xdisplay_from_output (output); unsigned long nitems, bytes_after; Atom atom, actual_type; int actual_format; @@ -635,7 +650,7 @@ output_get_panel_orientation_transform (MetaOutput *output) atom = XInternAtom (xdisplay, "panel orientation", False); XRRGetOutputProperty (xdisplay, - (XID) meta_output_get_id (output), + (XID) output_id, atom, 0, G_MAXLONG, False, False, XA_ATOM, &actual_type, &actual_format, @@ -658,27 +673,19 @@ output_get_panel_orientation_transform (MetaOutput *output) } static void -output_get_tile_info (MetaOutput *output) +output_info_init_tile_info (MetaOutputInfo *output_info, + Display *xdisplay, + RROutput output_id) { - MetaGpu *gpu = meta_output_get_gpu (output); - MetaBackend *backend = meta_gpu_get_backend (gpu); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - MetaMonitorManagerXrandr *monitor_manager_xrandr = - META_MONITOR_MANAGER_XRANDR (monitor_manager); - Display *xdisplay = xdisplay_from_output (output); Atom tile_atom; unsigned char *prop; unsigned long nitems, bytes_after; int actual_format; Atom actual_type; - if (!meta_monitor_manager_xrandr_has_randr15 (monitor_manager_xrandr)) - return; - tile_atom = XInternAtom (xdisplay, "TILE", FALSE); XRRGetOutputProperty (xdisplay, - (XID) meta_output_get_id (output), + (XID) output_id, tile_atom, 0, 100, False, False, AnyPropertyType, &actual_type, &actual_format, @@ -687,28 +694,29 @@ output_get_tile_info (MetaOutput *output) if (actual_type == XA_INTEGER && actual_format == 32 && nitems == 8) { long *values = (long *)prop; - output->tile_info.group_id = values[0]; - output->tile_info.flags = values[1]; - output->tile_info.max_h_tiles = values[2]; - output->tile_info.max_v_tiles = values[3]; - output->tile_info.loc_h_tile = values[4]; - output->tile_info.loc_v_tile = values[5]; - output->tile_info.tile_w = values[6]; - output->tile_info.tile_h = values[7]; + + output_info->tile_info.group_id = values[0]; + output_info->tile_info.flags = values[1]; + output_info->tile_info.max_h_tiles = values[2]; + output_info->tile_info.max_v_tiles = values[3]; + output_info->tile_info.loc_h_tile = values[4]; + output_info->tile_info.loc_v_tile = values[5]; + output_info->tile_info.tile_w = values[6]; + output_info->tile_info.tile_h = values[7]; } XFree (prop); } static void -output_get_modes (MetaOutput *output, - XRROutputInfo *xrandr_output) +output_info_init_modes (MetaOutputInfo *output_info, + MetaGpu *gpu, + XRROutputInfo *xrandr_output) { - MetaGpu *gpu = meta_output_get_gpu (output); unsigned int i; unsigned int n_actual_modes; - output->modes = g_new0 (MetaCrtcMode *, xrandr_output->nmode); + output_info->modes = g_new0 (MetaCrtcMode *, xrandr_output->nmode); n_actual_modes = 0; for (i = 0; i < (unsigned int) xrandr_output->nmode; i++) @@ -721,28 +729,27 @@ output_get_modes (MetaOutput *output, if (xrandr_output->modes[i] == (XID) mode->mode_id) { - output->modes[n_actual_modes] = mode; + output_info->modes[n_actual_modes] = mode; n_actual_modes += 1; break; } } } - output->n_modes = n_actual_modes; + output_info->n_modes = n_actual_modes; if (n_actual_modes > 0) - output->preferred_mode = output->modes[0]; + output_info->preferred_mode = output_info->modes[0]; } static void -output_get_crtcs (MetaOutput *output, - XRROutputInfo *xrandr_output, - MetaCrtc **assigned_crtc) +output_info_init_crtcs (MetaOutputInfo *output_info, + MetaGpu *gpu, + XRROutputInfo *xrandr_output) { - MetaGpu *gpu = meta_output_get_gpu (output); unsigned int i; unsigned int n_actual_crtcs; GList *l; - output->possible_crtcs = g_new0 (MetaCrtc *, xrandr_output->ncrtc); + output_info->possible_crtcs = g_new0 (MetaCrtc *, xrandr_output->ncrtc); n_actual_crtcs = 0; for (i = 0; i < (unsigned int) xrandr_output->ncrtc; i++) @@ -753,27 +760,30 @@ output_get_crtcs (MetaOutput *output, if ((XID) meta_crtc_get_id (crtc) == xrandr_output->crtcs[i]) { - output->possible_crtcs[n_actual_crtcs] = crtc; + output_info->possible_crtcs[n_actual_crtcs] = crtc; n_actual_crtcs += 1; break; } } } - output->n_possible_crtcs = n_actual_crtcs; + output_info->n_possible_crtcs = n_actual_crtcs; +} + +static MetaCrtc * +find_assigned_crtc (MetaGpu *gpu, + XRROutputInfo *xrandr_output) +{ + GList *l; - meta_output_unassign_crtc (output); for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) { MetaCrtc *crtc = l->data; if ((XID) meta_crtc_get_id (crtc) == xrandr_output->crtc) - { - *assigned_crtc = crtc; - return; - } + return crtc; } - *assigned_crtc = NULL; + return NULL; } MetaOutput * @@ -782,45 +792,80 @@ meta_create_xrandr_output (MetaGpuXrandr *gpu_xrandr, RROutput output_id, RROutput primary_output) { + MetaGpu *gpu = META_GPU (gpu_xrandr); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerXrandr *monitor_manager_xrandr = + META_MONITOR_MANAGER_XRANDR (monitor_manager); + Display *xdisplay = + meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr); + g_autoptr (MetaOutputInfo) output_info = NULL; MetaOutput *output; GBytes *edid; MetaCrtc *assigned_crtc; unsigned int i; - output = g_object_new (META_TYPE_OUTPUT, - "id", output_id, - "gpu", gpu_xrandr, - NULL); - output->name = g_strdup (xrandr_output->name); + output_info = meta_output_info_new (); - edid = meta_output_xrandr_read_edid (output); - meta_output_parse_edid (output, edid); + output_info->name = g_strdup (xrandr_output->name); + + edid = read_xrandr_edid (xdisplay, output_id); + meta_output_info_parse_edid (output_info, edid); g_bytes_unref (edid); - output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; - output->hotplug_mode_update = output_get_hotplug_mode_update (output); - output->suggested_x = output_get_suggested_x (output); - output->suggested_y = output_get_suggested_y (output); - output->connector_type = output_get_connector_type (output); - output->panel_orientation_transform = - output_get_panel_orientation_transform (output); + output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + output_info->hotplug_mode_update = output_get_hotplug_mode_update (xdisplay, + output_id); + output_info->suggested_x = output_get_suggested_x (xdisplay, output_id); + output_info->suggested_y = output_get_suggested_y (xdisplay, output_id); + output_info->connector_type = output_info_get_connector_type (output_info, + xdisplay, + output_id); + output_info->panel_orientation_transform = + output_get_panel_orientation_transform (xdisplay, output_id); if (meta_monitor_transform_is_rotated ( - output->panel_orientation_transform)) + output_info->panel_orientation_transform)) { - output->width_mm = xrandr_output->mm_height; - output->height_mm = xrandr_output->mm_width; + output_info->width_mm = xrandr_output->mm_height; + output_info->height_mm = xrandr_output->mm_width; } else { - output->width_mm = xrandr_output->mm_width; - output->height_mm = xrandr_output->mm_height; + output_info->width_mm = xrandr_output->mm_width; + output_info->height_mm = xrandr_output->mm_height; } - output_get_tile_info (output); - output_get_modes (output, xrandr_output); - output_get_crtcs (output, xrandr_output, &assigned_crtc); + if (!meta_monitor_manager_xrandr_has_randr15 (monitor_manager_xrandr)) + output_info_init_tile_info (output_info, xdisplay, output_id); + output_info_init_modes (output_info, gpu, xrandr_output); + output_info_init_crtcs (output_info, gpu, xrandr_output); + output_info->n_possible_clones = xrandr_output->nclone; + output_info->possible_clones = g_new0 (MetaOutput *, + output_info->n_possible_clones); + /* + * We can build the list of clones now, because we don't have the list of + * outputs yet, so temporarily set the pointers to the bare XIDs, and then + * we'll fix them in a second pass. + */ + for (i = 0; i < (unsigned int) xrandr_output->nclone; i++) + { + output_info->possible_clones[i] = GINT_TO_POINTER (xrandr_output->clones[i]); + } + + output_info->supports_underscanning = + output_get_supports_underscanning_xrandr (xdisplay, output_id); + output_info_init_backlight_limits_xrandr (output_info, xdisplay, output_id); + + output = g_object_new (META_TYPE_OUTPUT, + "id", output_id, + "gpu", gpu_xrandr, + "info", output_info, + NULL); + + assigned_crtc = find_assigned_crtc (gpu, xrandr_output); if (assigned_crtc) { MetaOutputAssignment output_assignment; @@ -832,28 +877,15 @@ meta_create_xrandr_output (MetaGpuXrandr *gpu_xrandr, }; meta_output_assign_crtc (output, assigned_crtc, &output_assignment); } - - output->n_possible_clones = xrandr_output->nclone; - output->possible_clones = g_new0 (MetaOutput *, - output->n_possible_clones); - /* - * We can build the list of clones now, because we don't have the list of - * outputs yet, so temporarily set the pointers to the bare XIDs, and then - * we'll fix them in a second pass. - */ - for (i = 0; i < (unsigned int) xrandr_output->nclone; i++) + else { - output->possible_clones[i] = GINT_TO_POINTER (xrandr_output->clones[i]); + meta_output_unassign_crtc (output); } - output->supports_underscanning = - output_get_supports_underscanning_xrandr (output); - output_get_backlight_limits_xrandr (output); - - if (!(output->backlight_min == 0 && output->backlight_max == 0)) + if (!(output_info->backlight_min == 0 && output_info->backlight_max == 0)) meta_output_set_backlight (output, output_get_backlight_xrandr (output)); - if (output->n_modes == 0 || output->n_possible_crtcs == 0) + if (output_info->n_modes == 0 || output_info->n_possible_crtcs == 0) { g_object_unref (output); return NULL; diff --git a/src/tests/headless-start-test.c b/src/tests/headless-start-test.c index 302ee8557..223ef1a49 100644 --- a/src/tests/headless-start-test.c +++ b/src/tests/headless-start-test.c @@ -124,6 +124,7 @@ meta_test_headless_monitor_connect (void) MetaGpu *gpu; MetaCrtc *crtc; MetaCrtc **possible_crtcs; + g_autoptr (MetaOutputInfo) output_info = NULL; MetaOutput *output; GList *logical_monitors; ClutterActor *stage; @@ -151,20 +152,25 @@ meta_test_headless_monitor_connect (void) possible_crtcs = g_new0 (MetaCrtc *, 1); possible_crtcs[0] = g_list_first (test_setup->crtcs)->data; + output_info = meta_output_info_new (); + + output_info->name = g_strdup ("DP-1"); + output_info->vendor = g_strdup ("MetaProduct's Inc."); + output_info->product = g_strdup ("MetaMonitor"); + output_info->serial = g_strdup ("0x987654"); + output_info->preferred_mode = modes[0]; + output_info->n_modes = 1; + output_info->modes = modes; + output_info->n_possible_crtcs = 1; + output_info->possible_crtcs = possible_crtcs; + output_info->connector_type = META_CONNECTOR_TYPE_DisplayPort; + output = g_object_new (META_TYPE_OUTPUT, "id", 1, "gpu", gpu, + "info", output_info, NULL); - output->name = g_strdup ("DP-1"); - output->vendor = g_strdup ("MetaProduct's Inc."); - output->product = g_strdup ("MetaMonitor"); - output->serial = g_strdup ("0x987654"); - output->preferred_mode = modes[0]; - output->n_modes = 1; - output->modes = modes; - output->n_possible_crtcs = 1; - output->possible_crtcs = possible_crtcs; - output->connector_type = META_CONNECTOR_TYPE_DisplayPort; + test_setup->outputs = g_list_append (NULL, output); meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); diff --git a/src/tests/monitor-test-utils.c b/src/tests/monitor-test-utils.c index 61d85c627..484ec1f19 100644 --- a/src/tests/monitor-test-utils.c +++ b/src/tests/monitor-test-utils.c @@ -598,6 +598,7 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup, int scale; gboolean is_laptop_panel; const char *serial; + g_autoptr (MetaOutputInfo) output_info = NULL; crtc_index = setup->outputs[i].crtc; if (crtc_index == -1) @@ -649,9 +650,45 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup, if (!serial) serial = "0x123456"; + output_info = meta_output_info_new (); + + output_info->name = (is_laptop_panel + ? g_strdup_printf ("eDP-%d", ++n_laptop_panels) + : g_strdup_printf ("DP-%d", ++n_normal_panels)); + output_info->vendor = g_strdup ("MetaProduct's Inc."); + output_info->product = g_strdup ("MetaMonitor"); + output_info->serial = g_strdup (serial); + if (setup->outputs[i].hotplug_mode) + { + output_info->suggested_x = setup->outputs[i].suggested_x; + output_info->suggested_y = setup->outputs[i].suggested_y; + } + else + { + output_info->suggested_x = -1; + output_info->suggested_y = -1; + } + output_info->hotplug_mode_update = hotplug_mode_update; + output_info->width_mm = setup->outputs[i].width_mm; + output_info->height_mm = setup->outputs[i].height_mm; + output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + output_info->preferred_mode = preferred_mode; + output_info->n_modes = n_modes; + output_info->modes = modes; + output_info->n_possible_crtcs = n_possible_crtcs; + output_info->possible_crtcs = possible_crtcs; + output_info->n_possible_clones = 0; + output_info->possible_clones = NULL; + output_info->connector_type = (is_laptop_panel ? META_CONNECTOR_TYPE_eDP + : META_CONNECTOR_TYPE_DisplayPort); + output_info->tile_info = setup->outputs[i].tile_info; + output_info->panel_orientation_transform = + setup->outputs[i].panel_orientation_transform; + output = g_object_new (META_TYPE_OUTPUT, "id", i, "gpu", test_get_gpu (), + "info", output_info, NULL); if (crtc) @@ -664,39 +701,6 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup, meta_output_assign_crtc (output, crtc, &output_assignment); } - output->name = (is_laptop_panel ? g_strdup_printf ("eDP-%d", - ++n_laptop_panels) - : g_strdup_printf ("DP-%d", - ++n_normal_panels)); - output->vendor = g_strdup ("MetaProduct's Inc."); - output->product = g_strdup ("MetaMonitor"); - output->serial = g_strdup (serial); - if (setup->outputs[i].hotplug_mode) - { - output->suggested_x = setup->outputs[i].suggested_x; - output->suggested_y = setup->outputs[i].suggested_y; - } - else - { - output->suggested_x = -1; - output->suggested_y = -1; - } - output->hotplug_mode_update = hotplug_mode_update; - output->width_mm = setup->outputs[i].width_mm; - output->height_mm = setup->outputs[i].height_mm; - output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; - output->preferred_mode = preferred_mode; - output->n_modes = n_modes; - output->modes = modes; - output->n_possible_crtcs = n_possible_crtcs; - output->possible_crtcs = possible_crtcs; - output->n_possible_clones = 0; - output->possible_clones = NULL; - output->connector_type = (is_laptop_panel ? META_CONNECTOR_TYPE_eDP - : META_CONNECTOR_TYPE_DisplayPort); - output->tile_info = setup->outputs[i].tile_info; - output->panel_orientation_transform = - setup->outputs[i].panel_orientation_transform; output->driver_private = output_test; output->driver_notify = (GDestroyNotify) meta_output_test_destroy_notify;