mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
Introduce new monitor configuration system
The new monitor configuration system (MetaMonitorConfigManager) aims to replace the current MetaMonitorConfig. The main difference between the two is that MetaMonitorConfigManager works with higher level input (MetaMonitor, MetaMonitorMode) instead of directly looking at the CRTC and connector state. It still produces CRTC and connector configuration later applied by the respective backends. Other difference the new system aims to introduce is that the configuration system doesn't manipulate the monitor manager state; that responsibility is left for the monitor manager to handle (it only manages configuration and creates CRTC/connector assignments, it doesn't apply anything). The new configuration system allows backends to not rely on deriving the current configuration from the CRTC/connector state, as this may no longer be possible (i.e. when using KMS and multiple framebuffers). The MetaMonitorConfigManager system is so far disabled by default, as it does not yet have all the features of the old system, but eventually it will replace MetaMonitorConfig which will at that point be removed. This will make it possible to remove old hacks introduced due to limitations in the old system. https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
parent
ee0677a021
commit
644ee666f6
@ -105,6 +105,8 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-logical-monitor.h \
|
||||
backends/meta-monitor-config.c \
|
||||
backends/meta-monitor-config.h \
|
||||
backends/meta-monitor-config-manager.c \
|
||||
backends/meta-monitor-config-manager.h \
|
||||
backends/meta-monitor.c \
|
||||
backends/meta-monitor.h \
|
||||
backends/meta-monitor-private.h \
|
||||
|
525
src/backends/meta-monitor-config-manager.c
Normal file
525
src/backends/meta-monitor-config-manager.c
Normal file
@ -0,0 +1,525 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/meta-monitor-config-manager.h"
|
||||
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
|
||||
struct _MetaMonitorConfigManager
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaMonitorManager *monitor_manager;
|
||||
|
||||
MetaMonitorsConfig *current_config;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaMonitorConfigManager, meta_monitor_config_manager,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
G_DEFINE_TYPE (MetaMonitorsConfig, meta_monitors_config,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
MetaMonitorConfigManager *
|
||||
meta_monitor_config_manager_new (MetaMonitorManager *monitor_manager)
|
||||
{
|
||||
MetaMonitorConfigManager *config_manager;
|
||||
|
||||
config_manager = g_object_new (META_TYPE_MONITOR_CONFIG_MANAGER, NULL);
|
||||
config_manager->monitor_manager = monitor_manager;
|
||||
|
||||
return config_manager;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_crtc_assigned (MetaCrtc *crtc,
|
||||
GPtrArray *crtc_infos)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < crtc_infos->len; i++)
|
||||
{
|
||||
MetaCrtcInfo *assigned_crtc_info = g_ptr_array_index (crtc_infos, i);
|
||||
|
||||
if (assigned_crtc_info->crtc == crtc)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static MetaCrtc *
|
||||
find_unassigned_crtc (MetaOutput *output,
|
||||
GPtrArray *crtc_infos)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < output->n_possible_crtcs; i++)
|
||||
{
|
||||
MetaCrtc *crtc = output->possible_crtcs[i];
|
||||
|
||||
if (is_crtc_assigned (crtc, crtc_infos))
|
||||
continue;
|
||||
|
||||
return crtc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config;
|
||||
MetaMonitorConfig *monitor_config;
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
} MonitorAssignmentData;
|
||||
|
||||
static gboolean
|
||||
assign_monitor_crtc (MetaMonitor *monitor,
|
||||
MetaMonitorMode *mode,
|
||||
MetaMonitorCrtcMode *monitor_crtc_mode,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
MonitorAssignmentData *data = user_data;
|
||||
MetaOutput *output;
|
||||
MetaCrtc *crtc;
|
||||
MetaCrtcInfo *crtc_info;
|
||||
MetaOutputInfo *output_info;
|
||||
MetaMonitorConfig *first_monitor_config;
|
||||
gboolean assign_output_as_primary;
|
||||
gboolean assign_output_as_presentation;
|
||||
|
||||
output = monitor_crtc_mode->output;
|
||||
|
||||
crtc = find_unassigned_crtc (output, data->crtc_infos);
|
||||
if (!crtc)
|
||||
{
|
||||
MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor);
|
||||
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No available CRTC for monitor '%s %s' not found",
|
||||
monitor_spec->vendor, monitor_spec->product);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
crtc_info = g_slice_new0 (MetaCrtcInfo);
|
||||
*crtc_info = (MetaCrtcInfo) {
|
||||
.crtc = crtc,
|
||||
.mode = monitor_crtc_mode->crtc_mode,
|
||||
.x = monitor_crtc_mode->x,
|
||||
.y = monitor_crtc_mode->y,
|
||||
.transform = META_MONITOR_TRANSFORM_NORMAL,
|
||||
.outputs = g_ptr_array_new ()
|
||||
};
|
||||
g_ptr_array_add (crtc_info->outputs, output);
|
||||
|
||||
/*
|
||||
* Currently, MetaCrtcInfo are deliberately offset incorrectly to carry over
|
||||
* logical monitor location inside the MetaCrtc struct, when in fact this
|
||||
* depends on the framebuffer configuration. This will eventually be negated
|
||||
* when setting the actual KMS mode.
|
||||
*
|
||||
* TODO: Remove this hack when we don't need to rely on MetaCrtc to pass
|
||||
* logical monitor state.
|
||||
*/
|
||||
crtc_info->x += data->logical_monitor_config->layout.x;
|
||||
crtc_info->y += data->logical_monitor_config->layout.y;
|
||||
|
||||
/*
|
||||
* Only one output can be marked as primary (due to Xrandr limitation),
|
||||
* so only mark the main output of the first monitor in the logical monitor
|
||||
* as such.
|
||||
*/
|
||||
first_monitor_config = data->logical_monitor_config->monitor_configs->data;
|
||||
if (data->monitor_config == first_monitor_config &&
|
||||
meta_monitor_get_main_output (monitor) == output)
|
||||
assign_output_as_primary = TRUE;
|
||||
else
|
||||
assign_output_as_primary = FALSE;
|
||||
|
||||
if (data->logical_monitor_config->is_presentation)
|
||||
assign_output_as_presentation = TRUE;
|
||||
else
|
||||
assign_output_as_presentation = FALSE;
|
||||
|
||||
output_info = g_slice_new0 (MetaOutputInfo);
|
||||
*output_info = (MetaOutputInfo) {
|
||||
.output = output,
|
||||
.is_primary = assign_output_as_primary,
|
||||
.is_presentation = assign_output_as_presentation,
|
||||
.is_underscanning = output->is_underscanning
|
||||
};
|
||||
|
||||
g_ptr_array_add (data->crtc_infos, crtc_info);
|
||||
g_ptr_array_add (data->output_infos, output_info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
assign_monitor_crtcs (MetaMonitorManager *manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
MetaMonitorConfig *monitor_config,
|
||||
GPtrArray *crtc_infos,
|
||||
GPtrArray *output_infos,
|
||||
GError **error)
|
||||
{
|
||||
MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec;
|
||||
MetaMonitorModeSpec *monitor_mode_spec = monitor_config->mode_spec;
|
||||
MetaMonitor *monitor;
|
||||
MetaMonitorMode *monitor_mode;
|
||||
MonitorAssignmentData data;
|
||||
|
||||
monitor = meta_monitor_manager_get_monitor_from_spec (manager, monitor_spec);
|
||||
if (!monitor)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Configured monitor '%s %s' not found",
|
||||
monitor_spec->vendor, monitor_spec->product);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
monitor_mode = meta_monitor_get_mode_from_spec (monitor, monitor_mode_spec);
|
||||
if (!monitor_mode)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid mode %dx%d (%f) for monitor '%s %s'",
|
||||
monitor_mode_spec->width, monitor_mode_spec->height,
|
||||
monitor_mode_spec->refresh_rate,
|
||||
monitor_spec->vendor, monitor_spec->product);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data = (MonitorAssignmentData) {
|
||||
.logical_monitor_config = logical_monitor_config,
|
||||
.monitor_config = monitor_config,
|
||||
.crtc_infos = crtc_infos,
|
||||
.output_infos = output_infos
|
||||
};
|
||||
if (!meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
|
||||
assign_monitor_crtc,
|
||||
&data,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
assign_logical_monitor_crtcs (MetaMonitorManager *manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
GPtrArray *crtc_infos,
|
||||
GPtrArray *output_infos,
|
||||
GError **error)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = logical_monitor_config->monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config = l->data;
|
||||
|
||||
if (!assign_monitor_crtcs (manager,
|
||||
logical_monitor_config,
|
||||
monitor_config,
|
||||
crtc_infos, output_infos,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GPtrArray **out_crtc_infos,
|
||||
GPtrArray **out_output_infos,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
GList *l;
|
||||
|
||||
crtc_infos =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_crtc_info_free);
|
||||
output_infos =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_output_info_free);
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
|
||||
if (!assign_logical_monitor_crtcs (manager, logical_monitor_config,
|
||||
crtc_infos, output_infos,
|
||||
error))
|
||||
{
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*out_crtc_infos = crtc_infos;
|
||||
*out_output_infos = output_infos;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaMonitor *
|
||||
find_monitor_with_highest_preferred_resolution (MetaMonitorManager *monitor_manager)
|
||||
{
|
||||
GList *monitors;
|
||||
GList *l;
|
||||
int largest_area = 0;
|
||||
MetaMonitor *largest_monitor = NULL;
|
||||
|
||||
monitors = meta_monitor_manager_get_monitors (monitor_manager);
|
||||
for (l = monitors; l; l = l->next)
|
||||
{
|
||||
MetaMonitor *monitor = l->data;
|
||||
MetaMonitorMode *mode;
|
||||
int width, height;
|
||||
int area;
|
||||
|
||||
mode = meta_monitor_get_preferred_mode (monitor);
|
||||
meta_monitor_mode_get_resolution (mode, &width, &height);
|
||||
area = width * height;
|
||||
|
||||
if (area > largest_area)
|
||||
{
|
||||
largest_area = area;
|
||||
largest_monitor = monitor;
|
||||
}
|
||||
}
|
||||
|
||||
return largest_monitor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tries to find the primary monitor as reported by the underlying system;
|
||||
* or failing that, a monitor looks to be the laptop panel; or failing that, the
|
||||
* monitor with the highest preferred resolution.
|
||||
*/
|
||||
static MetaMonitor *
|
||||
find_primary_monitor (MetaMonitorManager *monitor_manager)
|
||||
{
|
||||
MetaMonitor *monitor;
|
||||
|
||||
monitor = meta_monitor_manager_get_primary_monitor (monitor_manager);
|
||||
if (monitor)
|
||||
return monitor;
|
||||
|
||||
monitor = meta_monitor_manager_get_laptop_panel (monitor_manager);
|
||||
if (monitor)
|
||||
return monitor;
|
||||
|
||||
return find_monitor_with_highest_preferred_resolution (monitor_manager);
|
||||
}
|
||||
|
||||
static MetaMonitorConfig *
|
||||
create_monitor_config (MetaMonitor *monitor,
|
||||
MetaMonitorMode *mode)
|
||||
{
|
||||
MetaMonitorSpec *monitor_spec;
|
||||
MetaMonitorModeSpec *mode_spec;
|
||||
MetaMonitorConfig *monitor_config;
|
||||
|
||||
monitor_spec = meta_monitor_get_spec (monitor);
|
||||
mode_spec = meta_monitor_mode_get_spec (mode);
|
||||
|
||||
monitor_config = g_new0 (MetaMonitorConfig, 1);
|
||||
*monitor_config = (MetaMonitorConfig) {
|
||||
.monitor_spec = meta_monitor_spec_clone (monitor_spec),
|
||||
.mode_spec = g_memdup (mode_spec, sizeof (MetaMonitorModeSpec))
|
||||
};
|
||||
|
||||
return monitor_config;
|
||||
}
|
||||
|
||||
static MetaLogicalMonitorConfig *
|
||||
create_preferred_logical_monitor_config (MetaMonitor *monitor,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
int width, height;
|
||||
MetaMonitorConfig *monitor_config;
|
||||
MetaLogicalMonitorConfig *logical_monitor_config;
|
||||
|
||||
mode = meta_monitor_get_preferred_mode (monitor);
|
||||
meta_monitor_mode_get_resolution (mode, &width, &height);
|
||||
monitor_config = create_monitor_config (monitor, mode);
|
||||
|
||||
logical_monitor_config = g_new0 (MetaLogicalMonitorConfig, 1);
|
||||
*logical_monitor_config = (MetaLogicalMonitorConfig) {
|
||||
.layout = (MetaRectangle) {
|
||||
.x = x,
|
||||
.y = y,
|
||||
.width = width,
|
||||
.height = height
|
||||
},
|
||||
.monitor_configs = g_list_append (NULL, monitor_config)
|
||||
};
|
||||
|
||||
return logical_monitor_config;
|
||||
}
|
||||
|
||||
MetaMonitorsConfig *
|
||||
meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
|
||||
MetaMonitor *primary_monitor;
|
||||
MetaMonitorsConfig *config;
|
||||
MetaLogicalMonitorConfig *primary_logical_monitor_config;
|
||||
int x;
|
||||
GList *monitors;
|
||||
GList *l;
|
||||
|
||||
primary_monitor = find_primary_monitor (monitor_manager);
|
||||
|
||||
config = g_object_new (META_TYPE_MONITORS_CONFIG, NULL);
|
||||
|
||||
primary_logical_monitor_config =
|
||||
create_preferred_logical_monitor_config (primary_monitor, 0, 0);
|
||||
primary_logical_monitor_config->is_primary = TRUE;
|
||||
config->logical_monitor_configs =
|
||||
g_list_append (NULL, primary_logical_monitor_config);
|
||||
|
||||
x = primary_logical_monitor_config->layout.width;
|
||||
monitors = meta_monitor_manager_get_monitors (monitor_manager);
|
||||
for (l = monitors; l; l = l->next)
|
||||
{
|
||||
MetaMonitor *monitor = l->data;
|
||||
MetaLogicalMonitorConfig *logical_monitor_config;
|
||||
|
||||
if (monitor == primary_monitor)
|
||||
continue;
|
||||
|
||||
logical_monitor_config =
|
||||
create_preferred_logical_monitor_config (monitor, x, 0);
|
||||
config->logical_monitor_configs =
|
||||
g_list_append (config->logical_monitor_configs, logical_monitor_config);
|
||||
|
||||
x += logical_monitor_config->layout.width;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
MetaMonitorsConfig *
|
||||
meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_manager)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
|
||||
MetaMonitor *primary_monitor;
|
||||
MetaMonitorsConfig *config;
|
||||
MetaLogicalMonitorConfig *primary_logical_monitor_config;
|
||||
|
||||
primary_monitor = find_primary_monitor (monitor_manager);
|
||||
|
||||
config = g_object_new (META_TYPE_MONITORS_CONFIG, NULL);
|
||||
|
||||
primary_logical_monitor_config =
|
||||
create_preferred_logical_monitor_config (primary_monitor, 0, 0);
|
||||
primary_logical_monitor_config->is_primary = TRUE;
|
||||
config->logical_monitor_configs =
|
||||
g_list_append (NULL, primary_logical_monitor_config);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_config_manager_set_current (MetaMonitorConfigManager *config_manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
g_set_object (&config_manager->current_config, config);
|
||||
}
|
||||
|
||||
MetaMonitorsConfig *
|
||||
meta_monitor_config_manager_get_current (MetaMonitorConfigManager *config_manager)
|
||||
{
|
||||
return config_manager->current_config;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_config_manager_dispose (GObject *object)
|
||||
{
|
||||
MetaMonitorConfigManager *config_manager =
|
||||
META_MONITOR_CONFIG_MANAGER (object);
|
||||
|
||||
g_clear_object (&config_manager->current_config);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_config_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_config_manager_init (MetaMonitorConfigManager *config_manager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_config_manager_class_init (MetaMonitorConfigManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_monitor_config_manager_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_config_free (MetaMonitorConfig *monitor_config)
|
||||
{
|
||||
meta_monitor_spec_free (monitor_config->monitor_spec);
|
||||
g_free (monitor_config->mode_spec);
|
||||
g_free (monitor_config);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor_config)
|
||||
{
|
||||
g_list_free_full (logical_monitor_config->monitor_configs,
|
||||
(GDestroyNotify) meta_monitor_config_free);
|
||||
g_free (logical_monitor_config);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitors_config_finalize (GObject *object)
|
||||
{
|
||||
MetaMonitorsConfig *config = META_MONITORS_CONFIG (object);
|
||||
|
||||
g_list_free_full (config->logical_monitor_configs,
|
||||
(GDestroyNotify) meta_logical_monitor_config_free);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitors_config_init (MetaMonitorsConfig *config)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitors_config_class_init (MetaMonitorsConfigClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_monitors_config_finalize;
|
||||
}
|
74
src/backends/meta-monitor-config-manager.h
Normal file
74
src/backends/meta-monitor-config-manager.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_MONITOR_CONFIG_MANAGER_H
|
||||
#define META_MONITOR_CONFIG_MANAGER_H
|
||||
|
||||
#include "backends/meta-monitor.h"
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_CONFIG_MANAGER (meta_monitor_config_manager_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaMonitorConfigManager, meta_monitor_config_manager,
|
||||
META, MONITOR_CONFIG_MANAGER, GObject)
|
||||
|
||||
typedef struct _MetaMonitorConfig
|
||||
{
|
||||
MetaMonitorSpec *monitor_spec;
|
||||
MetaMonitorModeSpec *mode_spec;
|
||||
} MetaMonitorConfig;
|
||||
|
||||
typedef struct _MetaLogicalMonitorConfig
|
||||
{
|
||||
MetaRectangle layout;
|
||||
GList *monitor_configs;
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
} MetaLogicalMonitorConfig;
|
||||
|
||||
struct _MetaMonitorsConfig
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GList *logical_monitor_configs;
|
||||
};
|
||||
|
||||
#define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaMonitorsConfig, meta_monitors_config,
|
||||
META, MONITORS_CONFIG, GObject)
|
||||
|
||||
MetaMonitorConfigManager * meta_monitor_config_manager_new (MetaMonitorManager *monitor_manager);
|
||||
|
||||
gboolean meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GPtrArray **crtc_infos,
|
||||
GPtrArray **output_infos,
|
||||
GError **error);
|
||||
|
||||
MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager);
|
||||
|
||||
MetaMonitorsConfig * meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_manager);
|
||||
|
||||
void meta_monitor_config_manager_set_current (MetaMonitorConfigManager *config_manager,
|
||||
MetaMonitorsConfig *config);
|
||||
|
||||
MetaMonitorsConfig * meta_monitor_config_manager_get_current (MetaMonitorConfigManager *config_manager);
|
||||
|
||||
#endif /* META_MONITOR_CONFIG_MANAGER_H */
|
@ -30,6 +30,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <meta/util.h>
|
||||
#include "backends/meta-monitor-config-manager.h"
|
||||
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
@ -172,20 +173,25 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
|
||||
static void
|
||||
meta_monitor_manager_dummy_ensure_initial_config (MetaMonitorManager *manager)
|
||||
{
|
||||
meta_monitor_manager_ensure_configured (manager);
|
||||
MetaMonitorsConfig *config;
|
||||
|
||||
meta_monitor_manager_update_logical_state_derived (manager);
|
||||
config = meta_monitor_manager_ensure_configured (manager);
|
||||
|
||||
if (manager->config_manager)
|
||||
meta_monitor_manager_update_logical_state (manager, config);
|
||||
else
|
||||
meta_monitor_manager_update_logical_state_derived (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
unsigned i;
|
||||
int screen_width = 0, screen_height = 0;
|
||||
unsigned i;
|
||||
int screen_width = 0, screen_height = 0;
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
@ -287,6 +293,43 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
|
||||
|
||||
manager->screen_width = screen_width;
|
||||
manager->screen_height = screen_height;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_dummy_apply_monitors_config (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
|
||||
if (!meta_monitor_config_manager_assign (manager, config,
|
||||
&crtc_infos, &output_infos,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
apply_crtc_assignments (manager,
|
||||
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||
crtc_infos->len,
|
||||
(MetaOutputInfo **) output_infos->pdata,
|
||||
output_infos->len);
|
||||
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
|
||||
meta_monitor_manager_rebuild (manager, config);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
apply_crtc_assignments (manager, crtcs, n_crtcs, outputs, n_outputs);
|
||||
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
}
|
||||
@ -298,6 +341,7 @@ meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
|
||||
|
||||
manager_class->read_current = meta_monitor_manager_dummy_read_current;
|
||||
manager_class->ensure_initial_config = meta_monitor_manager_dummy_ensure_initial_config;
|
||||
manager_class->apply_monitors_config = meta_monitor_manager_dummy_apply_monitors_config;
|
||||
manager_class->apply_configuration = meta_monitor_manager_dummy_apply_config;
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include "meta-cursor.h"
|
||||
|
||||
typedef struct _MetaMonitorConfig MetaMonitorConfig;
|
||||
typedef struct _MetaMonitorConfigManager MetaMonitorConfigManager;
|
||||
typedef struct _MetaMonitorsConfig MetaMonitorsConfig;
|
||||
|
||||
typedef struct _MetaMonitor MetaMonitor;
|
||||
typedef struct _MetaMonitorNormal MetaMonitorNormal;
|
||||
@ -284,6 +286,8 @@ struct _MetaMonitorManager
|
||||
int persistent_timeout_id;
|
||||
MetaMonitorConfig *legacy_config;
|
||||
|
||||
MetaMonitorConfigManager *config_manager;
|
||||
|
||||
GnomePnpIds *pnp_ids;
|
||||
};
|
||||
|
||||
@ -300,6 +304,10 @@ struct _MetaMonitorManagerClass
|
||||
|
||||
void (*ensure_initial_config) (MetaMonitorManager *);
|
||||
|
||||
gboolean (*apply_monitors_config) (MetaMonitorManager *,
|
||||
MetaMonitorsConfig *,
|
||||
GError **);
|
||||
|
||||
void (*apply_configuration) (MetaMonitorManager *,
|
||||
MetaCrtcInfo **,
|
||||
unsigned int ,
|
||||
@ -334,6 +342,8 @@ struct _MetaMonitorManagerClass
|
||||
|
||||
};
|
||||
|
||||
void meta_monitor_manager_rebuild (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config);
|
||||
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);
|
||||
|
||||
int meta_monitor_manager_get_num_logical_monitors (MetaMonitorManager *manager);
|
||||
@ -413,8 +423,10 @@ void meta_monitor_manager_tiled_monitor_added (MetaMonitorManager
|
||||
void meta_monitor_manager_tiled_monitor_removed (MetaMonitorManager *manager,
|
||||
MetaMonitor *monitor);
|
||||
|
||||
void meta_monitor_manager_ensure_configured (MetaMonitorManager *manager);
|
||||
MetaMonitorsConfig * meta_monitor_manager_ensure_configured (MetaMonitorManager *manager);
|
||||
|
||||
void meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config);
|
||||
void meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager);
|
||||
|
||||
void meta_monitor_manager_clear_output (MetaOutput *output);
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "meta-monitor-config.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/meta-monitor.h"
|
||||
#include "backends/meta-monitor-config-manager.h"
|
||||
#include "backends/x11/meta-monitor-manager-xrandr.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
@ -106,6 +107,85 @@ logical_monitor_from_layout (MetaMonitorManager *manager,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static MetaLogicalMonitor *
|
||||
create_logical_monitor_from_config (MetaMonitorManager *manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
int monitor_number)
|
||||
{
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
GList *monitor_configs;
|
||||
MetaMonitorConfig *first_monitor_config;
|
||||
MetaMonitorSpec *first_monitor_spec;
|
||||
MetaMonitor *first_monitor;
|
||||
GList *l;
|
||||
|
||||
monitor_configs = logical_monitor_config->monitor_configs;
|
||||
first_monitor_config = g_list_first (monitor_configs)->data;
|
||||
first_monitor_spec = first_monitor_config->monitor_spec;
|
||||
first_monitor =
|
||||
meta_monitor_manager_get_monitor_from_spec (manager, first_monitor_spec);
|
||||
|
||||
/* Create logical monitor from the first monitor. */
|
||||
logical_monitor = meta_logical_monitor_new (first_monitor,
|
||||
logical_monitor_config->layout.x,
|
||||
logical_monitor_config->layout.y,
|
||||
monitor_number);
|
||||
|
||||
/* Add the other monitors. */
|
||||
for (l = monitor_configs->next; l; l = l->next)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config = l->data;
|
||||
MetaMonitorSpec *monitor_spec;
|
||||
MetaMonitor *monitor;
|
||||
|
||||
monitor_spec = monitor_config->monitor_spec;
|
||||
monitor = meta_monitor_manager_get_monitor_from_spec (manager,
|
||||
monitor_spec);
|
||||
|
||||
meta_logical_monitor_add_monitor (logical_monitor, monitor);
|
||||
}
|
||||
|
||||
return logical_monitor;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_rebuild_logical_monitors (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
GList *logical_monitors = NULL;
|
||||
GList *l;
|
||||
int monitor_number = 0;
|
||||
MetaLogicalMonitor *primary_logical_monitor = NULL;
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
|
||||
logical_monitor =
|
||||
create_logical_monitor_from_config (manager,
|
||||
logical_monitor_config,
|
||||
monitor_number);
|
||||
monitor_number++;
|
||||
|
||||
if (logical_monitor_config->is_primary)
|
||||
primary_logical_monitor = logical_monitor;
|
||||
|
||||
logical_monitors = g_list_append (logical_monitors, logical_monitor);
|
||||
}
|
||||
|
||||
/*
|
||||
* If no monitor was marked as primary, fall back on marking the first
|
||||
* logical monitor the primary one.
|
||||
*/
|
||||
if (!primary_logical_monitor && logical_monitors)
|
||||
primary_logical_monitor = g_list_first (logical_monitors)->data;
|
||||
|
||||
manager->logical_monitors = logical_monitors;
|
||||
meta_monitor_manager_set_primary_logical_monitor (manager,
|
||||
primary_logical_monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
derive_monitor_position (MetaMonitor *monitor,
|
||||
int *x,
|
||||
@ -206,6 +286,17 @@ meta_monitor_manager_ensure_initial_config (MetaMonitorManager *manager)
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager)->ensure_initial_config (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_apply_monitors_config (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GError **error)
|
||||
{
|
||||
MetaMonitorManagerClass *manager_class =
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||
|
||||
return manager_class->apply_monitors_config (manager, config, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -229,10 +320,52 @@ legacy_ensure_configured (MetaMonitorManager *manager)
|
||||
meta_monitor_config_make_default (manager->legacy_config, manager);
|
||||
}
|
||||
|
||||
void
|
||||
MetaMonitorsConfig *
|
||||
meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
||||
{
|
||||
legacy_ensure_configured (manager);
|
||||
MetaMonitorsConfig *config = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!manager->config_manager)
|
||||
{
|
||||
legacy_ensure_configured (manager);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config = meta_monitor_config_manager_create_linear (manager->config_manager);
|
||||
if (!meta_monitor_manager_apply_monitors_config (manager, config, &error))
|
||||
{
|
||||
g_clear_object (&config);
|
||||
g_warning ("Failed to use linear monitor configuration: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
config = meta_monitor_config_manager_create_fallback (manager->config_manager);
|
||||
if (!meta_monitor_manager_apply_monitors_config (manager, config, &error))
|
||||
{
|
||||
g_clear_object (&config);
|
||||
g_warning ("Failed to use fallback monitor configuration: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (!config)
|
||||
meta_fatal ("Failed to find any working monitor configuration, giving up");
|
||||
|
||||
meta_monitor_config_manager_set_current (manager->config_manager, config);
|
||||
g_object_unref (config);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -245,7 +378,10 @@ meta_monitor_manager_constructed (GObject *object)
|
||||
|
||||
manager->in_init = TRUE;
|
||||
|
||||
manager->legacy_config = meta_monitor_config_new ();
|
||||
if (g_strcmp0 (g_getenv ("MUTTER_USE_CONFIG_MANAGER"), "1") == 0)
|
||||
manager->config_manager = meta_monitor_config_manager_new (manager);
|
||||
else
|
||||
manager->legacy_config = meta_monitor_config_new ();
|
||||
|
||||
meta_monitor_manager_read_current_state (manager);
|
||||
|
||||
@ -353,6 +489,8 @@ meta_monitor_manager_dispose (GObject *object)
|
||||
manager->dbus_name_id = 0;
|
||||
}
|
||||
|
||||
g_clear_object (&manager->config_manager);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -704,7 +842,10 @@ save_config_timeout (gpointer user_data)
|
||||
{
|
||||
MetaMonitorManager *manager = user_data;
|
||||
|
||||
legacy_restore_previous_config (manager);
|
||||
if (manager->config_manager)
|
||||
g_assert (!"missing implementation");
|
||||
else
|
||||
legacy_restore_previous_config (manager);
|
||||
|
||||
manager->persistent_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
@ -728,6 +869,14 @@ meta_monitor_manager_legacy_handle_apply_configuration (MetaDBusDisplayConfig *
|
||||
guint output_index;
|
||||
GPtrArray *crtc_infos, *output_infos;
|
||||
|
||||
if (manager->config_manager)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Used old configuration API with new configuration system");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (serial != manager->serial)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@ -968,7 +1117,10 @@ meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
|
||||
g_source_remove (manager->persistent_timeout_id);
|
||||
manager->persistent_timeout_id = 0;
|
||||
|
||||
legacy_confirm_configuration (manager, ok);
|
||||
if (manager->config_manager)
|
||||
g_assert (!"not implemented");
|
||||
else
|
||||
legacy_confirm_configuration (manager, ok);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1543,6 +1695,79 @@ meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
|
||||
g_signal_emit_by_name (manager, "monitors-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
set_logical_monitor_modes (MetaMonitorManager *manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = logical_monitor_config->monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config = l->data;
|
||||
MetaMonitorSpec *monitor_spec;
|
||||
MetaMonitor *monitor;
|
||||
MetaMonitorModeSpec *monitor_mode_spec;
|
||||
MetaMonitorMode *monitor_mode;
|
||||
|
||||
monitor_spec = monitor_config->monitor_spec;
|
||||
monitor = meta_monitor_manager_get_monitor_from_spec (manager,
|
||||
monitor_spec);
|
||||
monitor_mode_spec = monitor_config->mode_spec;
|
||||
monitor_mode = meta_monitor_get_mode_from_spec (monitor,
|
||||
monitor_mode_spec);
|
||||
|
||||
meta_monitor_set_current_mode (monitor, monitor_mode);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_update_monitor_modes (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
|
||||
set_logical_monitor_modes (manager, logical_monitor_config);
|
||||
}
|
||||
|
||||
for (l = manager->monitors; l; l = l->next)
|
||||
{
|
||||
MetaMonitor *monitor = l->data;
|
||||
|
||||
if (!meta_monitor_get_logical_monitor (monitor))
|
||||
meta_monitor_set_current_mode (monitor, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
meta_monitor_manager_rebuild_logical_monitors (manager, config);
|
||||
meta_monitor_manager_update_monitor_modes (manager, config);
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_rebuild (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
GList *old_logical_monitors;
|
||||
|
||||
if (manager->in_init)
|
||||
return;
|
||||
|
||||
old_logical_monitors = manager->logical_monitors;
|
||||
|
||||
meta_monitor_manager_update_logical_state (manager, config);
|
||||
|
||||
meta_monitor_manager_notify_monitors_changed (manager);
|
||||
|
||||
g_list_free_full (old_logical_monitors, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_update_monitor_modes_derived (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -1664,7 +1889,13 @@ legacy_on_hotplug (MetaMonitorManager *manager)
|
||||
void
|
||||
meta_monitor_manager_on_hotplug (MetaMonitorManager *manager)
|
||||
{
|
||||
legacy_on_hotplug (manager);
|
||||
if (manager->legacy_config)
|
||||
{
|
||||
legacy_on_hotplug (manager);
|
||||
return;
|
||||
}
|
||||
|
||||
meta_monitor_manager_ensure_configured (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -581,6 +581,17 @@ meta_monitor_get_spec (MetaMonitor *monitor)
|
||||
return priv->spec;
|
||||
}
|
||||
|
||||
MetaLogicalMonitor *
|
||||
meta_monitor_get_logical_monitor (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output = meta_monitor_get_main_output (monitor);
|
||||
|
||||
if (output->crtc)
|
||||
return output->crtc->logical_monitor;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_mode_spec_equals (MetaMonitorModeSpec *monitor_mode_spec,
|
||||
MetaMonitorModeSpec *other_monitor_mode_spec)
|
||||
@ -668,6 +679,15 @@ meta_monitor_derive_current_mode (MetaMonitor *monitor)
|
||||
priv->current_mode = current_mode;
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_set_current_mode (MetaMonitor *monitor,
|
||||
MetaMonitorMode *mode)
|
||||
{
|
||||
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
|
||||
|
||||
priv->current_mode = mode;
|
||||
}
|
||||
|
||||
GList *
|
||||
meta_monitor_get_modes (MetaMonitor *monitor)
|
||||
{
|
||||
|
@ -115,6 +115,8 @@ const char * meta_monitor_get_serial (MetaMonitor *monitor);
|
||||
|
||||
uint32_t meta_monitor_tiled_get_tile_group_id (MetaMonitorTiled *monitor_tiled);
|
||||
|
||||
MetaLogicalMonitor * meta_monitor_get_logical_monitor (MetaMonitor *monitor);
|
||||
|
||||
MetaMonitorMode * meta_monitor_get_mode_from_spec (MetaMonitor *monitor,
|
||||
MetaMonitorModeSpec *monitor_mode_spec);
|
||||
|
||||
@ -124,6 +126,9 @@ MetaMonitorMode * meta_monitor_get_current_mode (MetaMonitor *monitor);
|
||||
|
||||
void meta_monitor_derive_current_mode (MetaMonitor *monitor);
|
||||
|
||||
void meta_monitor_set_current_mode (MetaMonitor *monitor,
|
||||
MetaMonitorMode *mode);
|
||||
|
||||
GList * meta_monitor_get_modes (MetaMonitor *monitor);
|
||||
|
||||
MetaMonitorModeSpec * meta_monitor_mode_get_spec (MetaMonitorMode *monitor_mode);
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "meta-monitor-manager-kms.h"
|
||||
#include "meta-monitor-config.h"
|
||||
#include "meta-monitor-config-manager.h"
|
||||
#include "meta-backend-private.h"
|
||||
#include "meta-renderer-native.h"
|
||||
|
||||
@ -1177,24 +1178,6 @@ init_outputs (MetaMonitorManager *manager,
|
||||
detect_and_setup_output_clones (manager, resources);
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_screen_size (MetaMonitorManager *manager)
|
||||
{
|
||||
unsigned int i;
|
||||
int width = 0, height = 0;
|
||||
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
{
|
||||
MetaCrtc *crtc = &manager->crtcs[i];
|
||||
|
||||
width = MAX (width, crtc->rect.x + crtc->rect.width);
|
||||
height = MAX (height, crtc->rect.y + crtc->rect.height);
|
||||
}
|
||||
|
||||
manager->screen_width = width;
|
||||
manager->screen_height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -1220,8 +1203,6 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
init_crtcs (manager, resources);
|
||||
init_outputs (manager, resources);
|
||||
|
||||
calculate_screen_size (manager);
|
||||
|
||||
drmModeFreeResources (resources);
|
||||
}
|
||||
|
||||
@ -1340,23 +1321,26 @@ set_underscan (MetaMonitorManagerKms *manager_kms,
|
||||
static void
|
||||
meta_monitor_manager_kms_ensure_initial_config (MetaMonitorManager *manager)
|
||||
{
|
||||
meta_monitor_manager_ensure_configured (manager);
|
||||
MetaMonitorsConfig *config;
|
||||
|
||||
meta_monitor_manager_update_logical_state_derived (manager);
|
||||
config = meta_monitor_manager_ensure_configured (manager);
|
||||
|
||||
if (manager->config_manager)
|
||||
meta_monitor_manager_update_logical_state (manager, config);
|
||||
else
|
||||
meta_monitor_manager_update_logical_state_derived (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
unsigned i;
|
||||
int screen_width, screen_height;
|
||||
|
||||
screen_width = 0; screen_height = 0;
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
MetaCrtcInfo *crtc_info = crtcs[i];
|
||||
@ -1393,9 +1377,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
height = mode->height;
|
||||
}
|
||||
|
||||
screen_width = MAX (screen_width, crtc_info->x + width);
|
||||
screen_height = MAX (screen_height, crtc_info->y + height);
|
||||
|
||||
crtc->rect.x = crtc_info->x;
|
||||
crtc->rect.y = crtc_info->y;
|
||||
crtc->rect.width = width;
|
||||
@ -1479,10 +1460,93 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
output->crtc = NULL;
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_screen_size (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
GList *l;
|
||||
int screen_width = 0;
|
||||
int screen_height = 0;
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
int right_edge;
|
||||
int bottom_edge;
|
||||
|
||||
right_edge = (logical_monitor_config->layout.width +
|
||||
logical_monitor_config->layout.x);
|
||||
if (right_edge > screen_width)
|
||||
screen_width = right_edge;
|
||||
|
||||
bottom_edge = (logical_monitor_config->layout.height +
|
||||
logical_monitor_config->layout.y);
|
||||
if (bottom_edge > screen_height)
|
||||
screen_height = bottom_edge;
|
||||
}
|
||||
|
||||
manager->screen_width = screen_width;
|
||||
manager->screen_height = screen_height;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
|
||||
if (!meta_monitor_config_manager_assign (manager, config,
|
||||
&crtc_infos, &output_infos,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
apply_crtc_assignments (manager,
|
||||
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||
crtc_infos->len,
|
||||
(MetaOutputInfo **) output_infos->pdata,
|
||||
output_infos->len);
|
||||
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
|
||||
update_screen_size (manager, config);
|
||||
meta_monitor_manager_rebuild (manager, config);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
legacy_calculate_screen_size (MetaMonitorManager *manager)
|
||||
{
|
||||
unsigned int i;
|
||||
int width = 0, height = 0;
|
||||
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
{
|
||||
MetaCrtc *crtc = &manager->crtcs[i];
|
||||
|
||||
width = MAX (width, crtc->rect.x + crtc->rect.width);
|
||||
height = MAX (height, crtc->rect.y + crtc->rect.height);
|
||||
}
|
||||
|
||||
manager->screen_width = width;
|
||||
manager->screen_height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
apply_crtc_assignments (manager, crtcs, n_crtcs, outputs, n_outputs);
|
||||
|
||||
legacy_calculate_screen_size (manager);
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
}
|
||||
|
||||
@ -1931,6 +1995,7 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
|
||||
manager_class->read_current = meta_monitor_manager_kms_read_current;
|
||||
manager_class->read_edid = meta_monitor_manager_kms_read_edid;
|
||||
manager_class->ensure_initial_config = meta_monitor_manager_kms_ensure_initial_config;
|
||||
manager_class->apply_monitors_config = meta_monitor_manager_kms_apply_monitors_config;
|
||||
manager_class->apply_configuration = meta_monitor_manager_kms_apply_configuration;
|
||||
manager_class->set_power_save_mode = meta_monitor_manager_kms_set_power_save_mode;
|
||||
manager_class->get_crtc_gamma = meta_monitor_manager_kms_get_crtc_gamma;
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <meta/main.h>
|
||||
#include <meta/errors.h>
|
||||
#include "meta-monitor-config.h"
|
||||
#include "backends/meta-monitor-config-manager.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
@ -1060,11 +1061,11 @@ output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
|
||||
unsigned i;
|
||||
@ -1294,6 +1295,41 @@ meta_monitor_manager_xrandr_ensure_initial_config (MetaMonitorManager *manager)
|
||||
meta_monitor_manager_update_logical_state_derived (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
|
||||
if (!meta_monitor_config_manager_assign (manager, config,
|
||||
&crtc_infos, &output_infos,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
apply_crtc_assignments (manager,
|
||||
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||
crtc_infos->len,
|
||||
(MetaOutputInfo **) output_infos->pdata,
|
||||
output_infos->len);
|
||||
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
apply_crtc_assignments (manager, crtcs, n_crtcs, outputs, n_outputs);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
|
||||
MetaOutput *output,
|
||||
@ -1587,6 +1623,7 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
|
||||
manager_class->read_current = meta_monitor_manager_xrandr_read_current;
|
||||
manager_class->read_edid = meta_monitor_manager_xrandr_read_edid;
|
||||
manager_class->ensure_initial_config = meta_monitor_manager_xrandr_ensure_initial_config;
|
||||
manager_class->apply_monitors_config = meta_monitor_manager_xrandr_apply_monitors_config;
|
||||
manager_class->apply_configuration = meta_monitor_manager_xrandr_apply_configuration;
|
||||
manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode;
|
||||
manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "tests/meta-monitor-manager-test.h"
|
||||
|
||||
#include "backends/meta-monitor-config-manager.h"
|
||||
|
||||
struct _MetaMonitorManagerTest
|
||||
{
|
||||
MetaMonitorManager parent;
|
||||
@ -86,20 +88,24 @@ meta_monitor_manager_test_read_current (MetaMonitorManager *manager)
|
||||
static void
|
||||
meta_monitor_manager_test_ensure_initial_config (MetaMonitorManager *manager)
|
||||
{
|
||||
meta_monitor_manager_ensure_configured (manager);
|
||||
MetaMonitorsConfig *config;
|
||||
|
||||
meta_monitor_manager_update_logical_state_derived (manager);
|
||||
config = meta_monitor_manager_ensure_configured (manager);
|
||||
|
||||
if (manager->config_manager)
|
||||
meta_monitor_manager_update_logical_state (manager, config);
|
||||
else
|
||||
meta_monitor_manager_update_logical_state_derived (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_test_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
unsigned int i;
|
||||
int screen_width = 0, screen_height = 0;
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
@ -142,9 +148,6 @@ meta_monitor_manager_test_apply_configuration (MetaMonitorManager *manager,
|
||||
crtc->current_mode = mode;
|
||||
crtc->transform = crtc_info->transform;
|
||||
|
||||
screen_width = MAX (screen_width, crtc_info->x + width);
|
||||
screen_height = MAX (screen_height, crtc_info->y + height);
|
||||
|
||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||
{
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||
@ -198,10 +201,93 @@ meta_monitor_manager_test_apply_configuration (MetaMonitorManager *manager,
|
||||
output->crtc = NULL;
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_screen_size (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
GList *l;
|
||||
int screen_width = 0;
|
||||
int screen_height = 0;
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
int right_edge;
|
||||
int bottom_edge;
|
||||
|
||||
right_edge = (logical_monitor_config->layout.width +
|
||||
logical_monitor_config->layout.x);
|
||||
if (right_edge > screen_width)
|
||||
screen_width = right_edge;
|
||||
|
||||
bottom_edge = (logical_monitor_config->layout.height +
|
||||
logical_monitor_config->layout.y);
|
||||
if (bottom_edge > screen_height)
|
||||
screen_height = bottom_edge;
|
||||
}
|
||||
|
||||
manager->screen_width = screen_width;
|
||||
manager->screen_height = screen_height;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_test_apply_monitors_config (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
|
||||
if (!meta_monitor_config_manager_assign (manager, config,
|
||||
&crtc_infos,
|
||||
&output_infos,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
apply_crtc_assignments (manager,
|
||||
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||
crtc_infos->len,
|
||||
(MetaOutputInfo **) output_infos->pdata,
|
||||
output_infos->len);
|
||||
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
|
||||
update_screen_size (manager, config);
|
||||
meta_monitor_manager_rebuild (manager, config);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
legacy_calculate_screen_size (MetaMonitorManager *manager)
|
||||
{
|
||||
unsigned int i;
|
||||
int width = 0, height = 0;
|
||||
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
{
|
||||
MetaCrtc *crtc = &manager->crtcs[i];
|
||||
|
||||
width = MAX (width, crtc->rect.x + crtc->rect.width);
|
||||
height = MAX (height, crtc->rect.y + crtc->rect.height);
|
||||
}
|
||||
|
||||
manager->screen_width = width;
|
||||
manager->screen_height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_test_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCrtcInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
apply_crtc_assignments (manager, crtcs, n_crtcs, outputs, n_outputs);
|
||||
legacy_calculate_screen_size (manager);
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
}
|
||||
|
||||
@ -249,6 +335,7 @@ meta_monitor_manager_test_class_init (MetaMonitorManagerTestClass *klass)
|
||||
|
||||
manager_class->read_current = meta_monitor_manager_test_read_current;
|
||||
manager_class->ensure_initial_config = meta_monitor_manager_test_ensure_initial_config;
|
||||
manager_class->apply_monitors_config = meta_monitor_manager_test_apply_monitors_config;
|
||||
manager_class->apply_configuration = meta_monitor_manager_test_apply_configuration;
|
||||
manager_class->tiled_monitor_added = meta_monitor_manager_test_tiled_monitor_added;
|
||||
manager_class->tiled_monitor_removed = meta_monitor_manager_test_tiled_monitor_removed;
|
||||
|
Loading…
Reference in New Issue
Block a user