MonitorManager: add support for DPMS levels

To the XRandR and dummy backend (and as usual the dummy backend
has no effect)
This commit is contained in:
Giovanni Campagna 2013-07-24 10:39:06 +02:00
parent e2f06dfa8c
commit 97ff406102
5 changed files with 195 additions and 0 deletions

View File

@ -126,6 +126,7 @@ libmutter_la_SOURCES = \
core/main.c \ core/main.c \
core/meta-cursor-tracker.c \ core/meta-cursor-tracker.c \
core/meta-cursor-tracker-private.h \ core/meta-cursor-tracker-private.h \
core/meta-xrandr-shared.h \
core/monitor.c \ core/monitor.c \
core/monitor-private.h \ core/monitor-private.h \
core/mutter-Xatomtype.h \ core/mutter-Xatomtype.h \

View File

@ -0,0 +1,40 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2013 Red Hat Inc.
*
* 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.
*/
/* This file is shared between mutter (src/core/meta-xrandr-shared.h)
and gnome-desktop (libgnome-desktop/meta-xrandr-shared.h).
The canonical place for all changes is mutter.
There should be no includes in this file.
*/
#ifndef META_XRANDR_SHARED_H
#define META_XRANDR_SHARED_H
typedef enum {
META_POWER_SAVE_UNKNOWN = -1,
META_POWER_SAVE_ON = 0,
META_POWER_SAVE_STANDBY,
META_POWER_SAVE_SUSPEND,
META_POWER_SAVE_OFF,
} MetaPowerSave;
#endif

View File

@ -46,6 +46,7 @@
#ifdef HAVE_WAYLAND #ifdef HAVE_WAYLAND
#include <wayland-server.h> #include <wayland-server.h>
#endif #endif
#include "meta-xrandr-shared.h"
#ifndef HAVE_WAYLAND #ifndef HAVE_WAYLAND
enum wl_output_transform { enum wl_output_transform {

View File

@ -32,6 +32,7 @@
#ifdef HAVE_RANDR #ifdef HAVE_RANDR
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#include <X11/extensions/dpms.h>
#endif #endif
#include <meta/main.h> #include <meta/main.h>
@ -64,6 +65,8 @@ struct _MetaMonitorManager
unsigned int serial; unsigned int serial;
MetaPowerSave power_save_mode;
int max_screen_width; int max_screen_width;
int max_screen_height; int max_screen_height;
int screen_width; int screen_width;
@ -110,6 +113,12 @@ enum {
SIGNALS_LAST SIGNALS_LAST
}; };
enum {
PROP_0,
PROP_POWER_SAVE_MODE,
PROP_LAST
};
static int signals[SIGNALS_LAST]; static int signals[SIGNALS_LAST];
static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface); static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface);
@ -334,11 +343,40 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager)
unsigned int n_actual_outputs; unsigned int n_actual_outputs;
int min_width, min_height; int min_width, min_height;
Screen *screen; Screen *screen;
BOOL dpms_capable, dpms_enabled;
CARD16 dpms_state;
if (manager->resources) if (manager->resources)
XRRFreeScreenResources (manager->resources); XRRFreeScreenResources (manager->resources);
manager->resources = NULL; manager->resources = NULL;
meta_error_trap_push (meta_get_display ());
dpms_capable = DPMSCapable (manager->xdisplay);
meta_error_trap_pop (meta_get_display ());
if (dpms_capable &&
DPMSInfo (manager->xdisplay, &dpms_state, &dpms_enabled) &&
dpms_enabled)
{
switch (dpms_state)
{
case DPMSModeOn:
manager->power_save_mode = META_POWER_SAVE_ON;
case DPMSModeStandby:
manager->power_save_mode = META_POWER_SAVE_STANDBY;
case DPMSModeSuspend:
manager->power_save_mode = META_POWER_SAVE_SUSPEND;
case DPMSModeOff:
manager->power_save_mode = META_POWER_SAVE_OFF;
default:
manager->power_save_mode = META_POWER_SAVE_UNKNOWN;
}
}
else
{
manager->power_save_mode = META_POWER_SAVE_UNKNOWN;
}
XRRGetScreenSizeRange (manager->xdisplay, DefaultRootWindow (manager->xdisplay), XRRGetScreenSizeRange (manager->xdisplay, DefaultRootWindow (manager->xdisplay),
&min_width, &min_width,
&min_height, &min_height,
@ -866,6 +904,49 @@ meta_monitor_manager_new (Display *display)
return manager; return manager;
} }
static void
meta_monitor_manager_set_power_save_mode (MetaMonitorManager *manager,
MetaPowerSave mode)
{
if (mode == manager->power_save_mode)
return;
if (manager->power_save_mode == META_POWER_SAVE_UNKNOWN ||
mode == META_POWER_SAVE_UNKNOWN)
return;
#ifdef HAVE_RANDR
if (manager->backend == META_BACKEND_XRANDR)
{
CARD16 state;
switch (mode) {
case META_POWER_SAVE_ON:
state = DPMSModeOn;
break;
case META_POWER_SAVE_STANDBY:
state = DPMSModeStandby;
break;
case META_POWER_SAVE_SUSPEND:
state = DPMSModeSuspend;
break;
case META_POWER_SAVE_OFF:
state = DPMSModeOff;
break;
default:
return;
}
meta_error_trap_push (meta_get_display ());
DPMSForceLevel (manager->xdisplay, state);
DPMSSetTimeouts (manager->xdisplay, 0, 0, 0);
meta_error_trap_pop (meta_get_display ());
}
#endif
manager->power_save_mode = mode;
}
static void static void
free_output_array (MetaOutput *old_outputs, free_output_array (MetaOutput *old_outputs,
int n_old_outputs) int n_old_outputs)
@ -913,11 +994,51 @@ meta_monitor_manager_dispose (GObject *object)
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object); G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
} }
static void
meta_monitor_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaMonitorManager *self = META_MONITOR_MANAGER (object);
switch (prop_id)
{
case PROP_POWER_SAVE_MODE:
meta_monitor_manager_set_power_save_mode (self, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_monitor_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaMonitorManager *self = META_MONITOR_MANAGER (object);
switch (prop_id)
{
case PROP_POWER_SAVE_MODE:
g_value_set_int (value, self->power_save_mode);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void static void
meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = meta_monitor_manager_get_property;
object_class->set_property = meta_monitor_manager_set_property;
object_class->dispose = meta_monitor_manager_dispose; object_class->dispose = meta_monitor_manager_dispose;
object_class->finalize = meta_monitor_manager_finalize; object_class->finalize = meta_monitor_manager_finalize;
@ -928,6 +1049,8 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
g_object_class_override_property (object_class, PROP_POWER_SAVE_MODE, "power-save-mode");
} }
static const double known_diagonals[] = { static const double known_diagonals[] = {

View File

@ -196,5 +196,35 @@
<arg name="crtcs" direction="in" type="a(uiiiuaua{sv})" /> <arg name="crtcs" direction="in" type="a(uiiiuaua{sv})" />
<arg name="outputs" direction="in" type="a(ua{sv})" /> <arg name="outputs" direction="in" type="a(ua{sv})" />
</method> </method>
<!--
PowerSaveMode:
Contains the current power saving mode for the screen, and
allows changing it.
Possible values:
- 0: on
- 1: standby
- 2: suspend
- 3: off
- -1: unknown (unsupported)
A client should not attempt to change the powersave mode
from -1 (unknown) to any other value, and viceversa.
Note that the actual effects of the different values
depend on the hardware and the kernel driver in use, and
it's perfectly possible that all values different than on
have the same effect.
Also, setting the PowerSaveMode to 3 (off) may or may
not have the same effect as disabling all outputs by
setting no CRTC on them with ApplyConfiguration(), and
may or may not cause a configuration change.
Also note that this property might become out of date
if changed through different means (for example using the
XRandR interface directly).
-->
<property name="PowerSaveMode" type="i" access="readwrite" />
</interface> </interface>
</node> </node>