1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qabstracteventdispatcher.h"
41#include "qabstracteventdispatcher_p.h"
42#include "qabstractnativeeventfilter.h"
43
44#include "qthread.h"
45#include <private/qthread_p.h>
46#include <private/qcoreapplication_p.h>
47#include <private/qfreelist_p.h>
48
49QT_BEGIN_NAMESPACE
50
51// we allow for 2^24 = 8^8 = 16777216 simultaneously running timers
52struct QtTimerIdFreeListConstants : public QFreeListDefaultConstants
53{
54 enum
55 {
56 InitialNextValue = 1,
57 BlockCount = 6
58 };
59
60 static const int Sizes[BlockCount];
61};
62
63enum {
64 Offset0 = 0x00000000,
65 Offset1 = 0x00000040,
66 Offset2 = 0x00000100,
67 Offset3 = 0x00001000,
68 Offset4 = 0x00010000,
69 Offset5 = 0x00100000,
70
71 Size0 = Offset1 - Offset0,
72 Size1 = Offset2 - Offset1,
73 Size2 = Offset3 - Offset2,
74 Size3 = Offset4 - Offset3,
75 Size4 = Offset5 - Offset4,
76 Size5 = QtTimerIdFreeListConstants::MaxIndex - Offset5
77};
78
79const int QtTimerIdFreeListConstants::Sizes[QtTimerIdFreeListConstants::BlockCount] = {
80 Size0,
81 Size1,
82 Size2,
83 Size3,
84 Size4,
85 Size5
86};
87
88typedef QFreeList<void, QtTimerIdFreeListConstants> QtTimerIdFreeList;
89Q_GLOBAL_STATIC(QtTimerIdFreeList, timerIdFreeList)
90
91int QAbstractEventDispatcherPrivate::allocateTimerId()
92{
93 // This function may be called after timerIdFreeList() has been destructed
94 // for example in case when application exits without waiting for
95 // running threads to exit and running thread finished() has been connected
96 // to a slot which triggers a sequence that registers new timer.
97 // See https://bugreports.qt-project.org/browse/QTBUG-38957.
98 if (QtTimerIdFreeList *fl = timerIdFreeList())
99 return fl->next();
100 return 0; // Note! returning 0 generates a warning
101}
102
103void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId)
104{
105 // this function may be called by a global destructor after
106 // timerIdFreeList() has been destructed
107 if (QtTimerIdFreeList *fl = timerIdFreeList())
108 fl->release(id: timerId);
109}
110
111/*!
112 \class QAbstractEventDispatcher
113 \inmodule QtCore
114 \brief The QAbstractEventDispatcher class provides an interface to manage Qt's event queue.
115
116 \ingroup events
117
118 An event dispatcher receives events from the window system and other
119 sources. It then sends them to the QCoreApplication or QApplication
120 instance for processing and delivery. QAbstractEventDispatcher provides
121 fine-grained control over event delivery.
122
123 For simple control of event processing use
124 QCoreApplication::processEvents().
125
126 For finer control of the application's event loop, call
127 instance() and call functions on the QAbstractEventDispatcher
128 object that is returned. If you want to use your own instance of
129 QAbstractEventDispatcher or of a QAbstractEventDispatcher
130 subclass, you must install it with QCoreApplication::setEventDispatcher()
131 or QThread::setEventDispatcher() \e before a default event dispatcher has
132 been installed.
133
134 The main event loop is started by calling
135 QCoreApplication::exec(), and stopped by calling
136 QCoreApplication::exit(). Local event loops can be created using
137 QEventLoop.
138
139 Programs that perform long operations can call processEvents()
140 with a bitwise OR combination of various QEventLoop::ProcessEventsFlag
141 values to control which events should be delivered.
142
143 QAbstractEventDispatcher also allows the integration of an
144 external event loop with the Qt event loop.
145
146 \sa QEventLoop, QCoreApplication, QThread
147*/
148
149/*!
150 Constructs a new event dispatcher with the given \a parent.
151*/
152QAbstractEventDispatcher::QAbstractEventDispatcher(QObject *parent)
153 : QObject(*new QAbstractEventDispatcherPrivate, parent) {}
154
155/*!
156 \internal
157*/
158QAbstractEventDispatcher::QAbstractEventDispatcher(QAbstractEventDispatcherPrivate &dd,
159 QObject *parent)
160 : QObject(dd, parent) {}
161
162/*!
163 Destroys the event dispatcher.
164*/
165QAbstractEventDispatcher::~QAbstractEventDispatcher()
166{ }
167
168/*!
169 Returns a pointer to the event dispatcher object for the specified
170 \a thread. If \a thread is \nullptr, the current thread is used. If no
171 event dispatcher exists for the specified thread, this function
172 returns \nullptr.
173
174 \b{Note:} If Qt is built without thread support, the \a thread
175 argument is ignored.
176 */
177QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
178{
179 QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current();
180 return data->eventDispatcher.loadRelaxed();
181}
182
183/*!
184 \fn bool QAbstractEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
185
186 Processes pending events that match \a flags until there are no
187 more events to process. Returns \c true if an event was processed;
188 otherwise returns \c false.
189
190 This function is especially useful if you have a long running
191 operation, and want to show its progress without allowing user
192 input by using the QEventLoop::ExcludeUserInputEvents flag.
193
194 If the QEventLoop::WaitForMoreEvents flag is set in \a flags, the
195 behavior of this function is as follows:
196
197 \list
198
199 \li If events are available, this function returns after processing
200 them.
201
202 \li If no events are available, this function will wait until more
203 are available and return after processing newly available events.
204
205 \endlist
206
207 If the QEventLoop::WaitForMoreEvents flag is not set in \a flags,
208 and no events are available, this function will return
209 immediately.
210
211 \b{Note:} This function does not process events continuously; it
212 returns after all available events are processed.
213
214 \sa hasPendingEvents()
215*/
216
217/*!
218 \internal
219
220 \note processEvents() only processes events queued before the function
221 is called. Events that are posted while the function runs will be queued
222 until a later round of event processing. This only applies to posted Qt
223 events. For timers and system level events, the situation is unknown.
224*/
225
226/*! \fn bool QAbstractEventDispatcher::hasPendingEvents()
227 \deprecated
228
229 Returns \c true if there is an event waiting; otherwise returns false. This
230 function is an implementation detail for
231 QCoreApplication::hasPendingEvents() and must not be called directly.
232*/
233
234/*!
235 \fn void QAbstractEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
236
237 Registers \a notifier with the event loop. Subclasses must
238 implement this method to tie a socket notifier into another
239 event loop.
240*/
241
242/*! \fn void QAbstractEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
243
244 Unregisters \a notifier from the event dispatcher. Subclasses must
245 reimplement this method to tie a socket notifier into another
246 event loop. Reimplementations must call the base
247 implementation.
248*/
249
250/*!
251 \obsolete
252
253 \fn int QAbstractEventDispatcher::registerTimer(int interval, QObject *object)
254
255 Registers a timer with the specified \a interval for the given \a object
256 and returns the timer id.
257*/
258
259/*!
260 \obsolete
261
262 \fn void QAbstractEventDispatcher::registerTimer(int timerId, int interval, QObject *object)
263
264 Register a timer with the specified \a timerId and \a interval for the
265 given \a object.
266*/
267
268/*!
269 Registers a timer with the specified \a interval and \a timerType for the
270 given \a object and returns the timer id.
271*/
272int QAbstractEventDispatcher::registerTimer(int interval, Qt::TimerType timerType, QObject *object)
273{
274 int id = QAbstractEventDispatcherPrivate::allocateTimerId();
275 registerTimer(timerId: id, interval, timerType, object);
276 return id;
277}
278
279/*!
280 \fn void QAbstractEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
281
282 Register a timer with the specified \a timerId, \a interval, and \a
283 timerType for the given \a object.
284*/
285
286/*!
287 \fn bool QAbstractEventDispatcher::unregisterTimer(int timerId)
288
289 Unregisters the timer with the given \a timerId.
290 Returns \c true if successful; otherwise returns \c false.
291
292 \sa registerTimer(), unregisterTimers()
293*/
294
295/*!
296 \fn bool QAbstractEventDispatcher::unregisterTimers(QObject *object)
297
298 Unregisters all the timers associated with the given \a object.
299 Returns \c true if all timers were successful removed; otherwise returns \c false.
300
301 \sa unregisterTimer(), registeredTimers()
302*/
303
304/*!
305 \fn QList<TimerInfo> QAbstractEventDispatcher::registeredTimers(QObject *object) const
306
307 Returns a list of registered timers for \a object. The TimerInfo struct has
308 \c timerId, \c interval, and \c timerType members.
309
310 \sa Qt::TimerType
311*/
312
313/*!
314 \fn int QAbstractEventDispatcher::remainingTime(int timerId)
315
316 Returns the remaining time in milliseconds with the given \a timerId.
317 If the timer is inactive, the returned value will be -1. If the timer is
318 overdue, the returned value will be 0.
319
320 \sa Qt::TimerType
321*/
322
323/*! \fn void QAbstractEventDispatcher::wakeUp()
324 \threadsafe
325
326 Wakes up the event loop.
327
328 \omit
329 ### FIXME - QTBUG-70229
330 On Unix and Glib event dispatchers, if the dispatcher is already awake when
331 this function is called, it is ensured that the current iteration won't block
332 waiting for more events, but will instead do another event loop iteration.
333
334 ### TODO - does other event dispatchers behave the same?
335 \endomit
336
337 \sa awake()
338*/
339
340/*!
341 \fn void QAbstractEventDispatcher::interrupt()
342
343 Interrupts event dispatching. The event dispatcher will
344 return from processEvents() as soon as possible.
345*/
346
347/*! \fn void QAbstractEventDispatcher::flush()
348 \deprecated
349
350 Depending from the event dispatcher implementation does nothing or
351 calls QApplication::sendPostedEvents().
352*/
353
354// ### DOC: Are these called when the _application_ starts/stops or just
355// when the current _event loop_ starts/stops?
356/*!
357 \internal
358*/
359void QAbstractEventDispatcher::startingUp()
360{ }
361
362/*!
363 \internal
364*/
365void QAbstractEventDispatcher::closingDown()
366{ }
367
368/*!
369 \class QAbstractEventDispatcher::TimerInfo
370 \inmodule QtCore
371
372 This struct represents information about a timer:
373 \l{QAbstractEventDispatcher::TimerInfo::timerId}{timerId},
374 \l{QAbstractEventDispatcher::TimerInfo::interval}{interval}, and
375 \l{QAbstractEventDispatcher::TimerInfo::timerType}{timerType}.
376
377 \sa registeredTimers()
378*/
379/*! \fn QAbstractEventDispatcher::TimerInfo::TimerInfo(int timerId, int interval, Qt::TimerType timerType)
380
381 Constructs a TimerInfo struct with the given \a timerId, \a interval, and
382 \a timerType.
383*/
384/*!
385 \variable QAbstractEventDispatcher::TimerInfo::timerId
386
387 The timer's unique id.
388*/
389/*!
390 \variable QAbstractEventDispatcher::TimerInfo::interval
391
392 The timer's interval.
393*/
394/*!
395 \variable QAbstractEventDispatcher::TimerInfo::timerType
396
397 The timer's type
398
399 \sa Qt::TimerType
400*/
401
402/*!
403 Installs an event filter \a filterObj for all native events received by the application.
404
405 The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
406 function, which is called for all events received by all threads.
407
408 The \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function should return true
409 if the event should be filtered, (in this case, stopped). It should return false to allow
410 normal Qt processing to continue: the native event can then be translated
411 into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
412 e.g. QObject::installEventFilter().
413
414 If multiple event filters are installed, the filter that was installed last
415 is activated first.
416
417 \note The filter function set here receives native messages,
418 that is, MSG or XEvent structs.
419
420 For maximum portability, you should always try to use QEvent objects
421 and QObject::installEventFilter() whenever possible.
422
423 \sa QObject::installEventFilter()
424
425 \since 5.0
426*/
427void QAbstractEventDispatcher::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
428{
429 Q_D(QAbstractEventDispatcher);
430
431 // clean up unused items in the list
432 d->eventFilters.removeAll(t: 0);
433 d->eventFilters.removeAll(t: filterObj);
434 d->eventFilters.prepend(t: filterObj);
435}
436
437/*!
438 Removes the event filter \a filter from this object. The
439 request is ignored if such an event filter has not been installed.
440
441 All event filters for this object are automatically removed when
442 this object is destroyed.
443
444 It is always safe to remove an event filter, even during event filter
445 filter activation (that is, even from within the \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function).
446
447 \sa installNativeEventFilter(), QAbstractNativeEventFilter
448 \since 5.0
449*/
450void QAbstractEventDispatcher::removeNativeEventFilter(QAbstractNativeEventFilter *filter)
451{
452 Q_D(QAbstractEventDispatcher);
453 for (int i = 0; i < d->eventFilters.count(); ++i) {
454 if (d->eventFilters.at(i) == filter) {
455 d->eventFilters[i] = 0;
456 break;
457 }
458 }
459}
460
461/*!
462 Sends \a message through the event filters that were set by
463 installNativeEventFilter(). This function returns \c true as soon as an
464 event filter returns \c true, and false otherwise to indicate that
465 the processing of the event should continue.
466
467 Subclasses of QAbstractEventDispatcher \e must call this function
468 for \e all messages received from the system to ensure
469 compatibility with any extensions that may be used in the
470 application. The type of event \a eventType is specific to the platform
471 plugin chosen at run-time, and can be used to cast message to the right type.
472 The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer.
473
474 Note that the type of \a message is platform dependent. See
475 QAbstractNativeEventFilter for details.
476
477 \sa installNativeEventFilter(), QAbstractNativeEventFilter::nativeEventFilter()
478 \since 5.0
479*/
480#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
481bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
482#else
483bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, long *result)
484#endif
485{
486 Q_D(QAbstractEventDispatcher);
487 if (!d->eventFilters.isEmpty()) {
488 // Raise the loopLevel so that deleteLater() calls in or triggered
489 // by event_filter() will be processed from the main event loop.
490 QScopedScopeLevelCounter scopeLevelCounter(d->threadData);
491 for (int i = 0; i < d->eventFilters.size(); ++i) {
492 QAbstractNativeEventFilter *filter = d->eventFilters.at(i);
493 if (!filter)
494 continue;
495 if (filter->nativeEventFilter(eventType, message, result))
496 return true;
497 }
498 }
499 return false;
500}
501
502/*! \fn bool QAbstractEventDispatcher::filterEvent(void *message)
503 \deprecated
504
505 Calls filterNativeEvent() with an empty eventType and \a message.
506 This function returns \c true as soon as an
507 event filter returns \c true, and false otherwise to indicate that
508 the processing of the event should continue.
509*/
510
511/*! \fn bool QAbstractEventDispatcher::registerEventNotifier(QWinEventNotifier *notifier)
512
513 This pure virtual method exists on windows only and has to be reimplemented by a Windows specific
514 event dispatcher implementation. \a notifier is the QWinEventNotifier instance to be registered.
515
516 The method should return true if the registration of \a notifier was successful, otherwise false.
517
518 QWinEventNotifier calls this method in it's constructor and there should never be a need to call this
519 method directly.
520
521 \sa QWinEventNotifier, unregisterEventNotifier()
522*/
523
524/*! \fn bool QAbstractEventDispatcher::unregisterEventNotifier(QWinEventNotifier *notifier)
525
526 This pure virtual method exists on windows only and has to be reimplemented by a Windows specific
527 event dispatcher implementation. \a notifier is the QWinEventNotifier instance to be unregistered.
528
529 QWinEventNotifier calls this method in it's destructor and there should never be a need to call this
530 method directly.
531
532 \sa QWinEventNotifier, registerEventNotifier()
533*/
534
535/*! \fn void QAbstractEventDispatcher::awake()
536
537 This signal is emitted after the event loop returns from a
538 function that could block.
539
540 \sa wakeUp(), aboutToBlock()
541*/
542
543/*! \fn void QAbstractEventDispatcher::aboutToBlock()
544
545 This signal is emitted before the event loop calls a function that
546 could block.
547
548 \sa awake()
549*/
550
551QT_END_NAMESPACE
552
553#include "moc_qabstracteventdispatcher.cpp"
554

source code of qtbase/src/corelib/kernel/qabstracteventdispatcher.cpp