Commit 9817a6aa authored by Jonas Ådahl's avatar Jonas Ådahl
Browse files

Make MetaOutput a GObject

Turn MetaOutput into a GObject and move it to a separate file. This
changes the storage format, resulting in changing the API for accessing
MetaOutputs from using an array, to using a GList.

https://bugzilla.gnome.org/show_bug.cgi?id=785381
parent 8185373b
......@@ -131,6 +131,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/meta-monitor-manager-dummy.h \
backends/meta-orientation-manager.c \
backends/meta-orientation-manager.h \
backends/meta-output.c \
backends/meta-output.h \
backends/meta-pointer-constraint.c \
backends/meta-pointer-constraint.h \
backends/meta-settings.c \
......
......@@ -21,9 +21,11 @@
#include "config.h"
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-backend-private.h"
#include "backends/meta-output.h"
G_DEFINE_TYPE (MetaLogicalMonitor, meta_logical_monitor, G_TYPE_OBJECT)
static MetaMonitor *
......
......@@ -26,6 +26,7 @@
#include "backends/meta-monitor-config-migration.h"
#include "backends/meta-monitor-config-store.h"
#include "backends/meta-monitor-manager-private.h"
#include "backends/meta-output.h"
#include "core/boxes-private.h"
#define CONFIG_HISTORY_MAX_SIZE 3
......
......@@ -33,6 +33,7 @@
#include "backends/meta-backend-private.h"
#include "backends/meta-monitor.h"
#include "backends/meta-monitor-config-manager.h"
#include "backends/meta-output.h"
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
......@@ -69,7 +70,7 @@ meta_output_dummy_notify_destroy (MetaOutput *output);
static void
append_monitor (GArray *modes,
GArray *crtcs,
GArray *outputs,
GList **outputs,
float scale)
{
MetaCrtcMode modes_decl[] = {
......@@ -86,8 +87,9 @@ append_monitor (GArray *modes,
};
MetaCrtc crtc;
MetaOutputDummy *output_dummy;
MetaOutput output;
MetaOutput *output;
unsigned int i;
unsigned int number;
for (i = 0; i < G_N_ELEMENTS (modes_decl); i++)
modes_decl[i].mode_id = modes->len + i;
......@@ -99,47 +101,49 @@ append_monitor (GArray *modes,
};
g_array_append_val (crtcs, crtc);
output = g_object_new (META_TYPE_OUTPUT, NULL);
output_dummy = g_new0 (MetaOutputDummy, 1);
*output_dummy = (MetaOutputDummy) {
.scale = scale
};
output = (MetaOutput) {
.winsys_id = outputs->len + 1,
.name = g_strdup_printf ("LVDS%d", outputs->len + 1),
.vendor = g_strdup ("MetaProducts Inc."),
.product = g_strdup ("MetaMonitor"),
.serial = g_strdup_printf ("0xC0FFEE-%d", outputs->len + 1),
.suggested_x = -1,
.suggested_y = -1,
.width_mm = 222,
.height_mm = 125,
.subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN,
.preferred_mode = &array_last (modes, MetaCrtcMode),
.n_possible_clones = 0,
.backlight = -1,
.connector_type = META_CONNECTOR_TYPE_LVDS,
.driver_private = output_dummy,
.driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy
};
output.modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (modes_decl));
number = g_list_length (*outputs) + 1;
output->winsys_id = number;
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 = &array_last (modes, MetaCrtcMode);
output->n_possible_clones = 0;
output->backlight = -1;
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 *, G_N_ELEMENTS (modes_decl));
for (i = 0; i < G_N_ELEMENTS (modes_decl); i++)
output.modes[i] = &g_array_index (modes, MetaCrtcMode,
modes->len - (i + 1));
output.n_modes = G_N_ELEMENTS (modes_decl);
output.possible_crtcs = g_new0 (MetaCrtc *, 1);
output.possible_crtcs[0] = &array_last (crtcs, MetaCrtc);
output.n_possible_crtcs = 1;
g_array_append_val (outputs, output);
output->modes[i] = &g_array_index (modes, MetaCrtcMode,
modes->len - (i + 1));
output->n_modes = G_N_ELEMENTS (modes_decl);
output->possible_crtcs = g_new0 (MetaCrtc *, 1);
output->possible_crtcs[0] = &array_last (crtcs, MetaCrtc);
output->n_possible_crtcs = 1;
*outputs = g_list_append (*outputs, output);
}
static void
append_tiled_monitor (GArray *modes,
GArray *crtcs,
GArray *outputs,
GList **outputs,
int scale)
{
MetaCrtcMode modes_decl[] = {
......@@ -162,7 +166,7 @@ append_tiled_monitor (GArray *modes,
.all_transforms = ALL_TRANSFORMS,
},
};
MetaOutput output;
MetaOutput *output;
unsigned int i;
uint32_t tile_group_id;
......@@ -174,61 +178,66 @@ append_tiled_monitor (GArray *modes,
crtcs_decl[i].crtc_id = crtcs->len + i + 1;
g_array_append_vals (crtcs, crtcs_decl, G_N_ELEMENTS (crtcs_decl));
tile_group_id = outputs->len + 1;
tile_group_id = g_list_length (*outputs) + 1;
for (i = 0; i < G_N_ELEMENTS (crtcs_decl); i++)
{
MetaOutputDummy *output_dummy;
MetaCrtcMode *preferred_mode;
unsigned int j;
unsigned int number;
output_dummy = g_new0 (MetaOutputDummy, 1);
*output_dummy = (MetaOutputDummy) {
.scale = scale
};
preferred_mode = &array_last (modes, MetaCrtcMode),
output = (MetaOutput) {
.winsys_id = outputs->len + 1,
.name = g_strdup_printf ("LVDS%d", outputs->len + 1),
.vendor = g_strdup ("MetaProducts Inc."),
.product = g_strdup ("MetaMonitor"),
.serial = g_strdup_printf ("0xC0FFEE-%d", outputs->len + 1),
.suggested_x = -1,
.suggested_y = -1,
.width_mm = 222,
.height_mm = 125,
.subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN,
.preferred_mode = preferred_mode,
.n_possible_clones = 0,
.backlight = -1,
.connector_type = META_CONNECTOR_TYPE_LVDS,
.tile_info = (MetaTileInfo) {
.group_id = tile_group_id,
.max_h_tiles = G_N_ELEMENTS (crtcs_decl),
.max_v_tiles = 1,
.loc_h_tile = i,
.loc_v_tile = 0,
.tile_w = preferred_mode->width,
.tile_h = preferred_mode->height
},
.driver_private = output_dummy,
.driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy
};
output.modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (modes_decl));
/* Arbitrary ID unique for this output */
number = g_list_length (*outputs) + 1;
preferred_mode = &array_last (modes, MetaCrtcMode);
output = g_object_new (META_TYPE_OUTPUT, NULL);
output->winsys_id = number;
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->backlight = -1;
output->connector_type = META_CONNECTOR_TYPE_LVDS;
output->tile_info = (MetaTileInfo) {
.group_id = tile_group_id,
.max_h_tiles = G_N_ELEMENTS (crtcs_decl),
.max_v_tiles = 1,
.loc_h_tile = i,
.loc_v_tile = 0,
.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 (modes_decl));
for (j = 0; j < G_N_ELEMENTS (modes_decl); j++)
output.modes[j] = &g_array_index (modes, MetaCrtcMode,
modes->len - (j + 1));
output.n_modes = G_N_ELEMENTS (modes_decl);
output->modes[j] = &g_array_index (modes, MetaCrtcMode,
modes->len - (j + 1));
output->n_modes = G_N_ELEMENTS (modes_decl);
output.possible_crtcs = g_new0 (MetaCrtc *, G_N_ELEMENTS (crtcs_decl));
output->possible_crtcs = g_new0 (MetaCrtc *, G_N_ELEMENTS (crtcs_decl));
for (j = 0; j < G_N_ELEMENTS (crtcs_decl); j++)
output.possible_crtcs[j] = &g_array_index (crtcs, MetaCrtc,
crtcs->len - (j + 1));
output.n_possible_crtcs = G_N_ELEMENTS (crtcs_decl);
output->possible_crtcs[j] = &g_array_index (crtcs, MetaCrtc,
crtcs->len - (j + 1));
output->n_possible_crtcs = G_N_ELEMENTS (crtcs_decl);
g_array_append_val (outputs, output);
*outputs = g_list_append (*outputs, output);
}
}
......@@ -248,7 +257,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
const char *tiled_monitors_str;
gboolean tiled_monitors;
unsigned int i;
GArray *outputs;
GList *outputs;
GArray *crtcs;
GArray *modes;
......@@ -321,26 +330,24 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
modes = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtcMode), MAX_MODES);
crtcs = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtc), MAX_CRTCS);
outputs = g_array_sized_new (FALSE, TRUE, sizeof (MetaOutput), MAX_OUTPUTS);
outputs = NULL;
for (i = 0; i < num_monitors; i++)
{
if (tiled_monitors)
append_tiled_monitor (modes, crtcs, outputs, monitor_scales[i]);
append_tiled_monitor (modes, crtcs, &outputs, monitor_scales[i]);
else
append_monitor (modes, crtcs, outputs, monitor_scales[i]);
append_monitor (modes, crtcs, &outputs, monitor_scales[i]);
}
manager->modes = (MetaCrtcMode *) modes->data;
manager->n_modes = modes->len;
manager->crtcs = (MetaCrtc *) crtcs->data;
manager->n_crtcs = crtcs->len;
manager->outputs = (MetaOutput *) outputs->data;
manager->n_outputs = outputs->len;
manager->outputs = outputs;
g_array_free (modes, FALSE);
g_array_free (crtcs, FALSE);
g_array_free (outputs, FALSE);
}
static void
......@@ -363,6 +370,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
MetaOutputInfo **outputs,
unsigned int n_outputs)
{
GList *l;
unsigned i;
for (i = 0; i < n_crtcs; i++)
......@@ -446,9 +454,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
}
/* Disable outputs not mentioned in the list */
for (i = 0; i < manager->n_outputs; i++)
for (l = manager->outputs; l; l = l->next)
{
MetaOutput *output = &manager->outputs[i];
MetaOutput *output = l->data;
if (output->is_dirty)
{
......
......@@ -105,28 +105,6 @@ typedef enum
META_MONITOR_TRANSFORM_FLIPPED_270,
} MetaMonitorTransform;
/* This matches the values in drm_mode.h */
typedef enum
{
META_CONNECTOR_TYPE_Unknown = 0,
META_CONNECTOR_TYPE_VGA = 1,
META_CONNECTOR_TYPE_DVII = 2,
META_CONNECTOR_TYPE_DVID = 3,
META_CONNECTOR_TYPE_DVIA = 4,
META_CONNECTOR_TYPE_Composite = 5,
META_CONNECTOR_TYPE_SVIDEO = 6,
META_CONNECTOR_TYPE_LVDS = 7,
META_CONNECTOR_TYPE_Component = 8,
META_CONNECTOR_TYPE_9PinDIN = 9,
META_CONNECTOR_TYPE_DisplayPort = 10,
META_CONNECTOR_TYPE_HDMIA = 11,
META_CONNECTOR_TYPE_HDMIB = 12,
META_CONNECTOR_TYPE_TV = 13,
META_CONNECTOR_TYPE_eDP = 14,
META_CONNECTOR_TYPE_VIRTUAL = 15,
META_CONNECTOR_TYPE_DSI = 16,
} MetaConnectorType;
/* Same as KMS mode flags and X11 randr flags */
typedef enum
{
......@@ -149,74 +127,6 @@ typedef enum
META_CRTC_MODE_FLAG_MASK = 0x3fff
} MetaCrtcModeFlag;
struct _MetaTileInfo
{
guint32 group_id;
guint32 flags;
guint32 max_h_tiles;
guint32 max_v_tiles;
guint32 loc_h_tile;
guint32 loc_v_tile;
guint32 tile_w;
guint32 tile_h;
};
struct _MetaOutput
{
/* The CRTC driving this output, NULL if the output is not enabled */
MetaCrtc *crtc;
/* The low-level ID of this output, used to apply back configuration */
glong winsys_id;
char *name;
char *vendor;
char *product;
char *serial;
int width_mm;
int height_mm;
CoglSubpixelOrder subpixel_order;
MetaConnectorType connector_type;
MetaCrtcMode *preferred_mode;
MetaCrtcMode **modes;
unsigned int n_modes;
MetaCrtc **possible_crtcs;
unsigned int n_possible_crtcs;
MetaOutput **possible_clones;
unsigned int n_possible_clones;
int backlight;
int backlight_min;
int backlight_max;
/* Used when changing configuration */
gboolean is_dirty;
/* The low-level bits used to build the high-level info
in MetaLogicalMonitor
XXX: flags maybe?
There is a lot of code that uses MonitorInfo->is_primary,
but nobody uses MetaOutput yet
*/
gboolean is_primary;
gboolean is_presentation;
gboolean is_underscanning;
gboolean supports_underscanning;
gpointer driver_private;
GDestroyNotify driver_notify;
/* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
gboolean hotplug_mode_update;
gint suggested_x;
gint suggested_y;
MetaTileInfo tile_info;
};
struct _MetaCrtc
{
glong crtc_id;
......@@ -317,8 +227,7 @@ struct _MetaMonitorManager
(like encoders, but less tied to the HW),
while logical_monitors refer to logical ones.
*/
MetaOutput *outputs;
unsigned int n_outputs;
GList *outputs;
MetaCrtcMode *modes;
unsigned int n_modes;
......@@ -451,8 +360,7 @@ MetaMonitor * meta_monitor_manager_get_monitor_from_connector (MetaMonitor
GList * meta_monitor_manager_get_monitors (MetaMonitorManager *manager);
MetaOutput *meta_monitor_manager_get_outputs (MetaMonitorManager *manager,
unsigned int *n_outputs);
GList * meta_monitor_manager_get_outputs (MetaMonitorManager *manager);
void meta_monitor_manager_get_resources (MetaMonitorManager *manager,
MetaCrtcMode **modes,
......
......@@ -40,6 +40,7 @@
#include "backends/meta-monitor.h"
#include "backends/meta-monitor-config-manager.h"
#include "backends/meta-orientation-manager.h"
#include "backends/meta-output.h"
#include "backends/x11/meta-monitor-manager-xrandr.h"
#include "meta-backend-private.h"
......@@ -446,11 +447,11 @@ meta_monitor_manager_apply_monitors_config (MetaMonitorManager *manager,
gboolean
meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
{
unsigned int i;
GList *l;
for (i = 0; i < manager->n_outputs; i++)
for (l = manager->outputs; l; l = l->next)
{
MetaOutput *output = &manager->outputs[i];
MetaOutput *output = l->data;
if (output->hotplug_mode_update)
return TRUE;
......@@ -718,35 +719,6 @@ meta_monitor_manager_constructed (GObject *object)
manager->in_init = FALSE;
}
void
meta_monitor_manager_clear_output (MetaOutput *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)
output->driver_notify (output);
memset (output, 0, sizeof (*output));
}
static void
meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
int n_old_outputs)
{
int i;
for (i = 0; i < n_old_outputs; i++)
meta_monitor_manager_clear_output (&old_outputs[i]);
g_free (old_outputs);
}
void
meta_monitor_manager_clear_mode (MetaCrtcMode *mode)
{
......@@ -796,7 +768,7 @@ meta_monitor_manager_finalize (GObject *object)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
meta_monitor_manager_free_output_array (manager->outputs, manager->n_outputs);
g_list_free_full (manager->outputs, g_object_unref);
meta_monitor_manager_free_mode_array (manager->modes, manager->n_modes);
meta_monitor_manager_free_crtc_array (manager->crtcs, manager->n_crtcs);
g_list_free_full (manager->logical_monitors, g_object_unref);
......@@ -965,6 +937,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (skeleton);
GVariantBuilder crtc_builder, output_builder, mode_builder;
GList *l;
unsigned int i, j;
int max_screen_width;
int max_screen_height;
......@@ -996,9 +969,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
NULL /* properties */);
}
for (i = 0; i < manager->n_outputs; i++)
for (l = manager->outputs; l; l = l->next)
{
MetaOutput *output = &manager->outputs[i];
MetaOutput *output = l->data;
GVariantBuilder crtcs, modes, clones, properties;
GBytes *edid;
char *edid_file;
......@@ -1015,8 +988,13 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_builder_init (&clones, G_VARIANT_TYPE ("au"));
for (j = 0; j < output->n_possible_clones; j++)
g_variant_builder_add (&clones, "u",
(unsigned)(output->possible_clones[j] - manager->outputs));
{
unsigned int possible_clone_index;
possible_clone_index = g_list_index (manager->outputs,
output->possible_clones[j]);
g_variant_builder_add (&clones, "u", possible_clone_index);
}
g_variant_builder_init (&properties, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&properties, "{sv}", "vendor",
......@@ -2030,14 +2008,14 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
return TRUE;
}
if (output_index >= manager->n_outputs)
if (output_index >= g_list_length (manager->outputs))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Invalid output id");
return TRUE;
}
output = &manager->outputs[output_index];
output = g_list_nth_data (manager->outputs, output_index);
if (value < 0 || value > 100)
{
......@@ -2425,11 +2403,9 @@ meta_monitor_manager_get_monitors (MetaMonitorManager *manager)
return manager->monitors;
}
MetaOutput *
meta_monitor_manager_get_outputs (MetaMonitorManager *manager,
unsigned int *n_outputs)
GList *
meta_monitor_manager_get_outputs (MetaMonitorManager *manager)
{
*n_outputs = manager->n_outputs;
return manager->outputs;
}
......@@ -2471,7 +2447,7 @@ meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
static void
rebuild_monitors (MetaMonitorManager *manager)
{
unsigned int i;
GList *l;
if (manager->monitors)
{
......@@ -2479,9 +2455,9 @@ rebuild_monitors (MetaMonitorManager *manager)
manager->monitors = NULL;
}
for (i = 0; i < manager->n_outputs; i++)
for (l = manager->outputs; l; l = l->next)
{
MetaOutput *output = &manager->outputs[i];
MetaOutput *output = l->data;
if (output->tile_info.group_id)
{
......@@ -2541,16 +2517,15 @@ meta_monitor_manager_is_transform_handled (MetaMonitorManager *manager,
void
meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
{
MetaOutput *old_outputs;
GList *old_outputs;