source: vendor/trolltech/current/src/kernel/qeventloop.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 12.1 KB
Line 
1/****************************************************************************
2** $Id: qeventloop.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QEventLoop class
5**
6** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the kernel module of the Qt GUI Toolkit.
9**
10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file.
13**
14** This file may be distributed and/or modified under the terms of the
15** GNU General Public License version 2 as published by the Free Software
16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file.
18**
19** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
20** licenses may use this file in accordance with the Qt Commercial License
21** Agreement provided with the Software.
22**
23** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25**
26** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
27** information about Qt Commercial License Agreements.
28** See http://www.trolltech.com/qpl/ for QPL licensing information.
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "qeventloop_p.h" // includes qplatformdefs.h
37#include "qeventloop.h"
38#include "qapplication.h"
39#include "qdatetime.h"
40
41/*!
42 \class QEventLoop
43 \brief The QEventLoop class manages the event queue.
44
45 \ingroup application
46 \ingroup events
47
48 It receives events from the window system and other sources. It
49 then sends them to QApplication for processing and delivery.
50
51 QEventLoop allows the application programmer to have more control
52 over event delivery. Programs that perform long operations can
53 call either processOneEvent() or processEvents() with various
54 ProcessEvent values OR'ed together to control which events should
55 be delivered.
56
57 QEventLoop also allows the integration of an external event loop
58 with the Qt event loop. The Motif Extension included with Qt
59 includes a reimplementation of QEventLoop for merging Qt and Motif
60 events together.
61
62 To use your own instance of QEventLoop or QEventLoop subclass create
63 it before you create the QApplication object.
64*/
65
66/*! \enum QEventLoop::ProcessEvents
67
68 This enum controls the types of events processed by the
69 processEvents() functions.
70
71 \value AllEvents - All events are processed
72 \value ExcludeUserInput - Do not process user input events.
73 ( ButtonPress, KeyPress, etc. )
74 \value ExcludeSocketNotifiers - Do not process socket notifier
75 events.
76 \value WaitForMore - Wait for events if no pending events
77 are available.
78
79 \sa processEvents()
80*/
81
82/*! \enum QEventLoop::ProcessEventsFlags
83 A \c typedef to allow various ProcessEvents values to be OR'ed together.
84
85 \sa ProcessEvents
86 */
87
88/*!
89 Creates a QEventLoop object, this object becomes the global event loop object.
90 There can only be one event loop object. The QEventLoop is usually constructed
91 by calling QApplication::eventLoop(). To create your own event loop object create
92 it before you instantiate the QApplication object.
93
94 The \a parent and \a name arguments are passed on to the QObject constructor.
95*/
96QEventLoop::QEventLoop( QObject *parent, const char *name )
97 : QObject( parent, name )
98{
99#if defined(QT_CHECK_STATE)
100 if ( QApplication::eventloop )
101 qFatal( "QEventLoop: there must be only one event loop object. \nConstruct it before QApplication." );
102 // for now ;)
103#endif // QT_CHECK_STATE
104
105 d = new QEventLoopPrivate;
106
107 init();
108 QApplication::eventloop = this;
109}
110
111/*!
112 Destructs the QEventLoop object.
113*/
114QEventLoop::~QEventLoop()
115{
116 cleanup();
117 delete d;
118 QApplication::eventloop = 0;
119}
120
121/*!
122 Enters the main event loop and waits until exit() is called, and
123 returns the value that was set to exit().
124
125 It is necessary to call this function to start event handling. The
126 main event loop receives events from the window system and
127 dispatches these to the application widgets.
128
129 Generally speaking, no user interaction can take place before
130 calling exec(). As a special case, modal widgets like QMessageBox
131 can be used before calling exec(), because modal widgets call
132 exec() to start a local event loop.
133
134 To make your application perform idle processing, i.e. executing a
135 special function whenever there are no pending events, use a
136 QTimer with 0 timeout. More advanced idle processing schemes can
137 be achieved using processEvents().
138
139 \sa QApplication::quit(), exit(), processEvents()
140*/
141int QEventLoop::exec()
142{
143 d->reset();
144
145 enterLoop();
146
147 // cleanup
148 d->looplevel = 0;
149 d->quitnow = FALSE;
150 d->exitloop = FALSE;
151 d->shortcut = FALSE;
152 // don't reset quitcode!
153
154 return d->quitcode;
155}
156
157/*! \fn void QEventLoop::exit( int retcode = 0 )
158
159 Tells the event loop to exit with a return code.
160
161 After this function has been called, the event loop returns from
162 the call to exec(). The exec() function returns \a retcode.
163
164 By convention, a \a retcode of 0 means success, and any non-zero
165 value indicates an error.
166
167 Note that unlike the C library function of the same name, this
168 function \e does return to the caller -- it is event processing that
169 stops.
170
171 \sa QApplication::quit(), exec()
172*/
173void QEventLoop::exit( int retcode )
174{
175 if ( d->quitnow ) // preserve existing quitcode
176 return;
177 d->quitcode = retcode;
178 d->quitnow = TRUE;
179 d->exitloop = TRUE;
180 d->shortcut = TRUE;
181}
182
183
184/*! \fn int QEventLoop::enterLoop()
185
186 This function enters the main event loop (recursively). Do not call
187 it unless you really know what you are doing.
188 */
189int QEventLoop::enterLoop()
190{
191 // save the current exitloop state
192 bool old_exitloop = d->exitloop;
193 d->exitloop = FALSE;
194 d->shortcut = FALSE;
195
196 d->looplevel++;
197 while ( ! d->exitloop )
198 processEvents( AllEvents | WaitForMore );
199 d->looplevel--;
200
201 // restore the exitloop state, but if quitnow is TRUE, we need to keep
202 // exitloop set so that all other event loops drop out.
203 d->exitloop = old_exitloop || d->quitnow;
204 d->shortcut = d->quitnow;
205
206 if ( d->looplevel < 1 ) {
207 d->quitnow = FALSE;
208 d->exitloop = FALSE;
209 d->shortcut = FALSE;
210 emit qApp->aboutToQuit();
211
212 // send deferred deletes
213 QApplication::sendPostedEvents( 0, QEvent::DeferredDelete );
214 }
215
216 return d->looplevel;
217}
218
219/*! \fn void QEventLoop::exitLoop()
220
221 This function exits from a recursive call to the main event loop.
222 Do not call it unless you really know what you are doing.
223*/
224void QEventLoop::exitLoop()
225{
226 d->exitloop = TRUE;
227 d->shortcut = TRUE;
228}
229
230/*! \fn void QEventLoop::loopLevel() const
231
232 Returns the current loop level.
233*/
234int QEventLoop::loopLevel() const
235{
236 return d->looplevel;
237}
238
239/*!
240 Process pending events that match \a flags for a maximum of \a
241 maxTime milliseconds, or until there are no more events to
242 process, which ever is shorter.
243
244 This function is especially useful if you have a long running
245 operation and want to show its progress without allowing user
246 input, i.e. by using the \c ExcludeUserInput flag.
247
248 NOTE: This function will not process events continuously; it
249 returns after all available events are processed.
250
251 NOTE: Specifying the \c WaitForMore flag makes no sense and will
252 be ignored.
253*/
254void QEventLoop::processEvents( ProcessEventsFlags flags, int maxTime )
255{
256 QTime start = QTime::currentTime();
257 QTime now;
258 while ( ! d->quitnow && processEvents( flags & ~WaitForMore ) ) {
259 now = QTime::currentTime();
260 if ( start.msecsTo( now ) > maxTime )
261 break;
262 }
263}
264
265/*!
266 \fn bool QEventLoop::processEvents( ProcessEventsFlags flags )
267 \overload
268
269 Processes pending events that match \a flags until there are no
270 more events to process.
271
272 This function is especially useful if you have a long running
273 operation and want to show its progress without allowing user
274 input, i.e. by using the \c ExcludeUserInput flag.
275
276 If the \c WaitForMore flag is set in \a flags, the behavior of
277 this function is as follows:
278
279 \list
280
281 \i If events are available, this function returns after processing
282 them.
283
284 \i If no events are available, this function will wait until more
285 are available and return after processing newly available events.
286
287 \endlist
288
289 If the \c WaitForMore flag is \e not set in \a flags, and no
290 events are available, this function will return immediately.
291
292 NOTE: This function will not process events continuously; it
293 returns after all available events are processed.
294
295 This function returns TRUE if an event was processed; otherwise it
296 returns FALSE.
297
298 \sa ProcessEvents hasPendingEvents()
299*/
300
301/*! \fn bool QEventLoop::hasPendingEvents() const
302
303 Returns TRUE if there is an event waiting, otherwise it returns FALSE.
304*/
305
306/*! \fn void QEventLoop::registerSocketNotifier( QSocketNotifier *notifier )
307
308 Registers \a notifier with the event loop. Subclasses need to
309 reimplement this method to tie a socket notifier into another
310 event loop. Reimplementations \e MUST call the base
311 implementation.
312*/
313
314/*! \fn void QEventLoop::unregisterSocketNotifier( QSocketNotifier *notifier )
315
316 Unregisters \a notifier from the event loop. Subclasses need to
317 reimplement this method to tie a socket notifier into another
318 event loop. Reimplementations \e MUST call the base
319 implementation.
320*/
321
322/*! \fn void QEventLoop::setSocketNotifierPending( QSocketNotifier *notifier )
323
324 Marks \a notifier as pending. The socket notifier will be
325 activated the next time activateSocketNotifiers() is called.
326*/
327
328/*! \fn int QEventLoop::activateSocketNotifiers()
329
330 Activates all pending socket notifiers and returns the number of
331 socket notifiers that were activated.
332*/
333
334/*! \fn int QEventLoop::activateTimers()
335
336 Activates all Qt timers and returns the number of timers that were
337 activated.
338
339 QEventLoop subclasses that do their own timer handling need to
340 call this after the time returned by timeToWait() has elapsed.
341
342 Note: This function is only useful on systems where \c select() is
343 used to block the eventloop. On Windows, this function always
344 returns 0. On MacOS X, this function always returns 0 when the
345 GUI is enabled. On MacOS X, this function returns the documented
346 value when the GUI is disabled.
347*/
348
349/*! \fn int QEventLoop::timeToWait() const
350
351 Returns the number of milliseconds that Qt needs to handle its
352 timers or -1 if there are no timers running.
353
354 QEventLoop subclasses that do their own timer handling need to use
355 this to make sure that Qt's timers continue to work.
356
357 Note: This function is only useful on systems where \c select() is
358 used to block the eventloop. On Windows, this function always
359 returns -1. On MacOS X, this function always returns -1 when the
360 GUI is enabled. On MacOS X, this function returns the documented
361 value when the GUI is disabled.
362*/
363
364/*! \fn void QEventLoop::wakeUp()
365 \threadsafe
366
367 Wakes up the event loop.
368
369 \sa awake()
370*/
371
372/*! \fn void QEventLoop::awake()
373
374 This signal is emitted after the event loop returns from a
375 function that could block.
376
377 \sa wakeUp() aboutToBlock()
378*/
379
380/*! \fn void QEventLoop::aboutToBlock()
381
382 This signal is emitted before the event loop calls a function that
383 could block.
384
385 \sa awake()
386*/
387
388#if !defined(Q_WS_X11)
389void QEventLoop::appStartingUp(){}
390void QEventLoop::appClosingDown(){}
391#endif // Q_WS_X11
Note: See TracBrowser for help on using the repository browser.