/* * * * Copyright (C) 2008-2011 Ali * * Licensed under the GNU General Public License Version 2 * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #endif #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include #include #include "xfpm-common.h" #include "xfpm-dpms.h" #include "xfpm-xfconf.h" #include "xfpm-config.h" #include "xfpm-debug.h" static void xfpm_dpms_finalize (GObject *object); struct XfpmDpmsPrivate { XfpmXfconf *conf; gboolean dpms_capable; gboolean inhibited; gboolean on_battery; gulong switch_off_timeout_id; gulong switch_on_timeout_id; }; G_DEFINE_TYPE_WITH_PRIVATE (XfpmDpms, xfpm_dpms, G_TYPE_OBJECT) static void xfpm_dpms_set_timeouts (XfpmDpms *dpms, guint16 standby, guint16 suspend, guint off) { CARD16 x_standby = 0 , x_suspend = 0, x_off = 0; DPMSGetTimeouts (gdk_x11_get_default_xdisplay(), &x_standby, &x_suspend, &x_off); if ( standby != x_standby || suspend != x_suspend || off != x_off ) { XFPM_DEBUG ("Settings dpms: standby=%d suspend=%d off=%d\n", standby, suspend, off); DPMSSetTimeouts (gdk_x11_get_default_xdisplay(), standby, suspend, off ); } } /* * Disable DPMS */ static void xfpm_dpms_disable (XfpmDpms *dpms) { BOOL state; CARD16 power_level; if (!DPMSInfo (gdk_x11_get_default_xdisplay(), &power_level, &state) ) g_warning ("Cannot get DPMSInfo"); if ( state ) DPMSDisable (gdk_x11_get_default_xdisplay()); } /* * Enable DPMS */ static void xfpm_dpms_enable (XfpmDpms *dpms) { BOOL state; CARD16 power_level; if (!DPMSInfo (gdk_x11_get_default_xdisplay(), &power_level, &state) ) g_warning ("Cannot get DPMSInfo"); if ( !state ) DPMSEnable (gdk_x11_get_default_xdisplay()); } static void xfpm_dpms_get_enabled (XfpmDpms *dpms, gboolean *dpms_enabled) { g_object_get (G_OBJECT (dpms->priv->conf), DPMS_ENABLED_CFG, dpms_enabled, NULL); } static void xfpm_dpms_get_sleep_mode (XfpmDpms *dpms, gboolean *ret_standby_mode) { gchar *sleep_mode; g_object_get (G_OBJECT (dpms->priv->conf), DPMS_SLEEP_MODE, &sleep_mode, NULL); if ( !g_strcmp0 (sleep_mode, "Standby")) *ret_standby_mode = TRUE; else *ret_standby_mode = FALSE; g_free (sleep_mode); } static void xfpm_dpms_get_configuration_timeouts (XfpmDpms *dpms, guint16 *ret_sleep, guint16 *ret_off ) { guint sleep_time, off_time; g_object_get (G_OBJECT (dpms->priv->conf), dpms->priv->on_battery ? ON_BATT_DPMS_SLEEP : ON_AC_DPMS_SLEEP, &sleep_time, dpms->priv->on_battery ? ON_BATT_DPMS_OFF : ON_AC_DPMS_OFF, &off_time, NULL); *ret_sleep = sleep_time * 60; *ret_off = off_time * 60; } void xfpm_dpms_refresh (XfpmDpms *dpms) { gboolean enabled; guint16 off_timeout; guint16 sleep_timeout; gboolean sleep_mode; if ( dpms->priv->inhibited) { xfpm_dpms_disable (dpms); return; } xfpm_dpms_get_enabled (dpms, &enabled); if ( !enabled ) { xfpm_dpms_disable (dpms); return; } xfpm_dpms_enable (dpms); xfpm_dpms_get_configuration_timeouts (dpms, &sleep_timeout, &off_timeout); xfpm_dpms_get_sleep_mode (dpms, &sleep_mode); if (sleep_mode == TRUE ) { xfpm_dpms_set_timeouts (dpms, sleep_timeout, 0, off_timeout); } else { xfpm_dpms_set_timeouts (dpms, 0, sleep_timeout, off_timeout ); } } static void xfpm_dpms_settings_changed_cb (GObject *obj, GParamSpec *spec, XfpmDpms *dpms) { if ( g_str_has_prefix (spec->name, "dpms")) { XFPM_DEBUG ("Configuration changed"); xfpm_dpms_refresh (dpms); } } static void xfpm_dpms_class_init(XfpmDpmsClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->finalize = xfpm_dpms_finalize; } /* * Check if the display is DPMS capabale if not do nothing. */ static void xfpm_dpms_init(XfpmDpms *dpms) { dpms->priv = xfpm_dpms_get_instance_private(dpms); dpms->priv->dpms_capable = DPMSCapable (gdk_x11_get_default_xdisplay()); dpms->priv->switch_off_timeout_id = 0; dpms->priv->switch_on_timeout_id = 0; if ( dpms->priv->dpms_capable ) { dpms->priv->conf = xfpm_xfconf_new (); g_signal_connect (dpms->priv->conf, "notify", G_CALLBACK (xfpm_dpms_settings_changed_cb), dpms); xfpm_dpms_refresh (dpms); } else { g_warning ("Monitor is not DPMS capable"); } } static void xfpm_dpms_finalize(GObject *object) { XfpmDpms *dpms; dpms = XFPM_DPMS (object); g_object_unref (dpms->priv->conf); G_OBJECT_CLASS(xfpm_dpms_parent_class)->finalize(object); } XfpmDpms * xfpm_dpms_new (void) { static gpointer xfpm_dpms_object = NULL; if ( G_LIKELY (xfpm_dpms_object != NULL ) ) { g_object_ref (xfpm_dpms_object); } else { xfpm_dpms_object = g_object_new (XFPM_TYPE_DPMS, NULL); g_object_add_weak_pointer (xfpm_dpms_object, &xfpm_dpms_object); } return XFPM_DPMS (xfpm_dpms_object); } gboolean xfpm_dpms_capable (XfpmDpms *dpms) { g_return_val_if_fail (XFPM_IS_DPMS(dpms), FALSE); return dpms->priv->dpms_capable; } void xfpm_dpms_force_level (XfpmDpms *dpms, CARD16 level) { CARD16 current_level; BOOL current_state; XFPM_DEBUG ("start"); if ( !dpms->priv->dpms_capable ) goto out; if ( G_UNLIKELY (!DPMSInfo (gdk_x11_get_default_xdisplay (), ¤t_level, ¤t_state)) ) { g_warning ("Cannot get DPMSInfo"); goto out; } if ( !current_state ) { XFPM_DEBUG ("DPMS is disabled"); goto out; } if ( current_level != level ) { XFPM_DEBUG ("Forcing DPMS mode %d", level); if ( !DPMSForceLevel (gdk_x11_get_default_xdisplay (), level ) ) { g_warning ("Cannot set Force DPMS level %d", level); goto out; } if ( level == DPMSModeOn ) XResetScreenSaver (gdk_x11_get_default_xdisplay ()); XSync (gdk_x11_get_default_xdisplay (), FALSE); } else { XFPM_DEBUG ("No need to change DPMS mode, current_level=%d requested_level=%d", current_level, level); } out: ; } gboolean xfpm_dpms_is_inhibited (XfpmDpms *dpms) { return dpms->priv->inhibited; } void xfpm_dpms_inhibit (XfpmDpms *dpms, gboolean inhibit) { if ( dpms->priv->inhibited == inhibit ) return; dpms->priv->inhibited = inhibit; xfpm_dpms_refresh (dpms); XFPM_DEBUG ("dpms inhibited %s", inhibit ? "TRUE" : "FALSE"); } void xfpm_dpms_set_on_battery (XfpmDpms *dpms, gboolean on_battery) { if ( dpms->priv->on_battery == on_battery ) return; dpms->priv->on_battery = on_battery; xfpm_dpms_refresh (dpms); XFPM_DEBUG ("dpms on battery %s", on_battery ? "TRUE" : "FALSE"); }