[gnome-desktop] Add the capability to get and set the DPMS mode of the screen



commit 4e7dac8fb6590a51054550b177b31b1991f7981e
Author: Richard Hughes <richard hughsie com>
Date:   Mon Jul 4 14:25:07 2011 +0100

    Add the capability to get and set the DPMS mode of the screen
    
    This is presently per-screen, but future versions of xrandr will allow us to
    set the DPMS mode of each output.
    
    This functionality is required by the power plugin in gnome-settings-daemon.

 libgnome-desktop/gnome-rr-private.h |    1 +
 libgnome-desktop/gnome-rr.c         |  125 +++++++++++++++++++++++++++++++++++
 libgnome-desktop/gnome-rr.h         |   17 +++++
 3 files changed, 143 insertions(+), 0 deletions(-)
---
diff --git a/libgnome-desktop/gnome-rr-private.h b/libgnome-desktop/gnome-rr-private.h
index b66cc29..1daf1bd 100644
--- a/libgnome-desktop/gnome-rr-private.h
+++ b/libgnome-desktop/gnome-rr-private.h
@@ -47,6 +47,7 @@ struct GnomeRRScreenPrivate
     int				rr_minor_version;
     
     Atom                        connector_type_atom;
+    gboolean                    dpms_capable;
 };
 
 struct GnomeRROutputInfoPrivate
diff --git a/libgnome-desktop/gnome-rr.c b/libgnome-desktop/gnome-rr.c
index a546967..1ed4a56 100644
--- a/libgnome-desktop/gnome-rr.c
+++ b/libgnome-desktop/gnome-rr.c
@@ -36,6 +36,7 @@
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include <X11/Xatom.h>
+#include <X11/extensions/dpms.h>
 
 #undef GNOME_DISABLE_DEPRECATED
 #include "gnome-rr.h"
@@ -532,6 +533,11 @@ fill_out_screen_info (Display *xdisplay,
     }
 #endif
 
+    /* can the screen do DPMS? */
+    gdk_error_trap_push ();
+    priv->dpms_capable = DPMSCapable (priv->xdisplay);
+    gdk_error_trap_pop_ignored ();
+
     return TRUE;
 #else
     return FALSE;
@@ -1166,6 +1172,125 @@ gnome_rr_screen_refresh (GnomeRRScreen *screen,
 }
 
 /**
+ * gnome_rr_screen_get_dpms_mode:
+ **/
+gboolean
+gnome_rr_screen_get_dpms_mode (GnomeRRScreen *screen,
+                               GnomeRRDpmsMode *mode,
+                               GError **error)
+{
+    BOOL enabled = FALSE;
+    CARD16 state;
+    gboolean ret = FALSE;
+
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+    g_return_val_if_fail (mode != NULL, FALSE);
+
+    if (!screen->priv->dpms_capable) {
+        g_set_error_literal (error,
+                             GNOME_RR_ERROR,
+                             GNOME_RR_ERROR_NO_DPMS_EXTENSION,
+                             "Display is not DPMS capable");
+        goto out;
+    }
+
+    if (!DPMSInfo (screen->priv->xdisplay,
+                   &state,
+                   &enabled)) {
+        g_set_error_literal (error,
+                             GNOME_RR_ERROR,
+                             GNOME_RR_ERROR_UNKNOWN,
+                             "Unable to get DPMS state");
+        goto out;
+    }
+
+    /* DPMS not enabled is a valid mode */
+    if (!enabled) {
+        *mode = GNOME_RR_DPMS_DISABLED;
+        ret = TRUE;
+        goto out;
+    }
+
+    switch (state) {
+    case DPMSModeOn:
+        *mode = GNOME_RR_DPMS_ON;
+        break;
+    case DPMSModeStandby:
+        *mode = GNOME_RR_DPMS_STANDBY;
+        break;
+    case DPMSModeSuspend:
+        *mode = GNOME_RR_DPMS_SUSPEND;
+        break;
+    case DPMSModeOff:
+        *mode = GNOME_RR_DPMS_OFF;
+        break;
+    default:
+        g_assert_not_reached ();
+        break;
+    }
+    ret = TRUE;
+out:
+    return ret;
+}
+
+/**
+ * gnome_rr_screen_set_dpms_mode:
+ **/
+gboolean
+gnome_rr_screen_set_dpms_mode (GnomeRRScreen *screen,
+                               GnomeRRDpmsMode mode,
+                               GError **error)
+{
+    CARD16 state = 0;
+    gboolean ret;
+    GnomeRRDpmsMode current_mode;
+
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+    /* set, if the new mode is different */
+    ret = gnome_rr_screen_get_dpms_mode (screen, &current_mode, error);
+    if (!ret)
+        goto out;
+    if (current_mode == mode)
+        goto out;
+
+    switch (state) {
+    case GNOME_RR_DPMS_ON:
+        state = DPMSModeOn;
+        break;
+    case GNOME_RR_DPMS_STANDBY:
+        state = DPMSModeStandby;
+        break;
+    case GNOME_RR_DPMS_SUSPEND:
+        state = DPMSModeSuspend;
+        break;
+    case GNOME_RR_DPMS_OFF:
+        state = DPMSModeOff;
+        break;
+    default:
+        g_assert_not_reached ();
+        break;
+    }
+
+    gdk_error_trap_push ();
+    ret = DPMSForceLevel (screen->priv->xdisplay, state);
+    gdk_flush ();
+    if (gdk_error_trap_pop ())
+        ret = FALSE;
+
+    if (!ret) {
+        ret = FALSE;
+        g_set_error_literal (error,
+                             GNOME_RR_ERROR,
+                             GNOME_RR_ERROR_UNKNOWN,
+                             "Could not change DPMS mode");
+        goto out;
+    }
+out:
+    return ret;
+}
+
+/**
  * gnome_rr_screen_list_modes:
  *
  * List available XRandR modes
diff --git a/libgnome-desktop/gnome-rr.h b/libgnome-desktop/gnome-rr.h
index c3bf46e..a4f4c9d 100644
--- a/libgnome-desktop/gnome-rr.h
+++ b/libgnome-desktop/gnome-rr.h
@@ -60,6 +60,15 @@ typedef enum
     GNOME_RR_REFLECT_Y =	(1 << 5)
 } GnomeRRRotation;
 
+typedef enum {
+	GNOME_RR_DPMS_ON,
+	GNOME_RR_DPMS_STANDBY,
+	GNOME_RR_DPMS_SUSPEND,
+	GNOME_RR_DPMS_OFF,
+	GNOME_RR_DPMS_DISABLED,
+	GNOME_RR_DPMS_UNKNOWN
+} GnomeRRDpmsMode;
+
 /* Error codes */
 
 #define GNOME_RR_ERROR (gnome_rr_error_quark ())
@@ -73,6 +82,7 @@ typedef enum {
     GNOME_RR_ERROR_BOUNDS_ERROR,	/* requested bounds of a CRTC are outside the maximum size */
     GNOME_RR_ERROR_CRTC_ASSIGNMENT,	/* could not assign CRTCs to outputs */
     GNOME_RR_ERROR_NO_MATCHING_CONFIG,	/* none of the saved configurations matched the current configuration */
+    GNOME_RR_ERROR_NO_DPMS_EXTENSION,	/* DPMS extension is not present */
 } GnomeRRError;
 
 #define GNOME_RR_CONNECTOR_TYPE_PANEL "Panel"  /* This is a laptop's built-in LCD */
@@ -127,6 +137,13 @@ void            gnome_rr_screen_set_primary_output (GnomeRRScreen         *scree
 
 GnomeRRMode   **gnome_rr_screen_create_clone_modes (GnomeRRScreen *screen);
 
+gboolean        gnome_rr_screen_get_dpms_mode      (GnomeRRScreen        *screen,
+                                                    GnomeRRDpmsMode       *mode,
+                                                    GError               **error);
+gboolean        gnome_rr_screen_set_dpms_mode      (GnomeRRScreen         *screen,
+                                                    GnomeRRDpmsMode        mode,
+                                                    GError              **error);
+
 /* GnomeRROutput */
 guint32         gnome_rr_output_get_id             (GnomeRROutput         *output);
 const char *    gnome_rr_output_get_name           (GnomeRROutput         *output);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]