1 //===========================================================================
3 // This file is part of the KDE project
5 // Copyright 1999 Martin R. Jones <mjones@kde.org>
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>
22 #include <QDBusConnection>
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()
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
);
49 XSetScreenSaver(QX11Info::display(), 0, mXInterval
, mXBlanking
, mXExposures
);
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;
72 //---------------------------------------------------------------------------
74 // Destructor - usual cleanups.
76 SaverEngine::~SaverEngine()
78 mLockProcess
.detach(); // don't kill it if we crash
81 // Restore X screensaver parameters
82 XSetScreenSaver(QX11Info::display(), mXTimeout
, mXInterval
, mXBlanking
,
86 //---------------------------------------------------------------------------
88 void SaverEngine::Lock()
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);
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()";
128 kDebug() << "Saver Lock Ready";
129 processLockTransactions();
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
);
152 //---------------------------------------------------------------------------
153 bool SaverEngine::quit()
155 if (mState
== Saving
|| mState
== Preparing
)
163 //---------------------------------------------------------------------------
164 bool SaverEngine::isEnabled()
166 return mXAutoLock
!= 0;
169 //---------------------------------------------------------------------------
170 bool SaverEngine::enable( bool e
, bool force
)
172 if ( !force
&& e
== isEnabled() )
175 // If we aren't in a suitable state, we will not reconfigure.
176 if (mState
!= Waiting
)
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
);
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());
200 kDebug() << "Saver Engine started, timeout: " << timeout
;
206 kDebug() << "Saver Engine disabled";
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" );
243 kDebug() << "Can't find krunner_lock!";
246 mLockProcess
.clearArguments();
247 mLockProcess
<< path
;
251 mLockProcess
<< QString( "--forcelock" );
254 mLockProcess
<< QString( "--dontlock" );
260 m_actived_time
= time( 0 );
261 if (mLockProcess
.start() == false )
263 kDebug() << "Failed to start krunner_lock!";
273 emit
ActiveChanged(true); // DBus signal
279 //---------------------------------------------------------------------------
281 // Stop the screen saver.
283 void SaverEngine::stopLockProcess()
285 Q_ASSERT(mState
!= Waiting
);
286 kDebug() << "SaverEngine: stopping lock process";
291 void SaverEngine::lockProcessExited()
293 Q_ASSERT(mState
!= Waiting
);
294 kDebug() << "SaverEngine: lock process exited";
301 processLockTransactions();
302 emit
ActiveChanged(false); // DBus signal
307 //---------------------------------------------------------------------------
309 // XAutoLock has detected the required idle time.
311 void SaverEngine::idleTimeout()
313 startLockProcess( DefaultLock
);
316 xautolock_corner_t
SaverEngine::applyManualSettings(int action
)
320 kDebug() << "no lock";
323 else if (action
== 1)
325 kDebug() << "lock screen";
328 else if (action
== 2)
330 kDebug() << "prevent lock";
335 kDebug() << "no lock nothing";
340 uint
SaverEngine::GetSessionIdleTime()
342 return mXAutoLock
->idleTime();
345 uint
SaverEngine::GetActiveTime()
347 if ( m_actived_time
== -1 )
349 return time( 0 ) - m_actived_time
;
352 bool SaverEngine::GetActive()
354 return ( mState
!= Waiting
);
357 bool SaverEngine::SetActive(bool state
)
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
);
379 void SaverEngine::UnInhibit(uint cookie
)
381 QMutableListIterator
<ScreenSaverRequest
> it( m_requests
);
382 while ( it
.hasNext() )
384 if ( it
.next().cookie
== cookie
) {
386 if ( !--m_nr_inhibited
)
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
);
402 if (mLockProcess
.isRunning())
403 mLockProcess
.suspend();
407 void SaverEngine::UnThrottle(uint cookie
)
409 QMutableListIterator
<ScreenSaverRequest
> it( m_requests
);
410 while ( it
.hasNext() )
412 if ( it
.next().cookie
== cookie
) {
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
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
);
435 UnInhibit( r
.cookie
);
440 #include "saverengine.moc"