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(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
215/*!
216 \internal
217
218 \note processEvents() only processes events queued before the function
219 is called. Events that are posted while the function runs will be queued
220 until a later round of event processing. This only applies to posted Qt
221 events. For timers and system level events, the situation is unknown.
222*/
223
224/*!
225 \fn void QAbstractEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
226
227 Registers \a notifier with the event loop. Subclasses must
228 implement this method to tie a socket notifier into another
229 event loop.
230*/
231
232/*! \fn void QAbstractEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
233
234 Unregisters \a notifier from the event dispatcher. Subclasses must
235 reimplement this method to tie a socket notifier into another
236 event loop. Reimplementations must call the base
237 implementation.
238*/
239
240/*!
241 Registers a timer with the specified \a interval and \a timerType for the
242 given \a object and returns the timer id.
243*/
244int QAbstractEventDispatcher::registerTimer(qint64 interval, Qt::TimerType timerType, QObject *object)
245{
246 int id = QAbstractEventDispatcherPrivate::allocateTimerId();
247 registerTimer(id, interval, timerType, object);
248 return id;
249}
250
251/*!
252 \fn void QAbstractEventDispatcher::registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object)
253
254 Register a timer with the specified \a timerId, \a interval, and \a
255 timerType for the given \a object.
256*/
257
258/*!
259 \fn bool QAbstractEventDispatcher::unregisterTimer(int timerId)
260
261 Unregisters the timer with the given \a timerId.
262 Returns \c true if successful; otherwise returns \c false.
263
264 \sa registerTimer(), unregisterTimers()
265*/
266
267/*!
268 \fn bool QAbstractEventDispatcher::unregisterTimers(QObject *object)
269
270 Unregisters all the timers associated with the given \a object.
271 Returns \c true if all timers were successful removed; otherwise returns \c false.
272
273 \sa unregisterTimer(), registeredTimers()
274*/
275
276/*!
277 \fn QList<TimerInfo> QAbstractEventDispatcher::registeredTimers(QObject *object) const
278
279 Returns a list of registered timers for \a object. The TimerInfo struct has
280 \c timerId, \c interval, and \c timerType members.
281
282 \sa Qt::TimerType
283*/
284
285/*!
286 \fn int QAbstractEventDispatcher::remainingTime(int timerId)
287
288 Returns the remaining time in milliseconds with the given \a timerId.
289 If the timer is inactive, the returned value will be -1. If the timer is
290 overdue, the returned value will be 0.
291
292 \sa Qt::TimerType
293*/
294
295/*! \fn void QAbstractEventDispatcher::wakeUp()
296 \threadsafe
297
298 Wakes up the event loop.
299
300 \omit
301 ### FIXME - QTBUG-70229
302 On Unix and Glib event dispatchers, if the dispatcher is already awake when
303 this function is called, it is ensured that the current iteration won't block
304 waiting for more events, but will instead do another event loop iteration.
305
306 ### TODO - does other event dispatchers behave the same?
307 \endomit
308
309 \sa awake()
310*/
311
312/*!
313 \fn void QAbstractEventDispatcher::interrupt()
314
315 Interrupts event dispatching. The event dispatcher will
316 return from processEvents() as soon as possible.
317*/
318
319// ### DOC: Are these called when the _application_ starts/stops or just
320// when the current _event loop_ starts/stops?
321/*!
322 \internal
323*/
324void QAbstractEventDispatcher::startingUp()
325{ }
326
327/*!
328 \internal
329*/
330void QAbstractEventDispatcher::closingDown()
331{ }
332
333/*!
334 \class QAbstractEventDispatcher::TimerInfo
335 \inmodule QtCore
336
337 This struct represents information about a timer:
338 \l{QAbstractEventDispatcher::TimerInfo::timerId}{timerId},
339 \l{QAbstractEventDispatcher::TimerInfo::interval}{interval}, and
340 \l{QAbstractEventDispatcher::TimerInfo::timerType}{timerType}.
341
342 \sa registeredTimers()
343*/
344/*! \fn QAbstractEventDispatcher::TimerInfo::TimerInfo(int timerId, int interval, Qt::TimerType timerType)
345
346 Constructs a TimerInfo struct with the given \a timerId, \a interval, and
347 \a timerType.
348*/
349/*!
350 \variable QAbstractEventDispatcher::TimerInfo::timerId
351
352 The timer's unique id.
353*/
354/*!
355 \variable QAbstractEventDispatcher::TimerInfo::interval
356
357 The timer's interval.
358*/
359/*!
360 \variable QAbstractEventDispatcher::TimerInfo::timerType
361
362 The timer's type
363
364 \sa Qt::TimerType
365*/
366
367/*!
368 Installs an event filter \a filterObj for all native events received by the application.
369
370 The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
371 function, which is called for all events received by all threads.
372
373 The \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function should return true
374 if the event should be filtered, (in this case, stopped). It should return false to allow
375 normal Qt processing to continue: the native event can then be translated
376 into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
377 e.g. QObject::installEventFilter().
378
379 If multiple event filters are installed, the filter that was installed last
380 is activated first.
381
382 \note The filter function set here receives native messages,
383 that is, MSG or XEvent structs.
384
385 For maximum portability, you should always try to use QEvent objects
386 and QObject::installEventFilter() whenever possible.
387
388 \sa QObject::installEventFilter()
389
390 \since 5.0
391*/
392void QAbstractEventDispatcher::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
393{
394 Q_D(QAbstractEventDispatcher);
395
396 // clean up unused items in the list
397 d->eventFilters.removeAll(nullptr);
398 d->eventFilters.removeAll(filterObj);
399 d->eventFilters.prepend(filterObj);
400}
401
402/*!
403 Removes the event filter \a filter from this object. The
404 request is ignored if such an event filter has not been installed.
405
406 All event filters for this object are automatically removed when
407 this object is destroyed.
408
409 It is always safe to remove an event filter, even during event filter
410 filter activation (that is, even from within the \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function).
411
412 \sa installNativeEventFilter(), QAbstractNativeEventFilter
413 \since 5.0
414*/
415void QAbstractEventDispatcher::removeNativeEventFilter(QAbstractNativeEventFilter *filter)
416{
417 Q_D(QAbstractEventDispatcher);
418 for (int i = 0; i < d->eventFilters.count(); ++i) {
419 if (d->eventFilters.at(i) == filter) {
420 d->eventFilters[i] = nullptr;
421 break;
422 }
423 }
424}
425
426/*!
427 Sends \a message through the event filters that were set by
428 installNativeEventFilter(). This function returns \c true as soon as an
429 event filter returns \c true, and false otherwise to indicate that
430 the processing of the event should continue.
431
432 Subclasses of QAbstractEventDispatcher \e must call this function
433 for \e all messages received from the system to ensure
434 compatibility with any extensions that may be used in the
435 application. The type of event \a eventType is specific to the platform
436 plugin chosen at run-time, and can be used to cast message to the right type.
437 The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer.
438
439 Note that the type of \a message is platform dependent. See
440 QAbstractNativeEventFilter for details.
441
442 \sa installNativeEventFilter(), QAbstractNativeEventFilter::nativeEventFilter()
443 \since 5.0
444*/
445bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
446{
447 Q_D(QAbstractEventDispatcher);
448 if (!d->eventFilters.isEmpty()) {
449 // Raise the loopLevel so that deleteLater() calls in or triggered
450 // by event_filter() will be processed from the main event loop.
451 QScopedScopeLevelCounter scopeLevelCounter(d->threadData);
452 for (int i = 0; i < d->eventFilters.size(); ++i) {
453 QAbstractNativeEventFilter *filter = d->eventFilters.at(i);
454 if (!filter)
455 continue;
456 if (filter->nativeEventFilter(eventType, message, result))
457 return true;
458 }
459 }
460 return false;
461}
462
463/*! \fn bool QAbstractEventDispatcher::registerEventNotifier(QWinEventNotifier *notifier)
464
465 This pure virtual method exists on windows only and has to be reimplemented by a Windows specific
466 event dispatcher implementation. \a notifier is the QWinEventNotifier instance to be registered.
467
468 The method should return true if the registration of \a notifier was successful, otherwise false.
469
470 QWinEventNotifier calls this method in it's constructor and there should never be a need to call this
471 method directly.
472
473 \sa QWinEventNotifier, unregisterEventNotifier()
474*/
475
476/*! \fn bool QAbstractEventDispatcher::unregisterEventNotifier(QWinEventNotifier *notifier)
477
478 This pure virtual method exists on windows only and has to be reimplemented by a Windows specific
479 event dispatcher implementation. \a notifier is the QWinEventNotifier instance to be unregistered.
480
481 QWinEventNotifier calls this method in it's destructor and there should never be a need to call this
482 method directly.
483
484 \sa QWinEventNotifier, registerEventNotifier()
485*/
486
487/*! \fn void QAbstractEventDispatcher::awake()
488
489 This signal is emitted after the event loop returns from a
490 function that could block.
491
492 \sa wakeUp(), aboutToBlock()
493*/
494
495/*! \fn void QAbstractEventDispatcher::aboutToBlock()
496
497 This signal is emitted before the event loop calls a function that
498 could block.
499
500 \sa awake()
501*/
502
503QT_END_NAMESPACE
504
505#include "moc_qabstracteventdispatcher.cpp"
506