monitor-manager: Clean up DPMS state tracking

DPMS is configured from a bit all over the place: via D-Bus, via X11 and
when reading the current KMS state. Each of these places did it slightly
differently, directly poking at the field in MetaMonitorManager.

To make things a bit more managable, move the field into a new
MetaMonitorManagerPrivate, and add helpers to get and set the current
value. Prior to this, there were for example situations where the DPMS
setting was changed, but without signal listeners being notified about
it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
This commit is contained in:
Jonas Ådahl 2019-01-11 14:45:44 +01:00
parent 72aeeb8c37
commit 4cae9b5b11
7 changed files with 120 additions and 48 deletions

View File

@ -1766,9 +1766,11 @@ power_save_mode_changed_cb (MetaMonitorManager *manager,
ClutterInputDevice *device;
MetaLogicalMonitor *logical_monitor;
MetaMonitor *builtin;
MetaPowerSave power_save_mode;
gboolean on;
on = (manager->power_save_mode == META_POWER_SAVE_ON);
power_save_mode = meta_monitor_manager_get_power_save_mode (manager);
on = power_save_mode == META_POWER_SAVE_ON;
priv = meta_input_settings_get_instance_private (user_data);
builtin = meta_monitor_manager_get_laptop_panel (manager);

View File

@ -116,8 +116,6 @@ struct _MetaMonitorManager
gboolean in_init;
unsigned int serial;
MetaPowerSave power_save_mode;
MetaLogicalMonitorLayoutMode layout_mode;
int screen_width;
@ -192,6 +190,8 @@ struct _MetaMonitorManagerClass
GBytes* (*read_edid) (MetaMonitorManager *,
MetaOutput *);
void (*read_current_state) (MetaMonitorManager *);
void (*ensure_initial_config) (MetaMonitorManager *);
gboolean (*apply_monitors_config) (MetaMonitorManager *,
@ -305,6 +305,11 @@ void meta_monitor_manager_get_screen_size (MetaMonitorManager *
int *width,
int *height);
MetaPowerSave meta_monitor_manager_get_power_save_mode (MetaMonitorManager *manager);
void meta_monitor_manager_power_save_mode_changed (MetaMonitorManager *manager,
MetaPowerSave mode);
void meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
gboolean ok);

View File

@ -95,7 +95,13 @@ static gfloat transform_matrices[][6] = {
static int signals[SIGNALS_LAST];
G_DEFINE_TYPE (MetaMonitorManager, meta_monitor_manager, G_TYPE_OBJECT)
typedef struct _MetaMonitorManagerPrivate
{
MetaPowerSave power_save_mode;
} MetaMonitorManagerPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitorManager, meta_monitor_manager,
G_TYPE_OBJECT)
static void initialize_dbus_interface (MetaMonitorManager *manager);
static void monitor_manager_setup_dbus_config_handlers (MetaMonitorManager *manager);
@ -107,6 +113,9 @@ meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
static MetaMonitor *
meta_monitor_manager_get_active_monitor (MetaMonitorManager *manager);
static void
meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager);
MetaBackend *
meta_monitor_manager_get_backend (MetaMonitorManager *manager)
{
@ -329,11 +338,24 @@ meta_monitor_manager_rebuild_logical_monitors_derived (MetaMonitorManager *manag
primary_logical_monitor);
}
void
meta_monitor_manager_power_save_mode_changed (MetaMonitorManager *manager,
MetaPowerSave mode)
{
MetaMonitorManagerPrivate *priv =
meta_monitor_manager_get_instance_private (manager);
priv->power_save_mode = mode;
g_signal_emit (manager, signals[POWER_SAVE_MODE_CHANGED], 0);
}
static void
power_save_mode_changed (MetaMonitorManager *manager,
GParamSpec *pspec,
gpointer user_data)
{
MetaMonitorManagerPrivate *priv =
meta_monitor_manager_get_instance_private (manager);
MetaMonitorManagerClass *klass;
int mode = meta_dbus_display_config_get_power_save_mode (manager->display_config);
@ -341,7 +363,7 @@ power_save_mode_changed (MetaMonitorManager *manager,
return;
/* If DPMS is unsupported, force the property back. */
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED)
if (priv->power_save_mode == META_POWER_SAVE_UNSUPPORTED)
{
meta_dbus_display_config_set_power_save_mode (manager->display_config, META_POWER_SAVE_UNSUPPORTED);
return;
@ -351,9 +373,7 @@ power_save_mode_changed (MetaMonitorManager *manager,
if (klass->set_power_save_mode)
klass->set_power_save_mode (manager, mode);
manager->power_save_mode = mode;
g_signal_emit (manager, signals[POWER_SAVE_MODE_CHANGED], 0);
meta_monitor_manager_power_save_mode_changed (manager, mode);
}
void
@ -855,6 +875,7 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
object_class->set_property = meta_monitor_manager_set_property;
klass->read_edid = meta_monitor_manager_real_read_edid;
klass->read_current_state = meta_monitor_manager_real_read_current_state;
signals[MONITORS_CHANGED] =
g_signal_new ("monitors-changed",
@ -2684,6 +2705,15 @@ meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
*height = manager->screen_height;
}
MetaPowerSave
meta_monitor_manager_get_power_save_mode (MetaMonitorManager *manager)
{
MetaMonitorManagerPrivate *priv =
meta_monitor_manager_get_instance_private (manager);
return priv->power_save_mode;
}
static void
rebuild_monitors (MetaMonitorManager *manager)
{
@ -2760,8 +2790,8 @@ meta_monitor_manager_is_transform_handled (MetaMonitorManager *manager,
return manager_class->is_transform_handled (manager, crtc, transform);
}
void
meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
static void
meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager)
{
GList *l;
@ -2782,6 +2812,15 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
rebuild_monitors (manager);
}
void
meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
{
MetaMonitorManagerClass *manager_class =
META_MONITOR_MANAGER_GET_CLASS (manager);
manager_class->read_current_state (manager);
}
static void
meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
{

View File

@ -210,7 +210,7 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
g_assert (meta_crtc_get_gpu (crtc) == META_GPU (gpu_kms));
if (monitor_manager->power_save_mode != META_POWER_SAVE_ON)
if (meta_monitor_manager_get_power_save_mode (monitor_manager))
return FALSE;
connected_crtc_found = FALSE;
@ -273,7 +273,8 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
int ret = -1;
g_assert (meta_crtc_get_gpu (crtc) == gpu);
g_assert (monitor_manager->power_save_mode == META_POWER_SAVE_ON);
g_assert (meta_monitor_manager_get_power_save_mode (monitor_manager) ==
META_POWER_SAVE_ON);
get_crtc_drm_connectors (gpu, crtc, &connectors, &n_connectors);
g_assert (n_connectors > 0);
@ -836,8 +837,6 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
GError **error)
{
MetaGpuKms *gpu_kms = META_GPU_KMS (gpu);
MetaMonitorManager *monitor_manager =
meta_gpu_get_monitor_manager (gpu);
MetaKmsResources resources;
g_autoptr (GError) local_error = NULL;
@ -855,8 +854,6 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
gpu_kms->max_buffer_width = resources.resources->max_width;
gpu_kms->max_buffer_height = resources.resources->max_height;
monitor_manager->power_save_mode = META_POWER_SAVE_ON;
/* Note: we must not free the public structures (output, crtc, monitor
mode and monitor info) here, they must be kept alive until the API
users are done with them after we emit monitors-changed, and thus

View File

@ -108,6 +108,21 @@ meta_monitor_manager_kms_read_edid (MetaMonitorManager *manager,
return meta_output_kms_read_edid (output);
}
static void
meta_monitor_manager_kms_read_current_state (MetaMonitorManager *manager)
{
MetaMonitorManagerClass *parent_class =
META_MONITOR_MANAGER_CLASS (meta_monitor_manager_kms_parent_class);
MetaPowerSave power_save_mode;
power_save_mode = meta_monitor_manager_get_power_save_mode (manager);
if (power_save_mode != META_POWER_SAVE_ON)
meta_monitor_manager_power_save_mode_changed (manager,
META_POWER_SAVE_ON);
parent_class->read_current_state (manager);
}
static void
meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
MetaPowerSave mode)
@ -755,6 +770,7 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
object_class->dispose = meta_monitor_manager_kms_dispose;
manager_class->read_edid = meta_monitor_manager_kms_read_edid;
manager_class->read_current_state = meta_monitor_manager_kms_read_current_state;
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->set_power_save_mode = meta_monitor_manager_kms_set_power_save_mode;

View File

@ -97,8 +97,6 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
GList *l;
int min_width, min_height;
Screen *screen;
BOOL dpms_capable, dpms_enabled;
CARD16 dpms_state;
GList *outputs = NULL;
GList *modes = NULL;
GList *crtcs = NULL;
@ -107,36 +105,6 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
XRRFreeScreenResources (gpu_xrandr->resources);
gpu_xrandr->resources = NULL;
dpms_capable = DPMSCapable (xdisplay);
if (dpms_capable &&
DPMSInfo (xdisplay, &dpms_state, &dpms_enabled) &&
dpms_enabled)
{
switch (dpms_state)
{
case DPMSModeOn:
monitor_manager->power_save_mode = META_POWER_SAVE_ON;
break;
case DPMSModeStandby:
monitor_manager->power_save_mode = META_POWER_SAVE_STANDBY;
break;
case DPMSModeSuspend:
monitor_manager->power_save_mode = META_POWER_SAVE_SUSPEND;
break;
case DPMSModeOff:
monitor_manager->power_save_mode = META_POWER_SAVE_OFF;
break;
default:
monitor_manager->power_save_mode = META_POWER_SAVE_UNSUPPORTED;
break;
}
}
else
{
monitor_manager->power_save_mode = META_POWER_SAVE_UNSUPPORTED;
}
XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay),
&min_width,
&min_height,

View File

@ -121,6 +121,50 @@ meta_monitor_manager_xrandr_read_edid (MetaMonitorManager *manager,
return meta_output_xrandr_read_edid (output);
}
static MetaPowerSave
x11_dpms_state_to_power_save (CARD16 dpms_state)
{
switch (dpms_state)
{
case DPMSModeOn:
return META_POWER_SAVE_ON;
case DPMSModeStandby:
return META_POWER_SAVE_STANDBY;
case DPMSModeSuspend:
return META_POWER_SAVE_SUSPEND;
case DPMSModeOff:
return META_POWER_SAVE_OFF;
default:
return META_POWER_SAVE_UNSUPPORTED;
}
}
static void
meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager)
{
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
MetaMonitorManagerClass *parent_class =
META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class);
Display *xdisplay = meta_monitor_manager_xrandr_get_xdisplay (manager_xrandr);
BOOL dpms_capable, dpms_enabled;
CARD16 dpms_state;
MetaPowerSave power_save_mode;
dpms_capable = DPMSCapable (xdisplay);
if (dpms_capable &&
DPMSInfo (xdisplay, &dpms_state, &dpms_enabled) &&
dpms_enabled)
power_save_mode = x11_dpms_state_to_power_save (dpms_state);
else
power_save_mode = META_POWER_SAVE_UNSUPPORTED;
meta_monitor_manager_power_save_mode_changed (manager, power_save_mode);
parent_class->read_current_state (manager);
}
static void
meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager,
MetaPowerSave mode)
@ -1046,6 +1090,7 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
object_class->constructed = meta_monitor_manager_xrandr_constructed;
manager_class->read_edid = meta_monitor_manager_xrandr_read_edid;
manager_class->read_current_state = meta_monitor_manager_xrandr_read_current_state;
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->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode;