not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / kcontrol / energy / energy.cpp
blob5c70b6b0ff766233b875dfa2148e386117905caa
1 /* vi: ts=8 sts=4 sw=4
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
23 #endif
25 #include <QCheckBox>
26 #include <QLabel>
27 #include <QLayout>
28 #include <kcomponentdata.h>
30 //Added by qt3to4:
31 #include <QPixmap>
32 #include <QVBoxLayout>
33 #include <QHBoxLayout>
35 #include <kconfig.h>
36 #include <kcursor.h>
37 #include <kdialog.h>
38 #include <kiconloader.h>
39 #include <klocale.h>
40 #include <knuminput.h>
41 #include <krun.h>
42 #include <kstandarddirs.h>
43 #include <kurllabel.h>
44 #include <kgenericfactory.h>
46 #include <kscreensaver_interface.h>
48 #include <X11/X.h>
49 #include <X11/Xlib.h>
50 #include <X11/Xatom.h>
51 #include <X11/Xutil.h>
52 #include <X11/Xos.h>
54 #include "energy.h"
55 #include <QX11Info>
58 #ifdef HAVE_DPMS
59 #include <X11/Xmd.h>
60 extern "C" {
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 * );
68 #endif
70 #ifndef HAVE_DPMSINFO_PROTO
71 Status DPMSInfo ( Display *, CARD16 *, BOOL * );
72 #endif
75 #if defined(XIMStringConversionRetrival) || defined (__sun) || defined(__hpux)
76 extern "C" {
77 #endif
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)
85 #endif
86 #endif
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"))
102 extern "C" {
104 KDE_EXPORT void kcminit_energy() {
105 #ifdef HAVE_DPMS
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;
115 bool enabled;
116 CARD16 standby;
117 CARD16 suspend;
118 CARD16 off;
119 int dummy;
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));
129 } else {
130 /* provide our defauts */
131 enabled = true;
132 standby = DFLT_STANDBY;
133 suspend = DFLT_SUSPEND;
134 off = DFLT_OFF;
136 delete _cfg;
137 KEnergy::applySettings(enabled, standby, suspend, off);
138 #endif
142 /**** KEnergy ****/
144 KEnergy::KEnergy(QWidget *parent, const QVariantList &args)
145 : KCModule(KEnergyFactory::componentData(), parent, args)
147 m_bChanged = false;
148 m_bEnabled = false;
149 m_Standby = DFLT_STANDBY;
150 m_Suspend = DFLT_SUSPEND;
151 m_Off = DFLT_OFF;
152 m_bDPMS = false;
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>"));
164 #ifdef HAVE_DPMS
165 int dummy;
166 m_bDPMS = DPMSQueryExtension(QX11Info::display(), &dummy, &dummy);
167 #endif
169 QVBoxLayout *top = new QVBoxLayout(this);
170 top->setMargin(0);
171 top->setSpacing(KDialog::spacingHint());
172 QHBoxLayout *hbox = new QHBoxLayout();
173 top->addLayout(hbox);
175 QLabel *lbl;
176 if (m_bDPMS) {
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.") );
182 } else {
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 &)));
194 hbox->addStretch();
195 hbox->addWidget(logo);
197 // Sliders
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.") );
233 top->addStretch();
235 if (m_bDPMS)
236 setButtons( KCModule::Help | KCModule::Default | KCModule::Apply );
237 else
238 setButtons( KCModule::Help );
240 m_pConfig = new KConfig("kcmdisplayrc", KConfig::NoGlobals);
244 KEnergy::~KEnergy()
246 delete m_pConfig;
251 void KEnergy::load()
253 readSettings();
254 showSettings();
256 emit changed(false);
260 void KEnergy::save()
262 writeSettings();
263 applySettings(m_bEnabled, m_Standby, m_Suspend, m_Off);
265 emit changed(false);
269 void KEnergy::defaults()
271 m_bEnabled = false;
272 m_Standby = DFLT_STANDBY;
273 m_Suspend = DFLT_SUSPEND;
274 m_Off = DFLT_OFF;
276 m_StandbyDesired = m_Standby;
277 m_SuspendDesired = m_Suspend;
278 m_OffDesired = m_Off;
280 showSettings();
281 emit changed(true);
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;
297 m_bChanged = false;
301 void KEnergy::writeSettings()
303 if (!m_bChanged)
304 return;
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);
312 group.sync();
313 m_bChanged = false;
317 void KEnergy::showSettings()
319 m_bMaintainSanity = false;
321 if (m_bDPMS)
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;
335 extern "C" {
336 int dropError(Display *, XErrorEvent *);
337 typedef int (*XErrFunc) (Display *, XErrorEvent *);
340 int dropError(Display *, XErrorEvent *)
342 return 0;
345 /* static */
346 void KEnergy::applySettings(bool enable, int standby, int suspend, int off)
348 #ifdef HAVE_DPMS
349 XErrFunc defaultHandler;
350 defaultHandler = XSetErrorHandler(dropError);
352 Display *dpy = QX11Info::display();
354 int dummy;
355 bool hasDPMS = DPMSQueryExtension(dpy, &dummy, &dummy);
356 if (hasDPMS) {
357 if (enable) {
358 DPMSEnable(dpy);
359 DPMSSetTimeouts(dpy, 60*standby, 60*suspend, 60*off);
360 } else
361 DPMSDisable(dpy);
362 } else
363 qWarning("Server has no DPMS extension");
365 XFlush(dpy);
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();
371 #else
372 /* keep gcc silent */
373 if (enable | standby | suspend | off)
374 /* nothing */ ;
375 #endif
379 void KEnergy::slotChangeEnable(bool ena)
381 m_bEnabled = ena;
382 m_bChanged = true;
384 m_pStandbySlider->setEnabled(ena);
385 m_pSuspendSlider->setEnabled(ena);
386 m_pOffSlider->setEnabled(ena);
388 emit changed(true);
392 void KEnergy::slotChangeStandby(int value)
394 m_Standby = 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;
408 m_bChanged = true;
409 emit changed(true);
413 void KEnergy::slotChangeSuspend(int value)
415 m_Suspend = 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;
430 m_bChanged = true;
431 emit changed(true);
435 void KEnergy::slotChangeOff(int value)
437 m_Off = 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;
453 m_bChanged = true;
454 emit changed(true);
457 void KEnergy::openUrl(const QString &URL)
459 new KRun(KUrl( URL ),this);
462 #include "energy.moc"