summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagn@redhat.com>2013-07-24 10:39:06 +0200
committerGiovanni Campagna <gcampagna@src.gnome.org>2013-08-18 00:33:37 +0200
commite039add2404ace8c75c2115de0874acd736a0a4b (patch)
tree2d683e1f61f7549087779b51f53d8c1bba391086
parentdbd8d4d5982e5affef212a1926209f68b8224017 (diff)
downloadmutter-e039add2404ace8c75c2115de0874acd736a0a4b.tar.gz
MonitorManager: add support for DPMS levels
To the XRandR and dummy backend (and as usual the dummy backend has no effect) https://bugzilla.gnome.org/show_bug.cgi?id=705670
-rw-r--r--src/Makefile.am1
-rw-r--r--src/core/meta-xrandr-shared.h40
-rw-r--r--src/core/monitor-private.h1
-rw-r--r--src/core/monitor.c123
-rw-r--r--src/xrandr.xml30
5 files changed, 195 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ac03bd4d3..3e2284e53 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -111,6 +111,7 @@ libmutter_la_SOURCES = \
core/keybindings.c \
core/keybindings-private.h \
core/main.c \
+ core/meta-xrandr-shared.h \
core/monitor.c \
core/monitor-private.h \
core/mutter-Xatomtype.h \
diff --git a/src/core/meta-xrandr-shared.h b/src/core/meta-xrandr-shared.h
new file mode 100644
index 000000000..c98f58103
--- /dev/null
+++ b/src/core/meta-xrandr-shared.h
@@ -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
diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index 21b4bd7c7..b2458ba0d 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -46,6 +46,7 @@
#ifdef HAVE_WAYLAND
#include <wayland-server.h>
#endif
+#include "meta-xrandr-shared.h"
#ifndef HAVE_WAYLAND
enum wl_output_transform {
diff --git a/src/core/monitor.c b/src/core/monitor.c
index 3ff66ea7c..a930ba633 100644
--- a/src/core/monitor.c
+++ b/src/core/monitor.c
@@ -33,6 +33,7 @@
#ifdef HAVE_RANDR
#include <X11/extensions/Xrandr.h>
+#include <X11/extensions/dpms.h>
#endif
#include <meta/main.h>
@@ -62,6 +63,8 @@ struct _MetaMonitorManager
unsigned int serial;
+ MetaPowerSave power_save_mode;
+
int max_screen_width;
int max_screen_height;
int screen_width;
@@ -108,6 +111,12 @@ enum {
SIGNALS_LAST
};
+enum {
+ PROP_0,
+ PROP_POWER_SAVE_MODE,
+ PROP_LAST
+};
+
static int signals[SIGNALS_LAST];
static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface);
@@ -332,11 +341,40 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager)
unsigned int n_actual_outputs;
int min_width, min_height;
Screen *screen;
+ BOOL dpms_capable, dpms_enabled;
+ CARD16 dpms_state;
if (manager->resources)
XRRFreeScreenResources (manager->resources);
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),
&min_width,
&min_height,
@@ -710,6 +748,49 @@ meta_monitor_manager_new (Display *display)
}
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
free_output_array (MetaOutput *old_outputs,
int n_old_outputs)
{
@@ -757,10 +838,50 @@ meta_monitor_manager_dispose (GObject *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
meta_monitor_manager_class_init (MetaMonitorManagerClass *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->finalize = meta_monitor_manager_finalize;
@@ -771,6 +892,8 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
+
+ g_object_class_override_property (object_class, PROP_POWER_SAVE_MODE, "power-save-mode");
}
static const double known_diagonals[] = {
diff --git a/src/xrandr.xml b/src/xrandr.xml
index f17a4c1fb..40c94ab84 100644
--- a/src/xrandr.xml
+++ b/src/xrandr.xml
@@ -194,5 +194,35 @@
<arg name="crtcs" direction="in" type="a(uiiiuaua{sv})" />
<arg name="outputs" direction="in" type="a(ua{sv})" />
</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>
</node>