Add (and install) svg for the new krunner interface.
[kdebase/uwolfer.git] / workspace / krunner / xautolock.cpp
blob8b7b9e6d1f8aee10a7882bb23c3499bafbafa676
1 //----------------------------------------------------------------------------
2 //
3 // This file is part of the KDE project
4 //
5 // Copyright 1999 Martin R. Jones <mjones@kde.org>
6 // Copyright 2003 Lubos Lunak <l.lunak@kde.org>
7 //
8 // KDE screensaver engine
9 //
11 #include <config-workspace.h>
13 #include "xautolock.h"
14 #include "xautolock_c.h"
16 #include <kapplication.h>
17 #include <kdebug.h>
19 #include <QTimerEvent>
20 #include <QX11Info>
22 #include <X11/Xlib.h>
23 #include <X11/Xutil.h>
25 #ifdef HAVE_DPMS
26 extern "C" {
27 #include <X11/Xmd.h>
28 #ifndef Bool
29 #define Bool BOOL
30 #endif
31 #include <X11/extensions/dpms.h>
33 #ifndef HAVE_DPMSINFO_PROTO
34 Status DPMSInfo ( Display *, CARD16 *, BOOL * );
35 #endif
37 #endif
39 #include <ctime>
41 #ifdef HAVE_XSCREENSAVER
42 int xautolock_useMit;
43 #endif
44 xautolock_corner_t xautolock_corners[ 4 ];
46 static XAutoLock* self = NULL;
48 extern "C" {
49 static int catchFalseAlarms(Display *, XErrorEvent *)
51 return 0;
55 //===========================================================================
57 // Detect user inactivity.
58 // Named XAutoLock after the program that it is based on.
60 XAutoLock::XAutoLock()
62 self = this;
63 #ifdef HAVE_XSCREENSAVER
64 int dummy;
65 xautolock_useMit = XScreenSaverQueryExtension( QX11Info::display(), &dummy, &dummy );
66 #endif
67 if( !xautolock_useMit )
69 kapp->installX11EventFilter( this );
70 int (*oldHandler)(Display *, XErrorEvent *);
71 oldHandler = XSetErrorHandler(catchFalseAlarms);
72 XSync(QX11Info::display(), False );
73 xautolock_initDiy( QX11Info::display());
74 XSync(QX11Info::display(), False );
75 XSetErrorHandler(oldHandler);
78 mTimeout = DEFAULT_TIMEOUT;
79 mDPMS = true;
80 resetTrigger();
82 time(&mLastTimeout);
83 mActive = false;
85 mTimerId = startTimer( CHECK_INTERVAL );
89 //---------------------------------------------------------------------------
91 // Destructor.
93 XAutoLock::~XAutoLock()
95 stop();
96 self = NULL;
99 //---------------------------------------------------------------------------
101 // The time in seconds of continuous inactivity.
103 void XAutoLock::setTimeout(int t)
105 mTimeout = t;
108 void XAutoLock::setDPMS(bool s)
110 #ifdef HAVE_DPMS
111 BOOL on;
112 CARD16 state;
113 DPMSInfo( QX11Info::display(), &state, &on );
114 if (!on)
115 s = false;
116 #endif
117 mDPMS = s;
120 //---------------------------------------------------------------------------
122 // Start watching Activity
124 void XAutoLock::start()
126 time(&mLastTimeout);
127 mActive = true;
128 resetTrigger();
129 XSetScreenSaver(QX11Info::display(), mTimeout + 10, 100, PreferBlanking, DontAllowExposures); // We'll handle blanking
130 kDebug() << "XSetScreenSaver" << mTimeout + 10;
133 //---------------------------------------------------------------------------
135 // Stop watching Activity
137 void XAutoLock::stop()
139 mActive = false;
140 resetTrigger();
141 XSetScreenSaver(QX11Info::display(), 0, 100, PreferBlanking, DontAllowExposures); // No blanking at all
142 kDebug() << "XSetScreenSaver 0";
145 //---------------------------------------------------------------------------
147 // Reset the trigger time.
149 void XAutoLock::resetTrigger()
151 mLastReset = time( 0 );
152 mTrigger = mLastReset + mTimeout;
153 XForceScreenSaver( QX11Info::display(), ScreenSaverReset );
156 //---------------------------------------------------------------------------
158 // Move the trigger time in order to postpone (repeat) emitting of timeout().
160 void XAutoLock::postpone()
162 mTrigger = time(0) + 60; // delay by 60sec
165 //---------------------------------------------------------------------------
167 // Set the remaining time to 't', if it's shorter than already set.
169 void XAutoLock::setTrigger( time_t t )
171 if( t < mTrigger )
172 mTrigger = t;
175 //---------------------------------------------------------------------------
177 // Process new windows and check the mouse.
179 void XAutoLock::timerEvent(QTimerEvent *ev)
181 if (ev->timerId() != mTimerId)
183 return;
186 int (*oldHandler)(Display *, XErrorEvent *) = NULL;
187 if( !xautolock_useMit )
188 { // only the diy way needs special X handler
189 XSync( QX11Info::display(), False );
190 oldHandler = XSetErrorHandler(catchFalseAlarms);
193 xautolock_processQueue();
195 time_t now = time(0);
196 if ((now > mLastTimeout && now - mLastTimeout > TIME_CHANGE_LIMIT) ||
197 (mLastTimeout > now && mLastTimeout - now > TIME_CHANGE_LIMIT+1))
199 /* the time has changed in one large jump. This could be because
200 the date was changed, or the machine was suspended. We'll just
201 reset the triger. */
202 resetTrigger();
205 mLastTimeout = now;
207 xautolock_queryIdleTime( QX11Info::display());
208 xautolock_queryPointer( QX11Info::display());
210 if( !xautolock_useMit )
211 XSetErrorHandler(oldHandler);
213 bool activate = false;
215 // kDebug() << now << mTrigger;
216 if (now >= mTrigger)
218 resetTrigger();
219 activate = true;
222 #ifdef HAVE_DPMS
223 BOOL on;
224 CARD16 state;
225 DPMSInfo( QX11Info::display(), &state, &on );
227 // kDebug() << "DPMSInfo " << state << on;
228 // If DPMS is active, it makes XScreenSaverQueryInfo() report idle time
229 // that is always smaller than DPMS timeout (X bug I guess). So if DPMS
230 // saving is active, simply always activate our saving too, otherwise
231 // this could prevent locking from working.
232 if(state == DPMSModeStandby || state == DPMSModeSuspend || state == DPMSModeOff)
233 activate = true;
234 if(!on && mDPMS) {
235 activate = false;
236 resetTrigger();
238 #endif
240 #ifdef HAVE_XSCREENSAVER
241 static XScreenSaverInfo* mitInfo = 0;
242 if (!mitInfo) mitInfo = XScreenSaverAllocInfo ();
243 if (XScreenSaverQueryInfo (QX11Info::display(), QX11Info::appRootWindow(), mitInfo)) {
244 // kDebug() << "XScreenSaverQueryInfo " << mitInfo->state << ScreenSaverDisabled;
245 if (mitInfo->state == ScreenSaverDisabled)
246 activate = false;
248 #endif
250 if(mActive && activate)
251 emit timeout();
254 bool XAutoLock::x11Event( XEvent* ev )
256 xautolock_processEvent( ev );
257 // don't futher process key events that were received only because XAutoLock wants them
258 if( ev->type == KeyPress && !ev->xkey.send_event
259 && !xautolock_useMit
260 && !QWidget::find( ev->xkey.window ))
261 return true;
262 return false;
265 bool XAutoLock::ignoreWindow( WId w )
267 if( w != QX11Info::appRootWindow() && QWidget::find( w ))
268 return true;
269 return false;
272 time_t XAutoLock::idleTime()
274 return time( 0 ) - mLastReset;
277 extern "C"
278 void xautolock_resetTriggers()
280 self->resetTrigger();
283 extern "C"
284 void xautolock_setTrigger( time_t t )
286 self->setTrigger( t );
289 extern "C"
290 int xautolock_ignoreWindow( Window w )
292 return self->ignoreWindow( w );
295 #include "xautolock.moc"