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 #ifndef QEVENTDISPATCHER_WIN_P_H
41 #define QEVENTDISPATCHER_WIN_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists purely as an
48 // implementation detail.  This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include "QtCore/qabstracteventdispatcher.h"
55 #include "QtCore/qt_windows.h"
56 #include "QtCore/qhash.h"
57 
58 #include "qabstracteventdispatcher_p.h"
59 
60 QT_BEGIN_NAMESPACE
61 
62 class QWinEventNotifier;
63 class QEventDispatcherWin32Private;
64 
65 // forward declaration
66 LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
67 quint64 qt_msectime();
68 
69 class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher
70 {
71     Q_OBJECT
72     Q_DECLARE_PRIVATE(QEventDispatcherWin32)
73 
74 protected:
75     void createInternalHwnd();
76 
77 public:
78     explicit QEventDispatcherWin32(QObject *parent = 0);
79     ~QEventDispatcherWin32();
80 
81     bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags) override;
82     bool hasPendingEvents() override;
83 
84     void registerSocketNotifier(QSocketNotifier *notifier) override;
85     void unregisterSocketNotifier(QSocketNotifier *notifier) override;
86 
87     void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) override;
88     bool unregisterTimer(int timerId) override;
89     bool unregisterTimers(QObject *object) override;
90     QList<TimerInfo> registeredTimers(QObject *object) const override;
91 
92     bool registerEventNotifier(QWinEventNotifier *notifier) override;
93     void unregisterEventNotifier(QWinEventNotifier *notifier) override;
94     void activateEventNotifiers();
95 
96     int remainingTime(int timerId) override;
97 
98     void wakeUp() override;
99     void interrupt() override;
100     void flush() override;
101 
102     void startingUp() override;
103     void closingDown() override;
104 
105     bool event(QEvent *e) override;
106 
107     HWND internalHwnd();
108 
109 protected:
110     QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0);
111     virtual void sendPostedEvents();
112     void doUnregisterSocketNotifier(QSocketNotifier *notifier);
113     void doUnregisterEventNotifier(QWinEventNotifier *notifier);
114 
115 private:
116     friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
117     friend LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM);
118 };
119 
120 struct QSockNot {
121     QSocketNotifier *obj;
122     int fd;
123 };
124 typedef QHash<int, QSockNot *> QSNDict;
125 
126 struct QSockFd {
127     long event;
128     long mask;
129     bool selected;
130 
eventQSockFd131     explicit inline QSockFd(long ev = 0, long ma = 0) : event(ev), mask(ma), selected(false) { }
132 };
133 typedef QHash<int, QSockFd> QSFDict;
134 
135 struct WinTimerInfo {                           // internal timer info
136     QObject *dispatcher;
137     int timerId;
138     int interval;
139     Qt::TimerType timerType;
140     quint64 timeout;                            // - when to actually fire
141     QObject *obj;                               // - object to receive events
142     bool inTimerEvent;
143     UINT fastTimerId;
144 };
145 
146 class QZeroTimerEvent : public QTimerEvent
147 {
148 public:
QZeroTimerEvent(int timerId)149     explicit inline QZeroTimerEvent(int timerId)
150         : QTimerEvent(timerId)
151     { t = QEvent::ZeroTimerEvent; }
152 };
153 
154 typedef QList<WinTimerInfo*>  WinTimerVec;      // vector of TimerInfo structs
155 typedef QHash<int, WinTimerInfo*> WinTimerDict; // fast dict of timers
156 
157 class Q_CORE_EXPORT QEventDispatcherWin32Private : public QAbstractEventDispatcherPrivate
158 {
159     Q_DECLARE_PUBLIC(QEventDispatcherWin32)
160 public:
161     QEventDispatcherWin32Private();
162     ~QEventDispatcherWin32Private();
get(QEventDispatcherWin32 * q)163     static QEventDispatcherWin32Private *get(QEventDispatcherWin32 *q) { return q->d_func(); }
164 
165     DWORD threadId;
166 
167     QAtomicInt interrupt;
168 
169     // internal window handle used for socketnotifiers/timers/etc
170     HWND internalHwnd;
171     HHOOK getMessageHook;
172 
173     // for controlling when to send posted events
174     UINT_PTR sendPostedEventsTimerId;
175     QAtomicInt wakeUps;
176 
177     // timers
178     WinTimerVec timerVec;
179     WinTimerDict timerDict;
180     void registerTimer(WinTimerInfo *t);
181     void unregisterTimer(WinTimerInfo *t);
182     void sendTimerEvent(int timerId);
183 
184     // socket notifiers
185     QSNDict sn_read;
186     QSNDict sn_write;
187     QSNDict sn_except;
188     QSFDict active_fd;
189     bool activateNotifiersPosted;
190     void postActivateSocketNotifiers();
191     void doWsaAsyncSelect(int socket, long event);
192 
193     bool closingDown = false;
194 
195     bool winEventNotifierListModified = false;
196     HANDLE winEventNotifierActivatedEvent;
197     QList<QWinEventNotifier *> winEventNotifierList;
198     void activateEventNotifier(QWinEventNotifier * wen);
199 
200     QList<MSG> queuedUserInputEvents;
201     QList<MSG> queuedSocketEvents;
202 };
203 
204 QT_END_NAMESPACE
205 
206 #endif // QEVENTDISPATCHER_WIN_P_H
207