You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
504 lines
14 KiB
504 lines
14 KiB
/*
|
|
* This file is part of the KDE project, module kcontrol.
|
|
* Copyright (C) 1999 Geert Jansen <g.t.jansen@stud.tue.nl>
|
|
*
|
|
* You can Freely distribute this program under the GNU General Public
|
|
* License. See the file "COPYING" for the exact licensing terms.
|
|
*
|
|
* Based on kcontrol1 energy.cpp, Copyright (c) 1999 Tom Vijlbrief
|
|
*/
|
|
|
|
|
|
/*
|
|
* KDE Energy setup module.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#if !defined(QT_CLEAN_NAMESPACE)
|
|
#define QT_CLEAN_NAMESPACE
|
|
#endif
|
|
|
|
#include <tqcheckbox.h>
|
|
#include <tqlabel.h>
|
|
#include <tqlayout.h>
|
|
#include <tqwhatsthis.h>
|
|
#include <tqpushbutton.h>
|
|
|
|
#include <tdeconfig.h>
|
|
#include <kcursor.h>
|
|
#include <kdialog.h>
|
|
#include <kiconloader.h>
|
|
#include <tdelocale.h>
|
|
#include <knuminput.h>
|
|
#include <krun.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kurllabel.h>
|
|
#include <dcopref.h>
|
|
|
|
#include <X11/X.h>
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xatom.h>
|
|
#include <X11/Xutil.h>
|
|
#include <X11/Xos.h>
|
|
|
|
#include "energy.h"
|
|
|
|
|
|
#ifdef HAVE_DPMS
|
|
#include <X11/Xmd.h>
|
|
extern "C" {
|
|
#include <X11/extensions/dpms.h>
|
|
Status DPMSInfo ( Display *, CARD16 *, BOOL * );
|
|
Bool DPMSCapable( Display * );
|
|
int __kde_do_not_unload = 1;
|
|
|
|
#ifndef HAVE_DPMSCAPABLE_PROTO
|
|
Bool DPMSCapable ( Display * );
|
|
#endif
|
|
|
|
#ifndef HAVE_DPMSINFO_PROTO
|
|
Status DPMSInfo ( Display *, CARD16 *, BOOL * );
|
|
#endif
|
|
}
|
|
|
|
#if defined(XIMStringConversionRetrival) || defined (__sun) || defined(__hpux)
|
|
extern "C" {
|
|
#endif
|
|
Bool DPMSQueryExtension(Display *, int *, int *);
|
|
Status DPMSEnable(Display *);
|
|
Status DPMSDisable(Display *);
|
|
Bool DPMSGetTimeouts(Display *, CARD16 *, CARD16 *, CARD16 *);
|
|
Bool DPMSSetTimeouts(Display *, CARD16, CARD16, CARD16);
|
|
#if defined(XIMStringConversionRetrival) || defined (__sun) || defined(__hpux)
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
static const int DFLT_STANDBY = 0;
|
|
static const int DFLT_SUSPEND = 30;
|
|
static const int DFLT_OFF = 60;
|
|
|
|
|
|
/**** DLL Interface ****/
|
|
|
|
extern "C" {
|
|
|
|
KDE_EXPORT TDECModule *create_energy(TQWidget *parent, char *) {
|
|
return new KEnergy(parent, "kcmenergy");
|
|
}
|
|
|
|
KDE_EXPORT void init_energy() {
|
|
#ifdef HAVE_DPMS
|
|
TDEConfig *cfg = new TDEConfig("kcmdisplayrc", true /*readonly*/, false /*no globals*/);
|
|
cfg->setGroup("DisplayEnergy");
|
|
|
|
Display *dpy = tqt_xdisplay();
|
|
CARD16 pre_configured_status;
|
|
BOOL pre_configured_enabled;
|
|
CARD16 pre_configured_standby;
|
|
CARD16 pre_configured_suspend;
|
|
CARD16 pre_configured_off;
|
|
bool enabled;
|
|
CARD16 standby;
|
|
CARD16 suspend;
|
|
CARD16 off;
|
|
int dummy;
|
|
/* query the running X server if DPMS is supported */
|
|
if (DPMSQueryExtension(dpy, &dummy, &dummy) && DPMSCapable(dpy)) {
|
|
DPMSGetTimeouts(dpy, &pre_configured_standby, &pre_configured_suspend, &pre_configured_off);
|
|
DPMSInfo(dpy, &pre_configured_status, &pre_configured_enabled);
|
|
/* let the user override the settings */
|
|
enabled = cfg->readBoolEntry("displayEnergySaving", pre_configured_enabled);
|
|
standby = cfg->readNumEntry("displayStandby", pre_configured_standby/60);
|
|
suspend = cfg->readNumEntry("displaySuspend", pre_configured_suspend/60);
|
|
off = cfg->readNumEntry("displayPowerOff", pre_configured_off/60);
|
|
} else {
|
|
/* provide our defauts */
|
|
enabled = true;
|
|
standby = DFLT_STANDBY;
|
|
suspend = DFLT_SUSPEND;
|
|
off = DFLT_OFF;
|
|
}
|
|
|
|
delete cfg;
|
|
|
|
KEnergy::applySettings(enabled, standby, suspend, off);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/**** KEnergy ****/
|
|
|
|
KEnergy::KEnergy(TQWidget *parent, const char *name)
|
|
: TDECModule(parent, name)
|
|
{
|
|
m_bChanged = false;
|
|
m_bEnabled = false;
|
|
m_Standby = DFLT_STANDBY;
|
|
m_Suspend = DFLT_SUSPEND;
|
|
m_Off = DFLT_OFF;
|
|
m_bDPMS = false;
|
|
m_bKPowersave = false;
|
|
m_bTDEPowersave = false;
|
|
m_bMaintainSanity = true;
|
|
|
|
setQuickHelp( i18n("<h1>Display Power Control</h1> If your display supports"
|
|
" power saving features, you can configure them using this module.<p>"
|
|
" There are three levels of power saving: standby, suspend, and off."
|
|
" The greater the level of power saving, the longer it takes for the"
|
|
" display to return to an active state.<p>"
|
|
" To wake up the display from a power saving mode, you can make a small"
|
|
" movement with the mouse, or press a key that is not likely to cause"
|
|
" any unintentional side-effects, for example, the \"Shift\" key."));
|
|
|
|
#ifdef HAVE_DPMS
|
|
int dummy;
|
|
m_bDPMS = DPMSQueryExtension(tqt_xdisplay(), &dummy, &dummy);
|
|
|
|
DCOPRef kpowersave("kpowersave", "KPowersaveIface");
|
|
DCOPReply managingDPMS = kpowersave.call("currentSchemeManagesDPMS()");
|
|
if (managingDPMS.isValid()) {
|
|
m_bKPowersave = managingDPMS;
|
|
m_bDPMS = !m_bKPowersave;
|
|
}
|
|
|
|
DCOPRef tdepowersave("tdepowersave", "tdepowersaveIface");
|
|
managingDPMS = tdepowersave.call("currentSchemeManagesDPMS()");
|
|
if (managingDPMS.isValid()) {
|
|
m_bTDEPowersave = managingDPMS;
|
|
m_bDPMS = !m_bTDEPowersave;
|
|
}
|
|
#endif
|
|
|
|
TQVBoxLayout *top = new TQVBoxLayout(this, 0, KDialog::spacingHint());
|
|
TQHBoxLayout *hbox = new TQHBoxLayout();
|
|
top->addLayout(hbox);
|
|
|
|
TQLabel *lbl;
|
|
if (m_bDPMS) {
|
|
TDEGlobal::locale()->insertCatalogue("kpowersave");
|
|
// ### these i18n strings need to be synced with kpowersave !!
|
|
m_pCBEnable= new TQCheckBox(i18n("&Enable display power management" ), this);
|
|
connect(m_pCBEnable, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChangeEnable(bool)));
|
|
hbox->addWidget(m_pCBEnable);
|
|
|
|
TQWhatsThis::add( m_pCBEnable, i18n("Check this option to enable the"
|
|
" power saving features of your display.") );
|
|
// ###
|
|
} else if(m_bKPowersave || m_bTDEPowersave) {
|
|
m_pCBEnable = new TQCheckBox(i18n("&Enable specific display power management"), this);
|
|
hbox->addWidget(m_pCBEnable);
|
|
m_bEnabled = false;
|
|
m_pCBEnable->setChecked(true);
|
|
m_pCBEnable->setEnabled(false);
|
|
} else {
|
|
lbl = new TQLabel(i18n("Your display does not support power saving."), this);
|
|
hbox->addWidget(lbl);
|
|
}
|
|
|
|
KURLLabel *logo = new KURLLabel(this);
|
|
logo->setURL("http://www.energystar.gov");
|
|
logo->setPixmap(TQPixmap(locate("data", "kcontrol/pics/energybig.png")));
|
|
logo->setTipText(i18n("Learn more about the Energy Star program"));
|
|
logo->setUseTips(true);
|
|
connect(logo, TQT_SIGNAL(leftClickedURL(const TQString&)), TQT_SLOT(openURL(const TQString &)));
|
|
|
|
hbox->addStretch();
|
|
hbox->addWidget(logo);
|
|
|
|
// Sliders
|
|
if (!m_bKPowersave && !m_bTDEPowersave) {
|
|
m_pStandbySlider = new KIntNumInput(m_Standby, this);
|
|
m_pStandbySlider->setLabel(i18n("&Standby after:"));
|
|
m_pStandbySlider->setRange(0, 120, 10);
|
|
m_pStandbySlider->setSuffix(i18n(" min"));
|
|
m_pStandbySlider->setSpecialValueText(i18n("Disabled"));
|
|
connect(m_pStandbySlider, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotChangeStandby(int)));
|
|
top->addWidget(m_pStandbySlider);
|
|
TQWhatsThis::add( m_pStandbySlider, i18n("Choose the period of inactivity"
|
|
" after which the display should enter \"standby\" mode. This is the"
|
|
" first level of power saving.") );
|
|
|
|
m_pSuspendSlider = new KIntNumInput(m_pStandbySlider, m_Suspend, this);
|
|
m_pSuspendSlider->setLabel(i18n("S&uspend after:"));
|
|
m_pSuspendSlider->setRange(0, 120, 10);
|
|
m_pSuspendSlider->setSuffix(i18n(" min"));
|
|
m_pSuspendSlider->setSpecialValueText(i18n("Disabled"));
|
|
connect(m_pSuspendSlider, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotChangeSuspend(int)));
|
|
top->addWidget(m_pSuspendSlider);
|
|
TQWhatsThis::add( m_pSuspendSlider, i18n("Choose the period of inactivity"
|
|
" after which the display should enter \"suspend\" mode. This is the"
|
|
" second level of power saving, but may not be different from the first"
|
|
" level for some displays.") );
|
|
|
|
m_pOffSlider = new KIntNumInput(m_pSuspendSlider, m_Off, this);
|
|
m_pOffSlider->setLabel(i18n("&Power off after:"));
|
|
m_pOffSlider->setRange(0, 120, 10);
|
|
m_pOffSlider->setSuffix(i18n(" min"));
|
|
m_pOffSlider->setSpecialValueText(i18n("Disabled"));
|
|
connect(m_pOffSlider, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotChangeOff(int)));
|
|
top->addWidget(m_pOffSlider);
|
|
TQWhatsThis::add( m_pOffSlider, i18n("Choose the period of inactivity"
|
|
" after which the display should be powered off. This is the"
|
|
" greatest level of power saving that can be achieved while the"
|
|
" display is still physically turned on.") );
|
|
|
|
} else {
|
|
m_pStandbySlider = 0;
|
|
m_pSuspendSlider = 0;
|
|
m_pOffSlider = 0;
|
|
if(m_bKPowersave) {
|
|
TQPushButton* btnKPowersave = new TQPushButton(this);
|
|
btnKPowersave->setText(i18n("Configure KPowersave..."));
|
|
connect(btnKPowersave, TQT_SIGNAL(clicked()), TQT_SLOT(slotLaunchKPowersave()));
|
|
top->addWidget(btnKPowersave);
|
|
}
|
|
if(m_bTDEPowersave) {
|
|
TQPushButton* btnTDEPowersave = new TQPushButton(this);
|
|
btnTDEPowersave->setText(i18n("Configure TDEPowersave..."));
|
|
connect(btnTDEPowersave, TQT_SIGNAL(clicked()), TQT_SLOT(slotLaunchTDEPowersave()));
|
|
top->addWidget(btnTDEPowersave);
|
|
}
|
|
}
|
|
|
|
top->addStretch();
|
|
|
|
if (m_bDPMS)
|
|
setButtons( TDECModule::Help | TDECModule::Default | TDECModule::Apply );
|
|
else
|
|
setButtons( TDECModule::Help );
|
|
|
|
m_pConfig = new TDEConfig("kcmdisplayrc", false /*readwrite*/, false /*no globals*/);
|
|
m_pConfig->setGroup("DisplayEnergy");
|
|
|
|
load();
|
|
}
|
|
|
|
|
|
KEnergy::~KEnergy()
|
|
{
|
|
delete m_pConfig;
|
|
}
|
|
|
|
|
|
void KEnergy::load()
|
|
{
|
|
load( false );
|
|
}
|
|
|
|
void KEnergy::load( bool useDefaults )
|
|
{
|
|
m_pConfig->setReadDefaults( useDefaults );
|
|
readSettings();
|
|
showSettings();
|
|
|
|
emit changed( useDefaults );
|
|
}
|
|
|
|
|
|
void KEnergy::save()
|
|
{
|
|
writeSettings();
|
|
applySettings(m_bEnabled, m_Standby, m_Suspend, m_Off);
|
|
|
|
emit changed(false);
|
|
}
|
|
|
|
|
|
void KEnergy::defaults()
|
|
{
|
|
load( true );
|
|
}
|
|
|
|
|
|
void KEnergy::readSettings()
|
|
{
|
|
if (m_bDPMS) {
|
|
m_bEnabled = m_pConfig->readBoolEntry("displayEnergySaving", false);
|
|
}
|
|
m_Standby = m_pConfig->readNumEntry("displayStandby", DFLT_STANDBY);
|
|
m_Suspend = m_pConfig->readNumEntry("displaySuspend", DFLT_SUSPEND);
|
|
m_Off = m_pConfig->readNumEntry("displayPowerOff", DFLT_OFF);
|
|
|
|
m_StandbyDesired = m_Standby;
|
|
m_SuspendDesired = m_Suspend;
|
|
m_OffDesired = m_Off;
|
|
|
|
m_bChanged = false;
|
|
}
|
|
|
|
|
|
void KEnergy::writeSettings()
|
|
{
|
|
if (!m_bChanged)
|
|
return;
|
|
|
|
m_pConfig->writeEntry( "displayEnergySaving", m_bEnabled);
|
|
m_pConfig->writeEntry("displayStandby", m_Standby);
|
|
m_pConfig->writeEntry("displaySuspend", m_Suspend);
|
|
m_pConfig->writeEntry("displayPowerOff", m_Off);
|
|
|
|
m_pConfig->sync();
|
|
m_bChanged = false;
|
|
}
|
|
|
|
|
|
void KEnergy::slotLaunchKPowersave()
|
|
{
|
|
DCOPRef r("kpowersave", "KPowersaveIface");
|
|
r.send("openConfigureDialog()");
|
|
}
|
|
|
|
void KEnergy::slotLaunchTDEPowersave()
|
|
{
|
|
DCOPRef r("tdepowersave", "tdepowersaveIface");
|
|
r.send("openConfigureDialog()");
|
|
}
|
|
|
|
void KEnergy::showSettings()
|
|
{
|
|
m_bMaintainSanity = false;
|
|
|
|
if (m_bDPMS) {
|
|
m_pCBEnable->setChecked(m_bEnabled);
|
|
}
|
|
|
|
if (!m_bKPowersave && !m_bTDEPowersave) {
|
|
m_pStandbySlider->setEnabled(m_bEnabled);
|
|
m_pStandbySlider->setValue(m_Standby);
|
|
m_pSuspendSlider->setEnabled(m_bEnabled);
|
|
m_pSuspendSlider->setValue(m_Suspend);
|
|
m_pOffSlider->setEnabled(m_bEnabled);
|
|
m_pOffSlider->setValue(m_Off);
|
|
}
|
|
|
|
m_bMaintainSanity = true;
|
|
}
|
|
|
|
|
|
extern "C" {
|
|
int dropError(Display *, XErrorEvent *);
|
|
typedef int (*XErrFunc) (Display *, XErrorEvent *);
|
|
}
|
|
|
|
int dropError(Display *, XErrorEvent *)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* static */
|
|
void KEnergy::applySettings(bool enable, int standby, int suspend, int off)
|
|
{
|
|
#ifdef HAVE_DPMS
|
|
XErrFunc defaultHandler;
|
|
defaultHandler = XSetErrorHandler(dropError);
|
|
|
|
Display *dpy = tqt_xdisplay();
|
|
|
|
int dummy;
|
|
bool hasDPMS = DPMSQueryExtension(dpy, &dummy, &dummy);
|
|
if (hasDPMS) {
|
|
if (enable) {
|
|
DPMSEnable(dpy);
|
|
DPMSSetTimeouts(dpy, 60*standby, 60*suspend, 60*off);
|
|
} else
|
|
DPMSDisable(dpy);
|
|
} else
|
|
tqWarning("Server has no DPMS extension");
|
|
|
|
XFlush(dpy);
|
|
XSetErrorHandler(defaultHandler);
|
|
#else
|
|
/* keep gcc silent */
|
|
if (enable | standby | suspend | off)
|
|
/* nothing */ ;
|
|
#endif
|
|
}
|
|
|
|
|
|
void KEnergy::slotChangeEnable(bool ena)
|
|
{
|
|
m_bEnabled = ena;
|
|
m_bChanged = true;
|
|
|
|
m_pStandbySlider->setEnabled(ena);
|
|
m_pSuspendSlider->setEnabled(ena);
|
|
m_pOffSlider->setEnabled(ena);
|
|
|
|
emit changed(true);
|
|
}
|
|
|
|
|
|
void KEnergy::slotChangeStandby(int value)
|
|
{
|
|
m_Standby = value;
|
|
|
|
if ( m_bMaintainSanity ) {
|
|
m_bMaintainSanity = false;
|
|
m_StandbyDesired = value;
|
|
if ((m_Suspend > 0 && m_Standby > m_Suspend) ||
|
|
(m_SuspendDesired && m_Standby >= m_SuspendDesired) )
|
|
m_pSuspendSlider->setValue(m_Standby);
|
|
if ((m_Off > 0 && m_Standby > m_Off) ||
|
|
(m_OffDesired && m_Standby >= m_OffDesired) )
|
|
m_pOffSlider->setValue(m_Standby);
|
|
m_bMaintainSanity = true;
|
|
}
|
|
|
|
m_bChanged = true;
|
|
emit changed(true);
|
|
}
|
|
|
|
|
|
void KEnergy::slotChangeSuspend(int value)
|
|
{
|
|
m_Suspend = value;
|
|
|
|
if ( m_bMaintainSanity ) {
|
|
m_bMaintainSanity = false;
|
|
m_SuspendDesired = value;
|
|
if (m_Suspend == 0 && m_StandbyDesired > 0)
|
|
m_pStandbySlider->setValue( m_StandbyDesired );
|
|
else if (m_Suspend < m_Standby || m_Suspend <= m_StandbyDesired )
|
|
m_pStandbySlider->setValue(m_Suspend);
|
|
if ((m_Off > 0 && m_Suspend > m_Off) ||
|
|
(m_OffDesired && m_Suspend >= m_OffDesired) )
|
|
m_pOffSlider->setValue(m_Suspend);
|
|
m_bMaintainSanity = true;
|
|
}
|
|
|
|
m_bChanged = true;
|
|
emit changed(true);
|
|
}
|
|
|
|
|
|
void KEnergy::slotChangeOff(int value)
|
|
{
|
|
m_Off = value;
|
|
|
|
if ( m_bMaintainSanity ) {
|
|
m_bMaintainSanity = false;
|
|
m_OffDesired = value;
|
|
if (m_Off == 0 && m_StandbyDesired > 0)
|
|
m_pStandbySlider->setValue( m_StandbyDesired );
|
|
else if (m_Off < m_Standby || m_Off <= m_StandbyDesired )
|
|
m_pStandbySlider->setValue(m_Off);
|
|
if (m_Off == 0 && m_SuspendDesired > 0)
|
|
m_pSuspendSlider->setValue( m_SuspendDesired );
|
|
else if (m_Off < m_Suspend || m_Off <= m_SuspendDesired )
|
|
m_pSuspendSlider->setValue(m_Off);
|
|
m_bMaintainSanity = true;
|
|
}
|
|
|
|
m_bChanged = true;
|
|
emit changed(true);
|
|
}
|
|
|
|
void KEnergy::openURL(const TQString &URL)
|
|
{
|
|
new KRun(KURL( URL ));
|
|
}
|
|
|
|
#include "energy.moc"
|