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;