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
This commit is contained in:
Jonas Ådahl 2020-02-26 09:45:07 +01:00 committed by Georges Basile Stavracas Neto
parent 46e3d20057
commit 1406348be4
13 changed files with 705 additions and 488 deletions

View File

@ -57,8 +57,9 @@ meta_gpu_has_hotplug_mode_update (MetaGpu *gpu)
for (l = priv->outputs; l; l = l->next) for (l = priv->outputs; l; l = l->next)
{ {
MetaOutput *output = l->data; 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; return TRUE;
} }

View File

@ -118,16 +118,19 @@ find_unassigned_crtc (MetaOutput *output,
GArray *reserved_crtcs) GArray *reserved_crtcs)
{ {
MetaCrtc *crtc; MetaCrtc *crtc;
const MetaOutputInfo *output_info;
unsigned int i; unsigned int i;
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
if (crtc && !is_crtc_assigned (crtc, crtc_assignments)) if (crtc && !is_crtc_assigned (crtc, crtc_assignments))
return crtc; return crtc;
output_info = meta_output_get_info (output);
/* then try to assign a CRTC that wasn't used */ /* 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)) if (is_crtc_assigned (crtc, crtc_assignments))
continue; continue;
@ -139,9 +142,9 @@ find_unassigned_crtc (MetaOutput *output,
} }
/* finally just give a CRTC that we haven't assigned */ /* 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)) if (is_crtc_assigned (crtc, crtc_assignments))
continue; continue;

View File

@ -142,6 +142,7 @@ append_monitor (MetaMonitorManager *manager,
MetaOutput *output; MetaOutput *output;
unsigned int i; unsigned int i;
unsigned int number; unsigned int number;
g_autoptr (MetaOutputInfo) output_info = NULL;
const char *mode_specs_str; const char *mode_specs_str;
GList *l; GList *l;
@ -207,44 +208,46 @@ append_monitor (MetaMonitorManager *manager,
number = g_list_length (*outputs) + 1; 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, output = g_object_new (META_TYPE_OUTPUT,
"id", number, "id", number,
"gpu", gpu, "gpu", gpu,
"info", output_info,
NULL); NULL);
output_dummy = g_new0 (MetaOutputDummy, 1); output_dummy = g_new0 (MetaOutputDummy, 1);
*output_dummy = (MetaOutputDummy) { *output_dummy = (MetaOutputDummy) {
.scale = scale .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_private = output_dummy;
output->driver_notify = output->driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy; (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); *outputs = g_list_append (*outputs, output);
} }
@ -307,6 +310,7 @@ append_tiled_monitor (MetaMonitorManager *manager,
MetaCrtcMode *preferred_mode; MetaCrtcMode *preferred_mode;
unsigned int j; unsigned int j;
unsigned int number; unsigned int number;
g_autoptr (MetaOutputInfo) output_info = NULL;
GList *l; GList *l;
output_dummy = g_new0 (MetaOutputDummy, 1); output_dummy = g_new0 (MetaOutputDummy, 1);
@ -319,24 +323,21 @@ append_tiled_monitor (MetaMonitorManager *manager,
preferred_mode = g_list_last (*modes)->data; preferred_mode = g_list_last (*modes)->data;
output = g_object_new (META_TYPE_OUTPUT, output_info = meta_output_info_new ();
"id", number,
"gpu", gpu,
NULL);
output->name = g_strdup_printf ("LVDS%d", number); output_info->name = g_strdup_printf ("LVDS%d", number);
output->vendor = g_strdup ("MetaProducts Inc."); output_info->vendor = g_strdup ("MetaProducts Inc.");
output->product = g_strdup ("MetaMonitor"); output_info->product = g_strdup ("MetaMonitor");
output->serial = g_strdup_printf ("0xC0FFEE-%d", number); output_info->serial = g_strdup_printf ("0xC0FFEE-%d", number);
output->suggested_x = -1; output_info->suggested_x = -1;
output->suggested_y = -1; output_info->suggested_y = -1;
output->width_mm = 222; output_info->width_mm = 222;
output->height_mm = 125; output_info->height_mm = 125;
output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
output->preferred_mode = preferred_mode; output_info->preferred_mode = preferred_mode;
output->n_possible_clones = 0; output_info->n_possible_clones = 0;
output->connector_type = META_CONNECTOR_TYPE_LVDS; output_info->connector_type = META_CONNECTOR_TYPE_LVDS;
output->tile_info = (MetaTileInfo) { output_info->tile_info = (MetaTileInfo) {
.group_id = tile_group_id, .group_id = tile_group_id,
.max_h_tiles = n_tiles, .max_h_tiles = n_tiles,
.max_v_tiles = 1, .max_v_tiles = 1,
@ -345,27 +346,33 @@ append_tiled_monitor (MetaMonitorManager *manager,
.tile_w = preferred_mode->width, .tile_w = preferred_mode->width,
.tile_h = preferred_mode->height .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++) for (l = new_modes, j = 0; l; l = l->next, j++)
{ {
MetaCrtcMode *mode = l->data; 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++) for (l = new_crtcs, j = 0; l; l = l->next, j++)
{ {
MetaCrtc *crtc = l->data; 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); *outputs = g_list_append (*outputs, output);
} }

View File

@ -140,7 +140,10 @@ meta_monitor_manager_set_primary_logical_monitor (MetaMonitorManager *manager,
static gboolean static gboolean
is_main_tiled_monitor_output (MetaOutput *output) 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 * 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++) for (l = combined_outputs, i = 0; l; l = l->next, i++)
{ {
MetaOutput *output = l->data; MetaOutput *output = l->data;
const MetaOutputInfo *output_info = meta_output_get_info (output);
GVariantBuilder crtcs, modes, clones, properties; GVariantBuilder crtcs, modes, clones, properties;
GBytes *edid; GBytes *edid;
MetaCrtc *crtc; MetaCrtc *crtc;
int crtc_index; 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")); 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; unsigned possible_crtc_index;
possible_crtc_index = g_list_index (combined_crtcs, possible_crtc); 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")); 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; 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_add (&modes, "u", mode_index);
} }
g_variant_builder_init (&clones, G_VARIANT_TYPE ("au")); 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; unsigned int possible_clone_index;
possible_clone_index = g_list_index (combined_outputs, 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); 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_init (&properties, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&properties, "{sv}", "vendor", 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_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_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_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_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_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_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_builder_add (&properties, "{sv}", "min-backlight-step",
g_variant_new_int32 ((output->backlight_max - output->backlight_min) ? g_variant_new_int32 (min_backlight_step));
100 / (output->backlight_max - output->backlight_min) : -1));
g_variant_builder_add (&properties, "{sv}", "primary", 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_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_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_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_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); edid = manager_class->read_edid (manager, output);
if (edid) if (edid)
@ -1131,18 +1152,20 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_bytes_unref (edid); g_bytes_unref (edid);
} }
if (output->tile_info.group_id) if (output_info->tile_info.group_id)
{ {
g_variant_builder_add (&properties, "{sv}", "tile", GVariant *tile_variant;
g_variant_new ("(uuuuuuuu)",
output->tile_info.group_id, tile_variant = g_variant_new ("(uuuuuuuu)",
output->tile_info.flags, output_info->tile_info.group_id,
output->tile_info.max_h_tiles, output_info->tile_info.flags,
output->tile_info.max_v_tiles, output_info->tile_info.max_h_tiles,
output->tile_info.loc_h_tile, output_info->tile_info.max_v_tiles,
output->tile_info.loc_v_tile, output_info->tile_info.loc_h_tile,
output->tile_info.tile_w, output_info->tile_info.loc_v_tile,
output->tile_info.tile_h)); 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); crtc = meta_output_get_assigned_crtc (output);
@ -1152,7 +1175,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
meta_output_get_id (output), meta_output_get_id (output),
crtc_index, crtc_index,
&crtcs, &crtcs,
output->name, meta_output_get_name (output),
&modes, &modes,
&clones, &clones,
&properties); &properties);
@ -2103,6 +2126,7 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
{ {
GList *combined_outputs; GList *combined_outputs;
MetaOutput *output; MetaOutput *output;
const MetaOutputInfo *output_info;
int new_backlight; int new_backlight;
if (serial != manager->serial) if (serial != manager->serial)
@ -2134,8 +2158,10 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
return TRUE; return TRUE;
} }
output_info = meta_output_get_info (output);
if (meta_output_get_backlight (output) == -1 || 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_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS, G_DBUS_ERROR_INVALID_ARGS,
@ -2653,8 +2679,9 @@ rebuild_monitors (MetaMonitorManager *manager)
for (k = meta_gpu_get_outputs (gpu); k; k = k->next) for (k = meta_gpu_get_outputs (gpu); k; k = k->next)
{ {
MetaOutput *output = k->data; 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)) if (is_main_tiled_monitor_output (output))
{ {
@ -2886,7 +2913,7 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager,
} }
void void
meta_output_parse_edid (MetaOutput *output, meta_output_info_parse_edid (MetaOutputInfo *output_info,
GBytes *edid) GBytes *edid)
{ {
MonitorInfo *parsed_edid; MonitorInfo *parsed_edid;
@ -2899,42 +2926,44 @@ meta_output_parse_edid (MetaOutput *output,
if (parsed_edid) if (parsed_edid)
{ {
output->vendor = g_strndup (parsed_edid->manufacturer_code, 4); output_info->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
if (!g_utf8_validate (output->vendor, -1, NULL)) if (!g_utf8_validate (output_info->vendor, -1, NULL))
g_clear_pointer (&output->vendor, g_free); g_clear_pointer (&output_info->vendor, g_free);
output->product = g_strndup (parsed_edid->dsc_product_name, 14); output_info->product = g_strndup (parsed_edid->dsc_product_name, 14);
if (!g_utf8_validate (output->product, -1, NULL) || if (!g_utf8_validate (output_info->product, -1, NULL) ||
output->product[0] == '\0') output_info->product[0] == '\0')
{ {
g_clear_pointer (&output->product, g_free); g_clear_pointer (&output_info->product, g_free);
output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code); output_info->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
} }
output->serial = g_strndup (parsed_edid->dsc_serial_number, 14); output_info->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
if (!g_utf8_validate (output->serial, -1, NULL) || if (!g_utf8_validate (output_info->serial, -1, NULL) ||
output->serial[0] == '\0') output_info->serial[0] == '\0')
{ {
g_clear_pointer (&output->serial, g_free); g_clear_pointer (&output_info->serial, g_free);
output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number); output_info->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
} }
g_free (parsed_edid); g_free (parsed_edid);
} }
out: out:
if (!output->vendor) if (!output_info->vendor)
output->vendor = g_strdup ("unknown"); output_info->vendor = g_strdup ("unknown");
if (!output->product) if (!output_info->product)
output->product = g_strdup ("unknown"); output_info->product = g_strdup ("unknown");
if (!output->serial) if (!output_info->serial)
output->serial = g_strdup ("unknown"); output_info->serial = g_strdup ("unknown");
} }
gboolean gboolean
meta_output_is_laptop (MetaOutput *output) 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_eDP:
case META_CONNECTOR_TYPE_LVDS: case META_CONNECTOR_TYPE_LVDS:

View File

@ -168,19 +168,28 @@ meta_monitor_spec_free (MetaMonitorSpec *monitor_spec)
g_free (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 static void
meta_monitor_generate_spec (MetaMonitor *monitor) meta_monitor_generate_spec (MetaMonitor *monitor)
{ {
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (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; MetaMonitorSpec *monitor_spec;
monitor_spec = g_new0 (MetaMonitorSpec, 1); monitor_spec = g_new0 (MetaMonitorSpec, 1);
*monitor_spec = (MetaMonitorSpec) { *monitor_spec = (MetaMonitorSpec) {
.connector = g_strdup (output->name), .connector = g_strdup (output_info->name),
.vendor = g_strdup (output->vendor), .vendor = g_strdup (output_info->vendor),
.product = g_strdup (output->product), .product = g_strdup (output_info->product),
.serial = g_strdup (output->serial), .serial = g_strdup (output_info->serial),
}; };
priv->spec = monitor_spec; priv->spec = monitor_spec;
@ -322,11 +331,10 @@ meta_monitor_is_primary (MetaMonitor *monitor)
gboolean gboolean
meta_monitor_supports_underscanning (MetaMonitor *monitor) 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_info->supports_underscanning;
return output->supports_underscanning;
} }
gboolean gboolean
@ -342,11 +350,10 @@ meta_monitor_is_underscanning (MetaMonitor *monitor)
gboolean gboolean
meta_monitor_is_laptop_panel (MetaMonitor *monitor) 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_info->connector_type)
switch (output->connector_type)
{ {
case META_CONNECTOR_TYPE_eDP: case META_CONNECTOR_TYPE_eDP:
case META_CONNECTOR_TYPE_LVDS: case META_CONNECTOR_TYPE_LVDS:
@ -392,65 +399,65 @@ meta_monitor_get_physical_dimensions (MetaMonitor *monitor,
int *width_mm, int *width_mm,
int *height_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_info->width_mm;
*width_mm = output->width_mm; *height_mm = output_info->height_mm;
*height_mm = output->height_mm;
} }
CoglSubpixelOrder CoglSubpixelOrder
meta_monitor_get_subpixel_order (MetaMonitor *monitor) 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_info->subpixel_order;
return output->subpixel_order;
} }
const char * const char *
meta_monitor_get_connector (MetaMonitor *monitor) 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_info->name;
return output->name;
} }
const char * const char *
meta_monitor_get_vendor (MetaMonitor *monitor) 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_info->vendor;
return output->vendor;
} }
const char * const char *
meta_monitor_get_product (MetaMonitor *monitor) 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_info->product;
return output->product;
} }
const char * const char *
meta_monitor_get_serial (MetaMonitor *monitor) 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_info->serial;
return output->serial;
} }
MetaConnectorType MetaConnectorType
meta_monitor_get_connector_type (MetaMonitor *monitor) 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_info->connector_type;
return output->connector_type;
} }
MetaMonitorTransform MetaMonitorTransform
@ -562,9 +569,10 @@ meta_monitor_create_spec (MetaMonitor *monitor,
int height, int height,
MetaCrtcMode *crtc_mode) 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; int temp = width;
width = height; width = height;
@ -586,15 +594,17 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
MetaMonitorPrivate *monitor_priv = MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor); meta_monitor_get_instance_private (monitor);
MetaOutput *output; MetaOutput *output;
const MetaOutputInfo *output_info;
MetaCrtcModeFlag preferred_mode_flags; MetaCrtcModeFlag preferred_mode_flags;
unsigned int i; unsigned int i;
output = meta_monitor_get_main_output (monitor); 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; MetaCrtc *crtc;
MetaMonitorMode *mode; MetaMonitorMode *mode;
gboolean replace; gboolean replace;
@ -623,12 +633,12 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
if (!meta_monitor_add_mode (monitor, mode, replace)) 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); meta_monitor_mode_free (mode);
continue; continue;
} }
if (crtc_mode == output->preferred_mode) if (crtc_mode == output_info->preferred_mode)
monitor_priv->preferred_mode = mode; monitor_priv->preferred_mode = mode;
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
@ -697,14 +707,14 @@ meta_monitor_normal_get_suggested_position (MetaMonitor *monitor,
int *x, int *x,
int *y) int *y)
{ {
MetaOutput *output; const MetaOutputInfo *output_info =
meta_monitor_get_main_output_info (monitor);
output = meta_monitor_get_main_output (monitor); if (output_info->suggested_x < 0 && output_info->suggested_y < 0)
if (output->suggested_x < 0 && output->suggested_y < 0)
return FALSE; return FALSE;
*x = output->suggested_x; *x = output_info->suggested_x;
*y = output->suggested_y; *y = output_info->suggested_y;
return TRUE; return TRUE;
} }
@ -765,12 +775,15 @@ add_tiled_monitor_outputs (MetaGpu *gpu,
for (l = outputs; l; l = l->next) for (l = outputs; l; l = l->next)
{ {
MetaOutput *output = l->data; 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; continue;
g_warn_if_fail (output->subpixel_order == origin_output_info = meta_output_get_info (monitor_tiled->origin_output);
monitor_tiled->origin_output->subpixel_order); g_warn_if_fail (output_info->subpixel_order ==
origin_output_info->subpixel_order);
monitor_priv->outputs = g_list_append (monitor_priv->outputs, monitor_priv->outputs = g_list_append (monitor_priv->outputs,
g_object_ref (output)); g_object_ref (output));
@ -786,51 +799,68 @@ calculate_tile_coordinate (MetaMonitor *monitor,
{ {
MetaMonitorPrivate *monitor_priv = MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor); meta_monitor_get_instance_private (monitor);
const MetaOutputInfo *output_info = meta_output_get_info (output);
GList *l; GList *l;
int x = 0; int x = 0;
int y = 0; int y = 0;
for (l = monitor_priv->outputs; l; l = l->next) 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) switch (crtc_transform)
{ {
case META_MONITOR_TRANSFORM_NORMAL: case META_MONITOR_TRANSFORM_NORMAL:
case META_MONITOR_TRANSFORM_FLIPPED: case META_MONITOR_TRANSFORM_FLIPPED:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && if ((other_output_info->tile_info.loc_v_tile ==
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile) output_info->tile_info.loc_v_tile) &&
x += other_output->tile_info.tile_w; (other_output_info->tile_info.loc_h_tile <
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && output_info->tile_info.loc_h_tile))
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile) x += other_output_info->tile_info.tile_w;
y += other_output->tile_info.tile_h; 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; break;
case META_MONITOR_TRANSFORM_180: case META_MONITOR_TRANSFORM_180:
case META_MONITOR_TRANSFORM_FLIPPED_180: case META_MONITOR_TRANSFORM_FLIPPED_180:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && if ((other_output_info->tile_info.loc_v_tile ==
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile) output_info->tile_info.loc_v_tile) &&
x += other_output->tile_info.tile_w; (other_output_info->tile_info.loc_h_tile >
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && output_info->tile_info.loc_h_tile))
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile) x += other_output_info->tile_info.tile_w;
y += other_output->tile_info.tile_h; 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; break;
case META_MONITOR_TRANSFORM_270: case META_MONITOR_TRANSFORM_270:
case META_MONITOR_TRANSFORM_FLIPPED_270: case META_MONITOR_TRANSFORM_FLIPPED_270:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && if ((other_output_info->tile_info.loc_v_tile ==
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile) output_info->tile_info.loc_v_tile) &&
y += other_output->tile_info.tile_w; (other_output_info->tile_info.loc_h_tile >
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && output_info->tile_info.loc_h_tile))
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile) y += other_output_info->tile_info.tile_w;
x += other_output->tile_info.tile_h; 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; break;
case META_MONITOR_TRANSFORM_90: case META_MONITOR_TRANSFORM_90:
case META_MONITOR_TRANSFORM_FLIPPED_90: case META_MONITOR_TRANSFORM_FLIPPED_90:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && if ((other_output_info->tile_info.loc_v_tile ==
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile) output_info->tile_info.loc_v_tile) &&
y += other_output->tile_info.tile_w; (other_output_info->tile_info.loc_h_tile <
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && output_info->tile_info.loc_h_tile))
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile) y += other_output_info->tile_info.tile_w;
x += other_output->tile_info.tile_h; 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; break;
} }
} }
@ -854,13 +884,13 @@ meta_monitor_tiled_calculate_tiled_size (MetaMonitor *monitor,
height = 0; height = 0;
for (l = monitor_priv->outputs; l; l = l->next) 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) if (output_info->tile_info.loc_v_tile == 0)
width += output->tile_info.tile_w; width += output_info->tile_info.tile_w;
if (output->tile_info.loc_h_tile == 0) if (output_info->tile_info.loc_h_tile == 0)
height += output->tile_info.tile_h; height += output_info->tile_info.tile_h;
} }
*out_width = width; *out_width = width;
@ -897,24 +927,27 @@ static gboolean
is_crtc_mode_tiled (MetaOutput *output, is_crtc_mode_tiled (MetaOutput *output,
MetaCrtcMode *crtc_mode) MetaCrtcMode *crtc_mode)
{ {
return (crtc_mode->width == (int) output->tile_info.tile_w && const MetaOutputInfo *output_info = meta_output_get_info (output);
crtc_mode->height == (int) output->tile_info.tile_h);
return (crtc_mode->width == (int) output_info->tile_info.tile_w &&
crtc_mode->height == (int) output_info->tile_info.tile_h);
} }
static MetaCrtcMode * static MetaCrtcMode *
find_tiled_crtc_mode (MetaOutput *output, find_tiled_crtc_mode (MetaOutput *output,
MetaCrtcMode *reference_crtc_mode) MetaCrtcMode *reference_crtc_mode)
{ {
const MetaOutputInfo *output_info = meta_output_get_info (output);
MetaCrtcMode *crtc_mode; MetaCrtcMode *crtc_mode;
unsigned int i; unsigned int i;
crtc_mode = output->preferred_mode; crtc_mode = output_info->preferred_mode;
if (is_crtc_mode_tiled (output, crtc_mode)) if (is_crtc_mode_tiled (output, crtc_mode))
return 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)) if (!is_crtc_mode_tiled (output, crtc_mode))
continue; continue;
@ -958,12 +991,13 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++)
{ {
MetaOutput *output = l->data; MetaOutput *output = l->data;
const MetaOutputInfo *output_info = meta_output_get_info (output);
MetaCrtcMode *tiled_crtc_mode; MetaCrtcMode *tiled_crtc_mode;
tiled_crtc_mode = find_tiled_crtc_mode (output, reference_crtc_mode); tiled_crtc_mode = find_tiled_crtc_mode (output, reference_crtc_mode);
if (!tiled_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); meta_monitor_mode_free ((MetaMonitorMode *) mode);
return NULL; return NULL;
} }
@ -973,7 +1007,8 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
.crtc_mode = tiled_crtc_mode .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; *out_is_preferred = is_preferred;
@ -988,16 +1023,18 @@ generate_tiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
MetaMonitorPrivate *monitor_priv = MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor); meta_monitor_get_instance_private (monitor);
MetaOutput *main_output; MetaOutput *main_output;
const MetaOutputInfo *main_output_info;
GList *tiled_modes = NULL; GList *tiled_modes = NULL;
unsigned int i; unsigned int i;
MetaMonitorMode *best_mode = NULL; MetaMonitorMode *best_mode = NULL;
GList *l; GList *l;
main_output = meta_monitor_get_main_output (META_MONITOR (monitor_tiled)); 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; MetaMonitorMode *mode;
gboolean is_preferred; gboolean is_preferred;
@ -1094,13 +1131,14 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
static int static int
count_untiled_crtc_modes (MetaOutput *output) count_untiled_crtc_modes (MetaOutput *output)
{ {
const MetaOutputInfo *output_info = meta_output_get_info (output);
int count; int count;
unsigned int i; unsigned int i;
count = 0; 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)) if (!is_crtc_mode_tiled (output, crtc_mode))
count++; count++;
@ -1149,13 +1187,15 @@ generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
MetaMonitorPrivate *monitor_priv = MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor); meta_monitor_get_instance_private (monitor);
MetaOutput *main_output; MetaOutput *main_output;
const MetaOutputInfo *main_output_info;
unsigned int i; unsigned int i;
main_output = meta_monitor_get_main_output (monitor); 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; MetaMonitorMode *mode;
mode = create_untiled_monitor_mode (monitor_tiled, mode = create_untiled_monitor_mode (monitor_tiled,
@ -1177,7 +1217,7 @@ generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
} }
if (!monitor_priv->preferred_mode && if (!monitor_priv->preferred_mode &&
crtc_mode == main_output->preferred_mode) crtc_mode == main_output_info->preferred_mode)
monitor_priv->preferred_mode = mode; monitor_priv->preferred_mode = mode;
} }
} }
@ -1281,6 +1321,7 @@ meta_monitor_tiled_new (MetaGpu *gpu,
MetaMonitorManager *monitor_manager, MetaMonitorManager *monitor_manager,
MetaOutput *output) MetaOutput *output)
{ {
const MetaOutputInfo *output_info = meta_output_get_info (output);
MetaMonitorTiled *monitor_tiled; MetaMonitorTiled *monitor_tiled;
MetaMonitor *monitor; MetaMonitor *monitor;
MetaMonitorPrivate *monitor_priv; MetaMonitorPrivate *monitor_priv;
@ -1291,7 +1332,7 @@ meta_monitor_tiled_new (MetaGpu *gpu,
monitor_priv->gpu = 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_priv->winsys_id = meta_output_get_id (output);
monitor_tiled->origin_output = output; monitor_tiled->origin_output = output;

View File

@ -27,6 +27,7 @@ enum
PROP_ID, PROP_ID,
PROP_GPU, PROP_GPU,
PROP_INFO,
N_PROPS N_PROPS
}; };
@ -39,6 +40,8 @@ typedef struct _MetaOutputPrivate
MetaGpu *gpu; MetaGpu *gpu;
MetaOutputInfo *info;
/* The CRTC driving this output, NULL if the output is not enabled */ /* The CRTC driving this output, NULL if the output is not enabled */
MetaCrtc *crtc; MetaCrtc *crtc;
@ -52,6 +55,44 @@ typedef struct _MetaOutputPrivate
G_DEFINE_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT) 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 uint64_t
meta_output_get_id (MetaOutput *output) meta_output_get_id (MetaOutput *output)
{ {
@ -71,7 +112,9 @@ meta_output_get_gpu (MetaOutput *output)
const char * const char *
meta_output_get_name (MetaOutput *output) meta_output_get_name (MetaOutput *output)
{ {
return output->name; MetaOutputPrivate *priv = meta_output_get_instance_private (output);
return priv->info->name;
} }
gboolean gboolean
@ -115,6 +158,29 @@ meta_output_get_backlight (MetaOutput *output)
return priv->backlight; 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 void
meta_output_assign_crtc (MetaOutput *output, meta_output_assign_crtc (MetaOutput *output,
MetaCrtc *crtc, MetaCrtc *crtc,
@ -154,9 +220,10 @@ MetaMonitorTransform
meta_output_logical_to_crtc_transform (MetaOutput *output, meta_output_logical_to_crtc_transform (MetaOutput *output,
MetaMonitorTransform transform) MetaMonitorTransform transform)
{ {
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
MetaMonitorTransform panel_orientation_transform; 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, return meta_monitor_transform_transform (transform,
panel_orientation_transform); panel_orientation_transform);
} }
@ -165,10 +232,11 @@ MetaMonitorTransform
meta_output_crtc_to_logical_transform (MetaOutput *output, meta_output_crtc_to_logical_transform (MetaOutput *output,
MetaMonitorTransform transform) MetaMonitorTransform transform)
{ {
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
MetaMonitorTransform inverted_panel_orientation_transform; MetaMonitorTransform inverted_panel_orientation_transform;
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, return meta_monitor_transform_transform (transform,
inverted_panel_orientation_transform); inverted_panel_orientation_transform);
} }
@ -190,6 +258,9 @@ meta_output_set_property (GObject *object,
case PROP_GPU: case PROP_GPU:
priv->gpu = g_value_get_object (value); priv->gpu = g_value_get_object (value);
break; break;
case PROP_INFO:
priv->info = meta_output_info_ref (g_value_get_boxed (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
@ -212,6 +283,9 @@ meta_output_get_property (GObject *object,
case PROP_GPU: case PROP_GPU:
g_value_set_object (value, priv->gpu); g_value_set_object (value, priv->gpu);
break; break;
case PROP_INFO:
g_value_set_boxed (value, priv->info);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
@ -232,18 +306,13 @@ static void
meta_output_finalize (GObject *object) meta_output_finalize (GObject *object)
{ {
MetaOutput *output = META_OUTPUT (object); MetaOutput *output = META_OUTPUT (object);
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
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);
if (output->driver_notify) if (output->driver_notify)
output->driver_notify (output); output->driver_notify (output);
g_clear_pointer (&priv->info, meta_output_info_unref);
G_OBJECT_CLASS (meta_output_parent_class)->finalize (object); G_OBJECT_CLASS (meta_output_parent_class)->finalize (object);
} }
@ -281,5 +350,13 @@ meta_output_class_init (MetaOutputClass *klass)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS); 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); g_object_class_install_properties (object_class, N_PROPS, obj_props);
} }

View File

@ -60,9 +60,9 @@ typedef enum
META_CONNECTOR_TYPE_DSI = 16, META_CONNECTOR_TYPE_DSI = 16,
} MetaConnectorType; } MetaConnectorType;
struct _MetaOutput typedef struct _MetaOutputInfo
{ {
GObject parent; grefcount ref_count;
char *name; char *name;
char *vendor; char *vendor;
@ -90,9 +90,6 @@ struct _MetaOutput
gboolean supports_underscanning; gboolean supports_underscanning;
gpointer driver_private;
GDestroyNotify driver_notify;
/* /*
* Get a new preferred mode on hotplug events, to handle dynamic guest * Get a new preferred mode on hotplug events, to handle dynamic guest
* resizing. * resizing.
@ -102,8 +99,35 @@ struct _MetaOutput
int suggested_y; int suggested_y;
MetaTileInfo tile_info; 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 ()) #define META_TYPE_OUTPUT (meta_output_get_type ())
META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject) 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); 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 META_EXPORT_TEST
void meta_output_assign_crtc (MetaOutput *output, void meta_output_assign_crtc (MetaOutput *output,
MetaCrtc *crtc, MetaCrtc *crtc,

View File

@ -264,9 +264,12 @@ static int
compare_outputs (gconstpointer one, compare_outputs (gconstpointer one,
gconstpointer two) 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 static void
@ -389,14 +392,7 @@ setup_output_clones (MetaGpu *gpu)
continue; continue;
if (meta_output_kms_can_clone (output, other_output)) if (meta_output_kms_can_clone (output, other_output))
{ meta_output_add_possible_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;
}
} }
} }
} }

View File

@ -57,8 +57,9 @@ meta_output_kms_set_underscan (MetaOutput *output,
MetaKmsUpdate *kms_update) MetaKmsUpdate *kms_update)
{ {
MetaOutputKms *output_kms = output->driver_private; 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; return;
if (meta_output_is_underscanning (output)) if (meta_output_is_underscanning (output))
@ -153,7 +154,7 @@ meta_output_destroy_notify (MetaOutput *output)
} }
static void static void
add_common_modes (MetaOutput *output, add_common_modes (MetaOutputInfo *output_info,
MetaGpuKms *gpu_kms) MetaGpuKms *gpu_kms)
{ {
const drmModeModeInfo *drm_mode; const drmModeModeInfo *drm_mode;
@ -165,9 +166,9 @@ add_common_modes (MetaOutput *output,
unsigned max_vdisplay = 0; unsigned max_vdisplay = 0;
float max_refresh_rate = 0.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); refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
max_hdisplay = MAX (max_hdisplay, drm_mode->hdisplay); max_hdisplay = MAX (max_hdisplay, drm_mode->hdisplay);
max_vdisplay = MAX (max_vdisplay, drm_mode->vdisplay); 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_info->modes = g_renew (MetaCrtcMode *, output_info->modes,
output->n_modes + array->len); output_info->n_modes + array->len);
memcpy (output->modes + output->n_modes, array->pdata, memcpy (output_info->modes + output_info->n_modes, array->pdata,
array->len * sizeof (MetaCrtcMode *)); array->len * sizeof (MetaCrtcMode *));
output->n_modes += array->len; output_info->n_modes += array->len;
g_ptr_array_free (array, TRUE); g_ptr_array_free (array, TRUE);
} }
@ -238,30 +239,29 @@ compare_modes (const void *one,
} }
static gboolean static gboolean
init_output_modes (MetaOutput *output, init_output_modes (MetaOutputInfo *output_info,
MetaGpuKms *gpu_kms, MetaGpuKms *gpu_kms,
MetaKmsConnector *kms_connector,
GError **error) GError **error)
{ {
MetaOutputKms *output_kms = output->driver_private;
const MetaKmsConnectorState *connector_state; const MetaKmsConnectorState *connector_state;
int i; int i;
connector_state = connector_state = meta_kms_connector_get_current_state (kms_connector);
meta_kms_connector_get_current_state (output_kms->kms_connector);
output->preferred_mode = NULL; output_info->preferred_mode = NULL;
output->n_modes = connector_state->n_modes; output_info->n_modes = connector_state->n_modes;
output->modes = g_new0 (MetaCrtcMode *, output->n_modes); output_info->modes = g_new0 (MetaCrtcMode *, output_info->n_modes);
for (i = 0; i < connector_state->n_modes; i++) for (i = 0; i < connector_state->n_modes; i++)
{ {
drmModeModeInfo *drm_mode = &connector_state->modes[i]; drmModeModeInfo *drm_mode = &connector_state->modes[i];
MetaCrtcMode *crtc_mode; MetaCrtcMode *crtc_mode;
crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, drm_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) 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? */ /* FIXME: MSC feature bit? */
@ -269,20 +269,20 @@ init_output_modes (MetaOutput *output,
* a panel fitter capable of adjusting any mode to suit. * a panel fitter capable of adjusting any mode to suit.
*/ */
if (connector_state->has_scaling) 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, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"No modes available"); "No modes available");
return FALSE; return FALSE;
} }
qsort (output->modes, output->n_modes, qsort (output_info->modes, output_info->n_modes,
sizeof (MetaCrtcMode *), compare_modes); sizeof (MetaCrtcMode *), compare_modes);
if (!output->preferred_mode) if (!output_info->preferred_mode)
output->preferred_mode = output->modes[0]; output_info->preferred_mode = output_info->modes[0];
return TRUE; return TRUE;
} }
@ -296,6 +296,7 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
MetaGpu *gpu = META_GPU (gpu_kms); MetaGpu *gpu = META_GPU (gpu_kms);
uint32_t connector_id; uint32_t connector_id;
uint32_t gpu_id; uint32_t gpu_id;
g_autoptr (MetaOutputInfo) output_info = NULL;
MetaOutput *output; MetaOutput *output;
MetaOutputKms *output_kms; MetaOutputKms *output_kms;
const MetaKmsConnectorState *connector_state; const MetaKmsConnectorState *connector_state;
@ -305,39 +306,26 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
gpu_id = meta_gpu_kms_get_id (gpu_kms); gpu_id = meta_gpu_kms_get_id (gpu_kms);
connector_id = meta_kms_connector_get_id (kms_connector); connector_id = meta_kms_connector_get_id (kms_connector);
output = g_object_new (META_TYPE_OUTPUT, output_info = meta_output_info_new ();
"id", ((uint64_t) gpu_id << 32) | connector_id, output_info->name = g_strdup (meta_kms_connector_get_name (kms_connector));
"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;
connector_state = meta_kms_connector_get_current_state (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; 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_info->width_mm = connector_state->height_mm;
output->height_mm = connector_state->width_mm; output_info->height_mm = connector_state->width_mm;
} }
else else
{ {
output->width_mm = connector_state->width_mm; output_info->width_mm = connector_state->width_mm;
output->height_mm = connector_state->height_mm; output_info->height_mm = connector_state->height_mm;
} }
if (!init_output_modes (output, gpu_kms, error)) if (!init_output_modes (output_info, gpu_kms, kms_connector, error))
{
g_object_unref (output);
return NULL; return NULL;
}
crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCrtc *)); 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); g_array_append_val (crtcs, crtc);
} }
output->n_possible_crtcs = crtcs->len; output_info->n_possible_crtcs = crtcs->len;
output->possible_crtcs = (MetaCrtc **) g_array_free (crtcs, FALSE); 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) if (connector_state->current_crtc_id)
{ {
@ -389,29 +401,5 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
meta_output_unassign_crtc (output); 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; return output;
} }

View File

@ -69,9 +69,12 @@ static int
compare_outputs (const void *one, compare_outputs (const void *one,
const void *two) 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 * static char *
@ -210,11 +213,12 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
for (l = outputs; l; l = l->next) for (l = outputs; l; l = l->next)
{ {
MetaOutput *output = l->data; MetaOutput *output = l->data;
const MetaOutputInfo *output_info = meta_output_get_info (output);
GList *k; 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) 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)) if (clone == (XID) meta_output_get_id (possible_clone))
{ {
output->possible_clones[j] = possible_clone; output_info->possible_clones[j] = possible_clone;
break; break;
} }
} }

View File

@ -47,9 +47,8 @@
#include "meta/util.h" #include "meta/util.h"
static Display * 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); MetaBackend *backend = meta_gpu_get_backend (gpu);
MetaMonitorManager *monitor_manager = MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend); 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); 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 static void
output_set_presentation_xrandr (MetaOutput *output, output_set_presentation_xrandr (MetaOutput *output,
gboolean presentation) gboolean presentation)
@ -140,7 +145,7 @@ meta_output_xrandr_apply_mode (MetaOutput *output)
output_set_presentation_xrandr (output, meta_output_is_presentation (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, output_set_underscanning_xrandr (output,
meta_output_is_underscanning (output)); meta_output_is_underscanning (output));
@ -151,20 +156,23 @@ static int
normalize_backlight (MetaOutput *output, normalize_backlight (MetaOutput *output,
int hw_value) int hw_value)
{ {
return round ((double)(hw_value - output->backlight_min) / const MetaOutputInfo *output_info = meta_output_get_info (output);
(output->backlight_max - output->backlight_min) * 100.0);
return round ((double) (hw_value - output_info->backlight_min) /
(output_info->backlight_max - output_info->backlight_min) * 100.0);
} }
void void
meta_output_xrandr_change_backlight (MetaOutput *output, meta_output_xrandr_change_backlight (MetaOutput *output,
int value) int value)
{ {
const MetaOutputInfo *output_info = meta_output_get_info (output);
Display *xdisplay = xdisplay_from_output (output); Display *xdisplay = xdisplay_from_output (output);
Atom atom; Atom atom;
int hw_value; int hw_value;
hw_value = round ((double) value / 100.0 * output->backlight_max + hw_value = round ((double) value / 100.0 * output_info->backlight_max +
output->backlight_min); output_info->backlight_min);
atom = XInternAtom (xdisplay, "Backlight", False); atom = XInternAtom (xdisplay, "Backlight", False);
@ -179,11 +187,11 @@ meta_output_xrandr_change_backlight (MetaOutput *output,
} }
static gboolean static gboolean
output_get_integer_property (MetaOutput *output, output_get_integer_property (Display *xdisplay,
RROutput output_id,
const char *propname, const char *propname,
gint *value) gint *value)
{ {
Display *xdisplay = xdisplay_from_output (output);
gboolean exists = FALSE; gboolean exists = FALSE;
Atom atom, actual_type; Atom atom, actual_type;
int actual_format; int actual_format;
@ -192,7 +200,7 @@ output_get_integer_property (MetaOutput *output,
atom = XInternAtom (xdisplay, propname, False); atom = XInternAtom (xdisplay, propname, False);
XRRGetOutputProperty (xdisplay, XRRGetOutputProperty (xdisplay,
(XID) meta_output_get_id (output), (XID) output_id,
atom, atom,
0, G_MAXLONG, False, False, XA_INTEGER, 0, G_MAXLONG, False, False, XA_INTEGER,
&actual_type, &actual_format, &actual_type, &actual_format,
@ -208,10 +216,10 @@ output_get_integer_property (MetaOutput *output,
} }
static gboolean static gboolean
output_get_property_exists (MetaOutput *output, output_get_property_exists (Display *xdisplay,
RROutput output_id,
const char *propname) const char *propname)
{ {
Display *xdisplay = xdisplay_from_output (output);
gboolean exists = FALSE; gboolean exists = FALSE;
Atom atom, actual_type; Atom atom, actual_type;
int actual_format; int actual_format;
@ -220,7 +228,7 @@ output_get_property_exists (MetaOutput *output,
atom = XInternAtom (xdisplay, propname, False); atom = XInternAtom (xdisplay, propname, False);
XRRGetOutputProperty (xdisplay, XRRGetOutputProperty (xdisplay,
(XID) meta_output_get_id (output), (XID) output_id,
atom, atom,
0, G_MAXLONG, False, False, AnyPropertyType, 0, G_MAXLONG, False, False, AnyPropertyType,
&actual_type, &actual_format, &actual_type, &actual_format,
@ -288,9 +296,9 @@ output_get_underscanning_xrandr (MetaOutput *output)
} }
static gboolean 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; Atom atom, actual_type;
int actual_format, i; int actual_format, i;
unsigned long nitems, bytes_after; unsigned long nitems, bytes_after;
@ -301,7 +309,7 @@ output_get_supports_underscanning_xrandr (MetaOutput *output)
atom = XInternAtom (xdisplay, "underscan", False); atom = XInternAtom (xdisplay, "underscan", False);
XRRGetOutputProperty (xdisplay, XRRGetOutputProperty (xdisplay,
(XID) meta_output_get_id (output), (XID) output_id,
atom, atom,
0, G_MAXLONG, False, False, XA_ATOM, 0, G_MAXLONG, False, False, XA_ATOM,
&actual_type, &actual_format, &actual_type, &actual_format,
@ -311,7 +319,7 @@ output_get_supports_underscanning_xrandr (MetaOutput *output)
return FALSE; return FALSE;
property_info = XRRQueryOutputProperty (xdisplay, property_info = XRRQueryOutputProperty (xdisplay,
(XID) meta_output_get_id (output), (XID) output_id,
atom); atom);
values = (Atom *) property_info->values; values = (Atom *) property_info->values;
@ -361,19 +369,18 @@ output_get_backlight_xrandr (MetaOutput *output)
} }
static void 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; Atom atom;
xcb_connection_t *xcb_conn; xcb_connection_t *xcb_conn;
xcb_randr_output_t output_id;
xcb_randr_query_output_property_cookie_t cookie; xcb_randr_query_output_property_cookie_t cookie;
g_autofree xcb_randr_query_output_property_reply_t *reply = NULL; g_autofree xcb_randr_query_output_property_reply_t *reply = NULL;
atom = XInternAtom (xdisplay, "Backlight", False); atom = XInternAtom (xdisplay, "Backlight", False);
xcb_conn = XGetXCBConnection (xdisplay); xcb_conn = XGetXCBConnection (xdisplay);
output_id = meta_output_get_id (output);
cookie = xcb_randr_query_output_property (xcb_conn, cookie = xcb_randr_query_output_property (xcb_conn,
output_id, output_id,
(xcb_atom_t) atom); (xcb_atom_t) atom);
@ -387,13 +394,13 @@ output_get_backlight_limits_xrandr (MetaOutput *output)
if (!reply->range || reply->length != 2) 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; return;
} }
int32_t *values = xcb_randr_query_output_property_valid_values (reply); int32_t *values = xcb_randr_query_output_property_valid_values (reply);
output->backlight_min = values[0]; output_info->backlight_min = values[0];
output->backlight_max = values[1]; output_info->backlight_max = values[1];
} }
static guint8 * static guint8 *
@ -430,27 +437,21 @@ get_edid_property (Display *xdisplay,
return result; return result;
} }
GBytes * static GBytes *
meta_output_xrandr_read_edid (MetaOutput *output) read_xrandr_edid (Display *xdisplay,
RROutput output_id)
{ {
Display *xdisplay = xdisplay_from_output (output);
Atom edid_atom; Atom edid_atom;
guint8 *result; guint8 *result;
gsize len; gsize len;
edid_atom = XInternAtom (xdisplay, "EDID", FALSE); edid_atom = XInternAtom (xdisplay, "EDID", FALSE);
result = get_edid_property (xdisplay, result = get_edid_property (xdisplay, output_id, edid_atom, &len);
meta_output_get_id (output),
edid_atom,
&len);
if (!result) if (!result)
{ {
edid_atom = XInternAtom (xdisplay, "EDID_DATA", FALSE); edid_atom = XInternAtom (xdisplay, "EDID_DATA", FALSE);
result = get_edid_property (xdisplay, result = get_edid_property (xdisplay, output_id, edid_atom, &len);
meta_output_get_id (output),
edid_atom,
&len);
} }
if (result) if (result)
@ -464,27 +465,39 @@ meta_output_xrandr_read_edid (MetaOutput *output)
return NULL; return NULL;
} }
static gboolean GBytes *
output_get_hotplug_mode_update (MetaOutput *output) 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 static gint
output_get_suggested_x (MetaOutput *output) output_get_suggested_x (Display *xdisplay,
RROutput output_id)
{ {
gint val; 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 val;
return -1; return -1;
} }
static gint static gint
output_get_suggested_y (MetaOutput *output) output_get_suggested_y (Display *xdisplay,
RROutput output_id)
{ {
gint val; 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 val;
return -1; return -1;
@ -528,9 +541,9 @@ connector_type_from_atom (Display *xdisplay,
} }
static MetaConnectorType 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; Atom atom, actual_type, connector_type_atom;
int actual_format; int actual_format;
unsigned long nitems, bytes_after; unsigned long nitems, bytes_after;
@ -538,7 +551,7 @@ output_get_connector_type_from_prop (MetaOutput *output)
atom = XInternAtom (xdisplay, "ConnectorType", False); atom = XInternAtom (xdisplay, "ConnectorType", False);
XRRGetOutputProperty (xdisplay, XRRGetOutputProperty (xdisplay,
(XID) meta_output_get_id (output), (XID) output_id,
atom, atom,
0, G_MAXLONG, False, False, XA_ATOM, 0, G_MAXLONG, False, False, XA_ATOM,
&actual_type, &actual_format, &actual_type, &actual_format,
@ -552,9 +565,9 @@ output_get_connector_type_from_prop (MetaOutput *output)
} }
static MetaConnectorType 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 /* drmmode_display.c, which was copy/pasted across all the FOSS
* xf86-video-* drivers, seems to name its outputs based on the * 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 static MetaConnectorType
output_get_connector_type (MetaOutput *output) output_info_get_connector_type (MetaOutputInfo *output_info,
Display *xdisplay,
RROutput output_id)
{ {
MetaConnectorType ret; MetaConnectorType ret;
@ -611,12 +626,12 @@ output_get_connector_type (MetaOutput *output)
* Try poking it first, without any expectations that it will work. * Try poking it first, without any expectations that it will work.
* If it's not there, we thankfully have other bonghits to try next. * 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) if (ret != META_CONNECTOR_TYPE_Unknown)
return ret; return ret;
/* Fall back to heuristics based on the output name. */ /* 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) if (ret != META_CONNECTOR_TYPE_Unknown)
return ret; return ret;
@ -624,9 +639,9 @@ output_get_connector_type (MetaOutput *output)
} }
static gint 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; unsigned long nitems, bytes_after;
Atom atom, actual_type; Atom atom, actual_type;
int actual_format; int actual_format;
@ -635,7 +650,7 @@ output_get_panel_orientation_transform (MetaOutput *output)
atom = XInternAtom (xdisplay, "panel orientation", False); atom = XInternAtom (xdisplay, "panel orientation", False);
XRRGetOutputProperty (xdisplay, XRRGetOutputProperty (xdisplay,
(XID) meta_output_get_id (output), (XID) output_id,
atom, atom,
0, G_MAXLONG, False, False, XA_ATOM, 0, G_MAXLONG, False, False, XA_ATOM,
&actual_type, &actual_format, &actual_type, &actual_format,
@ -658,27 +673,19 @@ output_get_panel_orientation_transform (MetaOutput *output)
} }
static void 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; Atom tile_atom;
unsigned char *prop; unsigned char *prop;
unsigned long nitems, bytes_after; unsigned long nitems, bytes_after;
int actual_format; int actual_format;
Atom actual_type; Atom actual_type;
if (!meta_monitor_manager_xrandr_has_randr15 (monitor_manager_xrandr))
return;
tile_atom = XInternAtom (xdisplay, "TILE", FALSE); tile_atom = XInternAtom (xdisplay, "TILE", FALSE);
XRRGetOutputProperty (xdisplay, XRRGetOutputProperty (xdisplay,
(XID) meta_output_get_id (output), (XID) output_id,
tile_atom, 0, 100, False, tile_atom, 0, 100, False,
False, AnyPropertyType, False, AnyPropertyType,
&actual_type, &actual_format, &actual_type, &actual_format,
@ -687,28 +694,29 @@ output_get_tile_info (MetaOutput *output)
if (actual_type == XA_INTEGER && actual_format == 32 && nitems == 8) if (actual_type == XA_INTEGER && actual_format == 32 && nitems == 8)
{ {
long *values = (long *)prop; long *values = (long *)prop;
output->tile_info.group_id = values[0];
output->tile_info.flags = values[1]; output_info->tile_info.group_id = values[0];
output->tile_info.max_h_tiles = values[2]; output_info->tile_info.flags = values[1];
output->tile_info.max_v_tiles = values[3]; output_info->tile_info.max_h_tiles = values[2];
output->tile_info.loc_h_tile = values[4]; output_info->tile_info.max_v_tiles = values[3];
output->tile_info.loc_v_tile = values[5]; output_info->tile_info.loc_h_tile = values[4];
output->tile_info.tile_w = values[6]; output_info->tile_info.loc_v_tile = values[5];
output->tile_info.tile_h = values[7]; output_info->tile_info.tile_w = values[6];
output_info->tile_info.tile_h = values[7];
} }
XFree (prop); XFree (prop);
} }
static void static void
output_get_modes (MetaOutput *output, output_info_init_modes (MetaOutputInfo *output_info,
MetaGpu *gpu,
XRROutputInfo *xrandr_output) XRROutputInfo *xrandr_output)
{ {
MetaGpu *gpu = meta_output_get_gpu (output);
unsigned int i; unsigned int i;
unsigned int n_actual_modes; 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; n_actual_modes = 0;
for (i = 0; i < (unsigned int) xrandr_output->nmode; i++) 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) 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; n_actual_modes += 1;
break; break;
} }
} }
} }
output->n_modes = n_actual_modes; output_info->n_modes = n_actual_modes;
if (n_actual_modes > 0) if (n_actual_modes > 0)
output->preferred_mode = output->modes[0]; output_info->preferred_mode = output_info->modes[0];
} }
static void static void
output_get_crtcs (MetaOutput *output, output_info_init_crtcs (MetaOutputInfo *output_info,
XRROutputInfo *xrandr_output, MetaGpu *gpu,
MetaCrtc **assigned_crtc) XRROutputInfo *xrandr_output)
{ {
MetaGpu *gpu = meta_output_get_gpu (output);
unsigned int i; unsigned int i;
unsigned int n_actual_crtcs; unsigned int n_actual_crtcs;
GList *l; 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; n_actual_crtcs = 0;
for (i = 0; i < (unsigned int) xrandr_output->ncrtc; i++) 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]) 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; n_actual_crtcs += 1;
break; 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) for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
{ {
MetaCrtc *crtc = l->data; MetaCrtc *crtc = l->data;
if ((XID) meta_crtc_get_id (crtc) == xrandr_output->crtc) if ((XID) meta_crtc_get_id (crtc) == xrandr_output->crtc)
{ return crtc;
*assigned_crtc = crtc;
return;
}
} }
*assigned_crtc = NULL; return NULL;
} }
MetaOutput * MetaOutput *
@ -782,45 +792,80 @@ meta_create_xrandr_output (MetaGpuXrandr *gpu_xrandr,
RROutput output_id, RROutput output_id,
RROutput primary_output) 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; MetaOutput *output;
GBytes *edid; GBytes *edid;
MetaCrtc *assigned_crtc; MetaCrtc *assigned_crtc;
unsigned int i; unsigned int i;
output = g_object_new (META_TYPE_OUTPUT, output_info = meta_output_info_new ();
"id", output_id,
"gpu", gpu_xrandr,
NULL);
output->name = g_strdup (xrandr_output->name);
edid = meta_output_xrandr_read_edid (output); output_info->name = g_strdup (xrandr_output->name);
meta_output_parse_edid (output, edid);
edid = read_xrandr_edid (xdisplay, output_id);
meta_output_info_parse_edid (output_info, edid);
g_bytes_unref (edid); g_bytes_unref (edid);
output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
output->hotplug_mode_update = output_get_hotplug_mode_update (output); output_info->hotplug_mode_update = output_get_hotplug_mode_update (xdisplay,
output->suggested_x = output_get_suggested_x (output); output_id);
output->suggested_y = output_get_suggested_y (output); output_info->suggested_x = output_get_suggested_x (xdisplay, output_id);
output->connector_type = output_get_connector_type (output); output_info->suggested_y = output_get_suggested_y (xdisplay, output_id);
output->panel_orientation_transform = output_info->connector_type = output_info_get_connector_type (output_info,
output_get_panel_orientation_transform (output); xdisplay,
output_id);
output_info->panel_orientation_transform =
output_get_panel_orientation_transform (xdisplay, output_id);
if (meta_monitor_transform_is_rotated ( if (meta_monitor_transform_is_rotated (
output->panel_orientation_transform)) output_info->panel_orientation_transform))
{ {
output->width_mm = xrandr_output->mm_height; output_info->width_mm = xrandr_output->mm_height;
output->height_mm = xrandr_output->mm_width; output_info->height_mm = xrandr_output->mm_width;
} }
else else
{ {
output->width_mm = xrandr_output->mm_width; output_info->width_mm = xrandr_output->mm_width;
output->height_mm = xrandr_output->mm_height; output_info->height_mm = xrandr_output->mm_height;
} }
output_get_tile_info (output); if (!meta_monitor_manager_xrandr_has_randr15 (monitor_manager_xrandr))
output_get_modes (output, xrandr_output); output_info_init_tile_info (output_info, xdisplay, output_id);
output_get_crtcs (output, xrandr_output, &assigned_crtc); 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) if (assigned_crtc)
{ {
MetaOutputAssignment output_assignment; MetaOutputAssignment output_assignment;
@ -832,28 +877,15 @@ meta_create_xrandr_output (MetaGpuXrandr *gpu_xrandr,
}; };
meta_output_assign_crtc (output, assigned_crtc, &output_assignment); meta_output_assign_crtc (output, assigned_crtc, &output_assignment);
} }
else
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++)
{ {
output->possible_clones[i] = GINT_TO_POINTER (xrandr_output->clones[i]); meta_output_unassign_crtc (output);
} }
output->supports_underscanning = if (!(output_info->backlight_min == 0 && output_info->backlight_max == 0))
output_get_supports_underscanning_xrandr (output);
output_get_backlight_limits_xrandr (output);
if (!(output->backlight_min == 0 && output->backlight_max == 0))
meta_output_set_backlight (output, output_get_backlight_xrandr (output)); 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); g_object_unref (output);
return NULL; return NULL;

View File

@ -124,6 +124,7 @@ meta_test_headless_monitor_connect (void)
MetaGpu *gpu; MetaGpu *gpu;
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtc **possible_crtcs; MetaCrtc **possible_crtcs;
g_autoptr (MetaOutputInfo) output_info = NULL;
MetaOutput *output; MetaOutput *output;
GList *logical_monitors; GList *logical_monitors;
ClutterActor *stage; ClutterActor *stage;
@ -151,20 +152,25 @@ meta_test_headless_monitor_connect (void)
possible_crtcs = g_new0 (MetaCrtc *, 1); possible_crtcs = g_new0 (MetaCrtc *, 1);
possible_crtcs[0] = g_list_first (test_setup->crtcs)->data; 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, output = g_object_new (META_TYPE_OUTPUT,
"id", 1, "id", 1,
"gpu", gpu, "gpu", gpu,
"info", output_info,
NULL); 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); test_setup->outputs = g_list_append (NULL, output);
meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);

View File

@ -598,6 +598,7 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup,
int scale; int scale;
gboolean is_laptop_panel; gboolean is_laptop_panel;
const char *serial; const char *serial;
g_autoptr (MetaOutputInfo) output_info = NULL;
crtc_index = setup->outputs[i].crtc; crtc_index = setup->outputs[i].crtc;
if (crtc_index == -1) if (crtc_index == -1)
@ -649,9 +650,45 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup,
if (!serial) if (!serial)
serial = "0x123456"; 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, output = g_object_new (META_TYPE_OUTPUT,
"id", i, "id", i,
"gpu", test_get_gpu (), "gpu", test_get_gpu (),
"info", output_info,
NULL); NULL);
if (crtc) if (crtc)
@ -664,39 +701,6 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup,
meta_output_assign_crtc (output, crtc, &output_assignment); 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_private = output_test;
output->driver_notify = (GDestroyNotify) meta_output_test_destroy_notify; output->driver_notify = (GDestroyNotify) meta_output_test_destroy_notify;