8#include <private/qsystemlibrary_p.h>
16#include <private/qthread_p.h>
20#ifndef TIME_KILL_SYNCHRONOUS
21# define TIME_KILL_SYNCHRONOUS 0x0100
25# define QS_RAWINPUT 0x0400
29# define WM_TOUCH 0x0240
33# define WM_GESTURE 0x0119
35#ifndef WM_GESTURENOTIFY
36# define WM_GESTURENOTIFY 0x011A
52#if !defined(DWORD_PTR) && !defined(Q_OS_WIN64)
53#define DWORD_PTR DWORD
60 using namespace std::chrono;
61 auto t = duration_cast<milliseconds>(steady_clock::now().time_since_epoch());
117 switch (WSAGETSELECTEVENT(lp)) {
135 QSNDict *sn_vec[4] = { &
d->sn_read, &
d->sn_write, &
d->sn_except, &
d->sn_read };
140 d->postActivateSocketNotifiers();
146 d->doWsaAsyncSelect(sn->
fd, 0);
149 d->postActivateSocketNotifiers();
153 const long eventCode = WSAGETSELECTEVENT(lp);
154 if ((sd.
mask & eventCode) != eventCode) {
155 sd.
mask |= eventCode;
170 if (!PeekMessage(&msg,
d->internalHwnd,
172 &&
d->queuedSocketEvents.isEmpty()) {
178 d->doWsaAsyncSelect(
it.key(), sd.
event);
185 d->activateNotifiersPosted =
false;
191 if (wp ==
d->sendPostedEventsTimerId)
192 q->sendPostedEvents();
194 d->sendTimerEvent(wp);
203 static const UINT
mask = QS_ALLEVENTS;
204 if (HIWORD(GetQueueStatus(
mask)) == 0)
205 q->sendPostedEvents();
207 d->startPostedEventsTimer();
211 return DefWindowProc(hwnd,
message, wp, lp);
221 USER_TIMER_MINIMUM, NULL);
242 className =
new wchar_t[qClassName.size() + 1];
251 wc.hInstance = GetModuleHandle(0);
254 wc.hbrBackground = 0;
255 wc.lpszMenuName = NULL;
257 atom = RegisterClass(&wc);
268 UnregisterClass(
className, GetModuleHandle(0));
280 HWND wnd = CreateWindow(
ctx->className,
290 qErrnoWarning(
"CreateWindow() for QEventDispatcherWin32 internal window failed");
294 SetWindowLongPtr(wnd, GWLP_USERDATA,
reinterpret_cast<LONG_PTR
>(eventDispatcher));
301 uint interval =
t->interval;
302 ULONG tolerance = TIMERV_DEFAULT_COALESCING;
303 switch (
t->timerType) {
314 if (interval >= 20000) {
316 }
else if (interval <= 20) {
321 tolerance = interval / 20;
332 interval = (interval + 500) / 1000 * 1000;
337 t->interval = interval;
350 uint interval =
t->interval;
351 if (interval == 0u) {
355 }
else if (tolerance == TIMERV_DEFAULT_COALESCING) {
365 ok = SetCoalescableTimer(
internalHwnd,
t->timerId, interval,
nullptr, tolerance);
371 qErrnoWarning(
"QEventDispatcherWin32::registerTimer: Failed to create a timer");
376 if (
t->interval == 0) {
377 QCoreApplicationPrivate::removePostedTimerEvent(
t->dispatcher,
t->timerId);
378 }
else if (
t->fastTimerId != 0) {
379 timeKillEvent(
t->fastTimerId);
380 QCoreApplicationPrivate::removePostedTimerEvent(
t->dispatcher,
t->timerId);
385 if (!
t->inTimerEvent)
392 if (
t && !
t->inTimerEvent) {
403 if (
t->timerId == -1) {
406 t->inTimerEvent =
false;
449#ifndef QT_NO_GESTURES
463 const bool wasInterrupted =
d->interrupt.fetchAndStoreRelaxed(
false);
473 auto threadData =
d->threadData.loadRelaxed();
477 QVarLengthArray<MSG> processedTimers;
478 while (!
d->interrupt.loadRelaxed()) {
483 msg =
d->queuedUserInputEvents.takeFirst();
486 msg =
d->queuedSocketEvents.takeFirst();
487 }
else if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
491 d->queuedUserInputEvents.append(msg);
497 d->queuedSocketEvents.append(msg);
500 }
else if (MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, MWMO_ALERTABLE)
510 d->startPostedEventsTimer();
515 if (msg.message == WM_TIMER) {
517 if (
d->internalHwnd == msg.hwnd && msg.wParam ==
d->sendPostedEventsTimerId)
522 for (
int i = 0; !found &&
i < processedTimers.count(); ++
i) {
523 const MSG processed = processedTimers.constData()[
i];
524 found = (processed.wParam == msg.wParam && processed.hwnd == msg.hwnd && processed.lParam == msg.lParam);
528 processedTimers.append(msg);
529 }
else if (msg.message == WM_QUIT) {
536 TranslateMessage(&msg);
537 DispatchMessage(&msg);
544 && !
d->interrupt.loadRelaxed()
546 && threadData->canWaitLocked());
549 MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
564 qWarning(
"QEventDispatcherWin32::registerSocketNotifier: invalid socket identifier");
568 qWarning(
"QEventDispatcherWin32: socket notifiers cannot be enabled from another thread");
574 QSNDict *sn_vec[3] = { &
d->sn_read, &
d->sn_write, &
d->sn_except };
580 if (dict->contains(sockfd)) {
581 const char *
t[] = {
"Read",
"Write",
"Exception" };
583 qWarning(
"QSocketNotifier: Multiple socket notifiers for "
590 dict->insert(sn->
fd, sn);
593 if (
d->sn_read.contains(sockfd))
594 event |= FD_READ | FD_CLOSE | FD_ACCEPT;
595 if (
d->sn_write.contains(sockfd))
596 event |= FD_WRITE | FD_CONNECT;
597 if (
d->sn_except.contains(sockfd))
601 if (
it !=
d->active_fd.
end()) {
604 d->doWsaAsyncSelect(sockfd, 0);
617 d->active_fd.insert(sockfd,
QSockFd(
event, FD_READ | FD_CLOSE | FD_ACCEPT | FD_WRITE
618 | FD_CONNECT | FD_OOB));
621 d->postActivateSocketNotifiers();
630 qWarning(
"QEventDispatcherWin32::unregisterSocketNotifier: invalid socket identifier");
634 qWarning(
"QEventDispatcherWin32: socket notifiers cannot be disabled from another thread");
649 if (
it !=
d->active_fd.
end()) {
652 d->doWsaAsyncSelect(sockfd, 0);
653 const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB };
656 d->active_fd.erase(
it);
659 d->postActivateSocketNotifiers();
663 QSNDict *sn_vec[3] = { &
d->sn_read, &
d->sn_write, &
d->sn_except };
669 dict->remove(sockfd);
676 if (timerId < 1 || interval < 0 || !
object) {
677 qWarning(
"QEventDispatcherWin32::registerTimer: invalid arguments");
681 qWarning(
"QEventDispatcherWin32::registerTimer: timers cannot be started from another thread");
695 t->timerId = timerId;
696 t->interval = interval;
697 t->timerType = timerType;
699 t->inTimerEvent =
false;
704 d->timerDict.insert(
t->timerId,
t);
711 qWarning(
"QEventDispatcherWin32::unregisterTimer: invalid argument");
715 qWarning(
"QEventDispatcherWin32::unregisterTimer: timers cannot be stopped from another thread");
726 d->unregisterTimer(
t);
734 qWarning(
"QEventDispatcherWin32::unregisterTimers: invalid argument");
738 qWarning(
"QEventDispatcherWin32::unregisterTimers: timers cannot be stopped from another thread");
744 if (
d->timerDict.isEmpty())
748 while (
it !=
d->timerDict.
end()) {
751 if (
t->obj ==
object) {
753 d->unregisterTimer(
t);
761QList<QEventDispatcherWin32::TimerInfo>
766 qWarning(
"QEventDispatcherWin32:registeredTimers: invalid argument");
767 return QList<TimerInfo>();
772 QList<TimerInfo>
list;
775 if (
t->obj ==
object)
785 qWarning(
"QEventDispatcherWin32::remainingTime: invalid argument");
801 qWarning(
"QEventDispatcherWin32::remainingTime: timer id %d not found", timerId);
810 if (
d->wakeUps.testAndSetRelaxed(0, 1)) {
813 qErrnoWarning(
"QEventDispatcherWin32::wakeUp: Failed to post a message");
820 d->interrupt.storeRelaxed(
true);
832 while (!
d->sn_read.isEmpty())
834 while (!
d->sn_write.isEmpty())
836 while (!
d->sn_except.isEmpty())
842 d->unregisterTimer(
t);
843 d->timerDict.clear();
845 d->closingDown =
true;
847 if (
d->sendPostedEventsTimerId != 0)
848 KillTimer(
d->internalHwnd,
d->sendPostedEventsTimerId);
849 d->sendPostedEventsTimerId = 0;
866 if (
t->timerId == -1) {
869 if (
t->interval == 0 &&
t->inTimerEvent) {
874 t->inTimerEvent =
false;
880 d->sendTimerEvent(
static_cast<const QTimerEvent*
>(e)->timerId());
892 if (
d->sendPostedEventsTimerId != 0)
893 KillTimer(
d->internalHwnd,
d->sendPostedEventsTimerId);
894 d->sendPostedEventsTimerId = 0;
897 d->wakeUps.storeRelaxed(0);
904 return d_func()->internalHwnd;
909#include "moc_qeventdispatcher_win_p.cpp"
DarwinBluetooth::LECBManagerNotifier * notifier
static QAbstractEventDispatcher * instance(QThread *thread=nullptr)
Returns a pointer to the event dispatcher object for the specified thread.
void aboutToBlock()
This signal is emitted before the event loop calls a function that could block.
bool filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
Sends message through the event filters that were set by installNativeEventFilter().
void awake()
This signal is emitted after the event loop returns from a function that could block.
void storeRelaxed(T newValue) noexcept
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data)
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static bool closingDown()
Returns true if the application objects are being destroyed; otherwise returns false.
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
void doWsaAsyncSelect(qintptr socket, long event)
bool activateNotifiersPosted
void sendTimerEvent(int timerId)
~QEventDispatcherWin32Private()
void registerTimer(WinTimerInfo *t)
UINT_PTR sendPostedEventsTimerId
void postActivateSocketNotifiers()
void unregisterTimer(WinTimerInfo *t)
void startPostedEventsTimer()
QEventDispatcherWin32Private()
void interrupt() override
Interrupts event dispatching.
void closingDown() override
bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags) override
Processes pending events that match flags until there are no more events to process.
virtual void sendPostedEvents()
bool unregisterTimer(int timerId) override
void startingUp() override
QList< TimerInfo > registeredTimers(QObject *object) const override
QEventDispatcherWin32(QObject *parent=nullptr)
bool unregisterTimers(QObject *object) override
Unregisters all the timers associated with the given object.
void wakeUp() override
\threadsafe
int remainingTime(int timerId) override
void doUnregisterSocketNotifier(QSocketNotifier *notifier)
void registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object) override
void registerSocketNotifier(QSocketNotifier *notifier) override
Registers notifier with the event loop.
void unregisterSocketNotifier(QSocketNotifier *notifier) override
Unregisters notifier from the event dispatcher.
bool event(QEvent *e) override
This virtual function receives events to an object and should return true if the event e was recogniz...
Type type() const
Returns the event type.
T value(const Key &key) const noexcept
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
QThread * thread() const
Returns the thread in which the object lives.
iterator erase(const_iterator i)
iterator find(const T &value)
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QThread * currentThread()
QSet< QString >::iterator it
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
static quint64 qt_msectime()
#define TIME_KILL_SYNCHRONOUS
@ SendPostedEventsTimerId
void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint, DWORD_PTR user, DWORD_PTR, DWORD_PTR)
@ WM_QT_ACTIVATENOTIFIERS
static bool isUserInputMessage(UINT message)
static ULONG calculateNextTimeout(WinTimerInfo *t, quint64 currentTime)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLuint GLsizei const GLchar * message
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLdouble GLdouble GLdouble GLdouble q
#define qUtf16Printable(string)
#define QStringLiteral(str)
unsigned long long quint64
static double currentTime()
const char className[16]
[1]
~QWindowsMessageWindowClassContext()
QWindowsMessageWindowClassContext()