Add (and install) svg for the new krunner interface.
[kdebase/uwolfer.git] / workspace / krunner / saverengine.cpp
blob6f6e94e44870575d6e53f7fc616355ef0586d5c9
1 //===========================================================================
2 //
3 // This file is part of the KDE project
4 //
5 // Copyright 1999 Martin R. Jones <mjones@kde.org>
6 //
9 #include "saverengine.h"
10 #include "kscreensaversettings.h"
11 #include "screensaveradaptor.h"
12 #include "kscreensaveradaptor.h"
14 #include <kstandarddirs.h>
15 #include <kapplication.h>
16 #include <kservicegroup.h>
17 #include <krandom.h>
18 #include <kdebug.h>
19 #include <klocale.h>
20 #include <QFile>
21 #include <QX11Info>
22 #include <QDBusConnection>
23 #include <assert.h>
24 #include <stdlib.h>
25 #include <time.h>
27 #include "xautolock_c.h"
28 extern xautolock_corner_t xautolock_corners[ 4 ];
30 //===========================================================================
32 // Screen saver engine. Doesn't handle the actual screensaver window,
33 // starting screensaver hacks, or password entry. That's done by
34 // a newly started process.
36 SaverEngine::SaverEngine()
37 : QWidget()
39 (void) new ScreenSaverAdaptor( this );
40 QDBusConnection::sessionBus().registerService( "org.freedesktop.ScreenSaver" ) ;
41 (void) new KScreenSaverAdaptor( this );
42 QDBusConnection::sessionBus().registerService( "org.kde.screensaver" ) ;
43 QDBusConnection::sessionBus().registerObject( "/ScreenSaver", this );
45 // Save X screensaver parameters
46 XGetScreenSaver(QX11Info::display(), &mXTimeout, &mXInterval,
47 &mXBlanking, &mXExposures);
48 // ... and disable it
49 XSetScreenSaver(QX11Info::display(), 0, mXInterval, mXBlanking, mXExposures);
51 mState = Waiting;
52 mXAutoLock = 0;
54 m_nr_throttled = 0;
55 m_nr_inhibited = 0;
56 m_actived_time = -1;
58 connect(&mLockProcess, SIGNAL(processExited(K3Process *)),
59 SLOT(lockProcessExited()));
61 connect(QDBusConnection::sessionBus().interface(),
62 SIGNAL(serviceOwnerChanged(QString,QString,QString)),
63 SLOT(serviceOwnerChanged(QString,QString,QString)));
65 // I make it a really random number to avoid
66 // some assumptions in clients, but just increase
67 // while gnome-ss creates a random number every time
68 m_next_cookie = KRandom::random() % 20000;
69 configure();
72 //---------------------------------------------------------------------------
74 // Destructor - usual cleanups.
76 SaverEngine::~SaverEngine()
78 mLockProcess.detach(); // don't kill it if we crash
79 delete mXAutoLock;
81 // Restore X screensaver parameters
82 XSetScreenSaver(QX11Info::display(), mXTimeout, mXInterval, mXBlanking,
83 mXExposures);
86 //---------------------------------------------------------------------------
88 void SaverEngine::Lock()
90 bool ok = true;
91 if (mState == Waiting)
93 ok = startLockProcess( ForceLock );
94 // It takes a while for krunner_lock to start and lock the screen.
95 // Therefore delay the DBus call until it tells krunner that the locking is in effect.
96 // This is done only for --forcelock .
97 if( ok && calledFromDBus())
99 mLockTransactions.append(message().createReply());
100 setDelayedReply(true);
103 else
105 // XXX race condition here
106 mLockProcess.kill( SIGHUP );
110 void SaverEngine::processLockTransactions()
112 QList<QDBusMessage>::ConstIterator it = mLockTransactions.constBegin(),
113 end = mLockTransactions.constEnd();
114 for ( ; it != end; ++it )
116 QDBusConnection::sessionBus().send(*it);
118 mLockTransactions.clear();
121 void SaverEngine::saverLockReady()
123 if( mState != Preparing )
125 kDebug() << "Got unexpected saverLockReady()";
126 return;
128 kDebug() << "Saver Lock Ready";
129 processLockTransactions();
130 if (m_nr_throttled)
131 mLockProcess.suspend();
134 void SaverEngine::SimulateUserActivity()
136 if ( mXAutoLock && mState == Waiting )
138 mXAutoLock->resetTrigger();
142 //---------------------------------------------------------------------------
143 bool SaverEngine::save()
145 if (mState == Waiting)
147 return startLockProcess( DefaultLock );
149 return false;
152 //---------------------------------------------------------------------------
153 bool SaverEngine::quit()
155 if (mState == Saving || mState == Preparing)
157 stopLockProcess();
158 return true;
160 return false;
163 //---------------------------------------------------------------------------
164 bool SaverEngine::isEnabled()
166 return mXAutoLock != 0;
169 //---------------------------------------------------------------------------
170 bool SaverEngine::enable( bool e, bool force )
172 if ( !force && e == isEnabled() )
173 return true;
175 // If we aren't in a suitable state, we will not reconfigure.
176 if (mState != Waiting)
177 return false;
179 if (e)
181 if (!mXAutoLock)
183 mXAutoLock = new XAutoLock();
184 connect(mXAutoLock, SIGNAL(timeout()), SLOT(idleTimeout()));
187 int timeout = KScreenSaverSettings::timeout();
188 mXAutoLock->setTimeout(timeout);
189 mXAutoLock->setDPMS(true);
190 #ifdef NOT_FREAKIN_UGLY
191 mXAutoLock->changeCornerLockStatus( mLockCornerTopLeft, mLockCornerTopRight, mLockCornerBottomLeft, mLockCornerBottomRight);
192 #else
193 xautolock_corners[0] = applyManualSettings(KScreenSaverSettings::actionTopLeft());
194 xautolock_corners[1] = applyManualSettings(KScreenSaverSettings::actionTopRight());
195 xautolock_corners[2] = applyManualSettings(KScreenSaverSettings::actionBottomLeft());
196 xautolock_corners[3] = applyManualSettings(KScreenSaverSettings::actionBottomRight());
197 #endif
199 mXAutoLock->start();
200 kDebug() << "Saver Engine started, timeout: " << timeout;
202 else
204 delete mXAutoLock;
205 mXAutoLock = 0;
206 kDebug() << "Saver Engine disabled";
209 return true;
212 //---------------------------------------------------------------------------
213 bool SaverEngine::isBlanked()
215 return (mState != Waiting);
218 //---------------------------------------------------------------------------
220 // Read and apply configuration.
222 void SaverEngine::configure()
224 // create a new config obj to ensure we read the latest options
225 KScreenSaverSettings::self()->readConfig();
227 enable( KScreenSaverSettings::screenSaverEnabled(), true );
230 //---------------------------------------------------------------------------
232 // Start the screen saver.
234 bool SaverEngine::startLockProcess( LockType lock_type )
236 Q_ASSERT(mState == Waiting);
238 kDebug() << "SaverEngine: starting saver";
240 QString path = KStandardDirs::findExe( "krunner_lock" );
241 if( path.isEmpty())
243 kDebug() << "Can't find krunner_lock!";
244 return false;
246 mLockProcess.clearArguments();
247 mLockProcess << path;
248 switch( lock_type )
250 case ForceLock:
251 mLockProcess << QString( "--forcelock" );
252 break;
253 case DontLock:
254 mLockProcess << QString( "--dontlock" );
255 break;
256 default:
257 break;
260 m_actived_time = time( 0 );
261 if (mLockProcess.start() == false )
263 kDebug() << "Failed to start krunner_lock!";
264 m_actived_time = -1;
265 return false;
268 if (mXAutoLock)
270 mXAutoLock->stop();
273 emit ActiveChanged(true); // DBus signal
274 mState = Preparing;
276 return true;
279 //---------------------------------------------------------------------------
281 // Stop the screen saver.
283 void SaverEngine::stopLockProcess()
285 Q_ASSERT(mState != Waiting);
286 kDebug() << "SaverEngine: stopping lock process";
288 mLockProcess.kill();
291 void SaverEngine::lockProcessExited()
293 Q_ASSERT(mState != Waiting);
294 kDebug() << "SaverEngine: lock process exited";
296 if (mXAutoLock)
298 mXAutoLock->start();
301 processLockTransactions();
302 emit ActiveChanged(false); // DBus signal
303 m_actived_time = -1;
304 mState = Waiting;
307 //---------------------------------------------------------------------------
309 // XAutoLock has detected the required idle time.
311 void SaverEngine::idleTimeout()
313 startLockProcess( DefaultLock );
316 xautolock_corner_t SaverEngine::applyManualSettings(int action)
318 if (action == 0)
320 kDebug() << "no lock";
321 return ca_nothing;
323 else if (action == 1)
325 kDebug() << "lock screen";
326 return ca_forceLock;
328 else if (action == 2)
330 kDebug() << "prevent lock";
331 return ca_dontLock;
333 else
335 kDebug() << "no lock nothing";
336 return ca_nothing;
340 uint SaverEngine::GetSessionIdleTime()
342 return mXAutoLock->idleTime();
345 uint SaverEngine::GetActiveTime()
347 if ( m_actived_time == -1 )
348 return 0;
349 return time( 0 ) - m_actived_time;
352 bool SaverEngine::GetActive()
354 return ( mState != Waiting );
357 bool SaverEngine::SetActive(bool state)
359 if ( state )
360 return save();
361 else
362 return quit();
365 uint SaverEngine::Inhibit(const QString &/*application_name*/, const QString &/*reason*/)
367 ScreenSaverRequest sr;
368 // sr.appname = application_name;
369 // sr.reasongiven = reason;
370 sr.cookie = m_next_cookie++;
371 sr.dbusid = message().service();
372 sr.type = ScreenSaverRequest::Inhibit;
373 m_requests.append( sr );
374 m_nr_inhibited++;
375 enable( false );
376 return sr.cookie;
379 void SaverEngine::UnInhibit(uint cookie)
381 QMutableListIterator<ScreenSaverRequest> it( m_requests );
382 while ( it.hasNext() )
384 if ( it.next().cookie == cookie ) {
385 it.remove();
386 if ( !--m_nr_inhibited )
387 enable( true );
392 uint SaverEngine::Throttle(const QString &/*application_name*/, const QString &/*reason*/)
394 ScreenSaverRequest sr;
395 // sr.appname = application_name;
396 // sr.reasongiven = reason;
397 sr.cookie = m_next_cookie++;
398 sr.type = ScreenSaverRequest::Throttle;
399 sr.dbusid = message().service();
400 m_requests.append( sr );
401 m_nr_throttled++;
402 if (mLockProcess.isRunning())
403 mLockProcess.suspend();
404 return sr.cookie;
407 void SaverEngine::UnThrottle(uint cookie)
409 QMutableListIterator<ScreenSaverRequest> it( m_requests );
410 while ( it.hasNext() )
412 if ( it.next().cookie == cookie ) {
413 it.remove();
414 if ( !--m_nr_throttled )
415 if (mLockProcess.isRunning())
416 mLockProcess.resume();
421 void SaverEngine::serviceOwnerChanged(const QString& name, const QString &, const QString &newOwner)
423 if ( !newOwner.isEmpty() ) // looking for deaths
424 return;
426 QListIterator<ScreenSaverRequest> it( m_requests );
427 while ( it.hasNext() )
429 const ScreenSaverRequest &r = it.next();
430 if ( r.dbusid == name )
432 if ( r.type == ScreenSaverRequest::Throttle )
433 UnThrottle( r.cookie );
434 else
435 UnInhibit( r.cookie );
440 #include "saverengine.moc"