5 * This file is part of the KDE project, module kcontrol.
6 * Copyright (C) 1999 Geert Jansen <g.t.jansen@stud.tue.nl>
8 * You can Freely distribute this program under the GNU General Public
9 * License. See the file "COPYING" for the exact licensing terms.
11 * Based on kcontrol1 energy.cpp, Copyright (c) 1999 Tom Vijlbrief
16 * KDE Energy setup module.
19 #include <config-workspace.h>
21 #if !defined(QT_CLEAN_NAMESPACE)
22 #define QT_CLEAN_NAMESPACE
28 #include <kcomponentdata.h>
32 #include <QVBoxLayout>
33 #include <QHBoxLayout>
38 #include <kiconloader.h>
40 #include <knuminput.h>
42 #include <kstandarddirs.h>
43 #include <kurllabel.h>
44 #include <kgenericfactory.h>
46 #include <kscreensaver_interface.h>
50 #include <X11/Xatom.h>
51 #include <X11/Xutil.h>
61 #include <X11/extensions/dpms.h>
62 Status
DPMSInfo ( Display
*, CARD16
*, BOOL
* );
63 Bool
DPMSCapable( Display
* );
64 int __kde_do_not_unload
= 1;
66 #ifndef HAVE_DPMSCAPABLE_PROTO
67 Bool
DPMSCapable ( Display
* );
70 #ifndef HAVE_DPMSINFO_PROTO
71 Status
DPMSInfo ( Display
*, CARD16
*, BOOL
* );
75 #if defined(XIMStringConversionRetrival) || defined (__sun) || defined(__hpux)
78 Bool
DPMSQueryExtension(Display
*, int *, int *);
79 Status
DPMSEnable(Display
*);
80 Status
DPMSDisable(Display
*);
81 Bool
DPMSGetTimeouts(Display
*, CARD16
*, CARD16
*, CARD16
*);
82 Bool
DPMSSetTimeouts(Display
*, CARD16
, CARD16
, CARD16
);
83 #if defined(XIMStringConversionRetrival) || defined (__sun) || defined(__hpux)
88 static const int DFLT_STANDBY
= 0;
89 static const int DFLT_SUSPEND
= 30;
90 static const int DFLT_OFF
= 60;
93 /**** DLL Interface ****/
96 K_PLUGIN_FACTORY(KEnergyFactory
,
97 registerPlugin
<KEnergy
>();
99 K_EXPORT_PLUGIN(KEnergyFactory("kcmenergy"))
104 KDE_EXPORT
void kcminit_energy() {
106 KConfig
*_cfg
= new KConfig( "kcmdisplayrc", KConfig::NoGlobals
);
107 KConfigGroup
cfg(_cfg
, "DisplayEnergy");
109 Display
*dpy
= QX11Info::display();
110 CARD16 pre_configured_status
;
111 BOOL pre_configured_enabled
;
112 CARD16 pre_configured_standby
;
113 CARD16 pre_configured_suspend
;
114 CARD16 pre_configured_off
;
120 /* query the running X server if DPMS is supported */
121 if (DPMSQueryExtension(dpy
, &dummy
, &dummy
) && DPMSCapable(dpy
)) {
122 DPMSGetTimeouts(dpy
, &pre_configured_standby
, &pre_configured_suspend
, &pre_configured_off
);
123 DPMSInfo(dpy
, &pre_configured_status
, &pre_configured_enabled
);
124 /* let the user override the settings */
125 enabled
= cfg
.readEntry("displayEnergySaving", bool(pre_configured_enabled
));
126 standby
= cfg
.readEntry("displayStandby", int(pre_configured_standby
/60));
127 suspend
= cfg
.readEntry("displaySuspend", int(pre_configured_suspend
/60));
128 off
= cfg
.readEntry("displayPowerOff", int(pre_configured_off
/60));
130 /* provide our defauts */
132 standby
= DFLT_STANDBY
;
133 suspend
= DFLT_SUSPEND
;
137 KEnergy::applySettings(enabled
, standby
, suspend
, off
);
144 KEnergy::KEnergy(QWidget
*parent
, const QVariantList
&args
)
145 : KCModule(KEnergyFactory::componentData(), parent
, args
)
149 m_Standby
= DFLT_STANDBY
;
150 m_Suspend
= DFLT_SUSPEND
;
153 m_bMaintainSanity
= true;
155 setQuickHelp( i18n("<h1>Display Power Control</h1> <p>If your display supports"
156 " power saving features, you can configure them using this module.</p>"
157 " <p>There are three levels of power saving: standby, suspend, and off."
158 " The greater the level of power saving, the longer it takes for the"
159 " display to return to an active state.</p>"
160 " <p>To wake up the display from a power saving mode, you can make a small"
161 " movement with the mouse, or press a key that is not likely to cause"
162 " any unintentional side-effects, for example, the \"Shift\" key.</p>"));
166 m_bDPMS
= DPMSQueryExtension(QX11Info::display(), &dummy
, &dummy
);
169 QVBoxLayout
*top
= new QVBoxLayout(this);
171 top
->setSpacing(KDialog::spacingHint());
172 QHBoxLayout
*hbox
= new QHBoxLayout();
173 top
->addLayout(hbox
);
177 m_pCBEnable
= new QCheckBox(i18n("&Enable display power management" ), this);
178 connect(m_pCBEnable
, SIGNAL(toggled(bool)), SLOT(slotChangeEnable(bool)));
179 hbox
->addWidget(m_pCBEnable
);
180 m_pCBEnable
->setWhatsThis( i18n("Check this option to enable the"
181 " power saving features of your display.") );
183 lbl
= new QLabel(i18n("Your display does not support power saving."), this);
184 hbox
->addWidget(lbl
);
187 KUrlLabel
*logo
= new KUrlLabel(this);
188 logo
->setUrl("http://www.energystar.gov");
189 logo
->setPixmap(QPixmap(KStandardDirs::locate("data", "kcontrol/pics/energybig.png")));
190 logo
->setTipText(i18n("Learn more about the Energy Star program"));
191 logo
->setUseTips(true);
192 connect(logo
, SIGNAL(leftClickedUrl(const QString
&)), SLOT(openUrl(const QString
&)));
195 hbox
->addWidget(logo
);
198 m_pStandbySlider
= new KIntNumInput(m_Standby
, this);
199 m_pStandbySlider
->setLabel(i18n("&Standby after:"));
200 m_pStandbySlider
->setRange(0, 120, 1);
201 m_pStandbySlider
->setSuffix(i18n(" min"));
202 m_pStandbySlider
->setSpecialValueText(i18nc("Disables display entering standby mode after x min", "Disabled"));
203 connect(m_pStandbySlider
, SIGNAL(valueChanged(int)), SLOT(slotChangeStandby(int)));
204 top
->addWidget(m_pStandbySlider
);
205 m_pStandbySlider
->setWhatsThis( i18n("Choose the period of inactivity"
206 " after which the display should enter \"standby\" mode. This is the"
207 " first level of power saving.") );
209 m_pSuspendSlider
= new KIntNumInput(m_pStandbySlider
, m_Suspend
, this);
210 m_pSuspendSlider
->setLabel(i18n("S&uspend after:"));
211 m_pSuspendSlider
->setRange(0, 120, 1);
212 m_pSuspendSlider
->setSuffix(i18n(" min"));
213 m_pSuspendSlider
->setSpecialValueText(i18nc("Disables display entering suspend mode after x min", "Disabled"));
214 connect(m_pSuspendSlider
, SIGNAL(valueChanged(int)), SLOT(slotChangeSuspend(int)));
215 top
->addWidget(m_pSuspendSlider
);
216 m_pSuspendSlider
->setWhatsThis( i18n("Choose the period of inactivity"
217 " after which the display should enter \"suspend\" mode. This is the"
218 " second level of power saving, but may not be different from the first"
219 " level for some displays.") );
221 m_pOffSlider
= new KIntNumInput(m_pSuspendSlider
, m_Off
, this);
222 m_pOffSlider
->setLabel(i18n("&Power off after:"));
223 m_pOffSlider
->setRange(0, 120, 1);
224 m_pOffSlider
->setSuffix(i18n(" min"));
225 m_pOffSlider
->setSpecialValueText(i18nc("Disables display being turned off after x min", "Disabled"));
226 connect(m_pOffSlider
, SIGNAL(valueChanged(int)), SLOT(slotChangeOff(int)));
227 top
->addWidget(m_pOffSlider
);
228 m_pOffSlider
->setWhatsThis( i18n("Choose the period of inactivity"
229 " after which the display should be powered off. This is the"
230 " greatest level of power saving that can be achieved while the"
231 " display is still physically turned on.") );
236 setButtons( KCModule::Help
| KCModule::Default
| KCModule::Apply
);
238 setButtons( KCModule::Help
);
240 m_pConfig
= new KConfig("kcmdisplayrc", KConfig::NoGlobals
);
263 applySettings(m_bEnabled
, m_Standby
, m_Suspend
, m_Off
);
269 void KEnergy::defaults()
272 m_Standby
= DFLT_STANDBY
;
273 m_Suspend
= DFLT_SUSPEND
;
276 m_StandbyDesired
= m_Standby
;
277 m_SuspendDesired
= m_Suspend
;
278 m_OffDesired
= m_Off
;
285 void KEnergy::readSettings()
287 KConfigGroup group
= m_pConfig
->group("DisplayEnergy");
288 m_bEnabled
= group
.readEntry("displayEnergySaving", false);
289 m_Standby
= group
.readEntry("displayStandby", DFLT_STANDBY
);
290 m_Suspend
= group
.readEntry("displaySuspend", DFLT_SUSPEND
);
291 m_Off
= group
.readEntry("displayPowerOff", DFLT_OFF
);
293 m_StandbyDesired
= m_Standby
;
294 m_SuspendDesired
= m_Suspend
;
295 m_OffDesired
= m_Off
;
301 void KEnergy::writeSettings()
306 KConfigGroup group
= m_pConfig
->group("DisplayEnergy");
307 group
.writeEntry( "displayEnergySaving", m_bEnabled
);
308 group
.writeEntry("displayStandby", m_Standby
);
309 group
.writeEntry("displaySuspend", m_Suspend
);
310 group
.writeEntry("displayPowerOff", m_Off
);
317 void KEnergy::showSettings()
319 m_bMaintainSanity
= false;
322 m_pCBEnable
->setChecked(m_bEnabled
);
324 m_pStandbySlider
->setEnabled(m_bEnabled
);
325 m_pStandbySlider
->setValue(m_Standby
);
326 m_pSuspendSlider
->setEnabled(m_bEnabled
);
327 m_pSuspendSlider
->setValue(m_Suspend
);
328 m_pOffSlider
->setEnabled(m_bEnabled
);
329 m_pOffSlider
->setValue(m_Off
);
331 m_bMaintainSanity
= true;
336 int dropError(Display
*, XErrorEvent
*);
337 typedef int (*XErrFunc
) (Display
*, XErrorEvent
*);
340 int dropError(Display
*, XErrorEvent
*)
346 void KEnergy::applySettings(bool enable
, int standby
, int suspend
, int off
)
349 XErrFunc defaultHandler
;
350 defaultHandler
= XSetErrorHandler(dropError
);
352 Display
*dpy
= QX11Info::display();
355 bool hasDPMS
= DPMSQueryExtension(dpy
, &dummy
, &dummy
);
359 DPMSSetTimeouts(dpy
, 60*standby
, 60*suspend
, 60*off
);
363 qWarning("Server has no DPMS extension");
366 XSetErrorHandler(defaultHandler
);
368 // The screen saver depends on the DPMS settings
369 org::kde::screensaver
kscreensaver("org.freedesktop.ScreenSaver", "/ScreenSaver", QDBusConnection::sessionBus());
370 kscreensaver
.configure();
372 /* keep gcc silent */
373 if (enable
| standby
| suspend
| off
)
379 void KEnergy::slotChangeEnable(bool ena
)
384 m_pStandbySlider
->setEnabled(ena
);
385 m_pSuspendSlider
->setEnabled(ena
);
386 m_pOffSlider
->setEnabled(ena
);
392 void KEnergy::slotChangeStandby(int value
)
396 if ( m_bMaintainSanity
) {
397 m_bMaintainSanity
= false;
398 m_StandbyDesired
= value
;
399 if ((m_Suspend
> 0 && m_Standby
> m_Suspend
) ||
400 (m_SuspendDesired
&& m_Standby
>= m_SuspendDesired
) )
401 m_pSuspendSlider
->setValue(m_Standby
);
402 if ((m_Off
> 0 && m_Standby
> m_Off
) ||
403 (m_OffDesired
&& m_Standby
>= m_OffDesired
) )
404 m_pOffSlider
->setValue(m_Standby
);
405 m_bMaintainSanity
= true;
413 void KEnergy::slotChangeSuspend(int value
)
417 if ( m_bMaintainSanity
) {
418 m_bMaintainSanity
= false;
419 m_SuspendDesired
= value
;
420 if (m_Suspend
== 0 && m_StandbyDesired
> 0)
421 m_pStandbySlider
->setValue( m_StandbyDesired
);
422 else if (m_Suspend
< m_Standby
|| m_Suspend
<= m_StandbyDesired
)
423 m_pStandbySlider
->setValue(m_Suspend
);
424 if ((m_Off
> 0 && m_Suspend
> m_Off
) ||
425 (m_OffDesired
&& m_Suspend
>= m_OffDesired
) )
426 m_pOffSlider
->setValue(m_Suspend
);
427 m_bMaintainSanity
= true;
435 void KEnergy::slotChangeOff(int value
)
439 if ( m_bMaintainSanity
) {
440 m_bMaintainSanity
= false;
441 m_OffDesired
= value
;
442 if (m_Off
== 0 && m_StandbyDesired
> 0)
443 m_pStandbySlider
->setValue( m_StandbyDesired
);
444 else if (m_Off
< m_Standby
|| m_Off
<= m_StandbyDesired
)
445 m_pStandbySlider
->setValue(m_Off
);
446 if (m_Off
== 0 && m_SuspendDesired
> 0)
447 m_pSuspendSlider
->setValue( m_SuspendDesired
);
448 else if (m_Off
< m_Suspend
|| m_Off
<= m_SuspendDesired
)
449 m_pSuspendSlider
->setValue(m_Off
);
450 m_bMaintainSanity
= true;
457 void KEnergy::openUrl(const QString
&URL
)
459 new KRun(KUrl( URL
),this);
462 #include "energy.moc"