Qt 4.8
qeventdispatcher_win.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qeventdispatcher_win_p.h"
43 
44 #include "qcoreapplication.h"
45 #include "qhash.h"
46 #include <private/qsystemlibrary_p.h>
47 #include "qpair.h"
48 #include "qset.h"
49 #include "qsocketnotifier.h"
50 #include "qvarlengtharray.h"
51 #include "qwineventnotifier_p.h"
52 
54 #include "qcoreapplication_p.h"
55 #include <private/qthread_p.h>
56 
58 
59 HINSTANCE qWinAppInst();
61 
62 #ifndef TIME_KILL_SYNCHRONOUS
63 # define TIME_KILL_SYNCHRONOUS 0x0100
64 #endif
65 
66 #ifndef QS_RAWINPUT
67 # ifdef Q_OS_WINCE
68 # define QS_RAWINPUT 0x0000
69 # else
70 # define QS_RAWINPUT 0x0400
71 # endif
72 #endif
73 
74 #ifndef WM_TOUCH
75 # define WM_TOUCH 0x0240
76 #endif
77 #ifndef QT_NO_GESTURES
78 #ifndef WM_GESTURE
79 # define WM_GESTURE 0x0119
80 #endif
81 #ifndef WM_GESTURENOTIFY
82 # define WM_GESTURENOTIFY 0x011A
83 #endif
84 #endif // QT_NO_GESTURES
85 
86 enum {
88  WM_QT_SENDPOSTEDEVENTS = WM_USER + 1,
90 };
91 
92 #if defined(Q_OS_WINCE)
94 #include <winsock.h>
95 // Asynchronous Winsocks ------------------------------------------
96 #ifndef QT_NO_THREAD
97 #include <qthread.h>
98 #include <qmap.h>
99 #include <qmutex.h>
101 
102 //#define QCE_ASYNC_DEBUG
103 
104 namespace {
105  class SocketAsyncHandler;
106 
107  class SocketAsyncHandler : public QThread
108  {
109  public:
110  SocketAsyncHandler();
111  ~SocketAsyncHandler();
112  void run();
113  void select(SOCKET sock, HWND handle, unsigned int msg, long ev);
114  void removeSelect(SOCKET sock);
115  void safeRemove(SOCKET sock);
116  private:
117  struct SockInfo {
118  HWND handle;
119  unsigned int msg;
120  long ev;
121  };
122  QMap<SOCKET, SockInfo> sockets;
123  QMutex mutex;
124  QWaitCondition cond;
125  bool supposedToDie;
126  };
127 
128  SocketAsyncHandler::SocketAsyncHandler()
129  : supposedToDie(false)
130  {
131  }
132 
133  SocketAsyncHandler::~SocketAsyncHandler()
134  {
135  mutex.lock();
136  supposedToDie = true;
137  mutex.unlock();
138  cond.wakeOne();
139  wait();
140  while (sockets.size() > 0)
141  removeSelect(sockets.begin().key());
142  }
143 
144  void SocketAsyncHandler::removeSelect(SOCKET sock)
145  {
146  if (!sockets.contains(sock))
147  return;
148  sockets.remove(sock);
149  return;
150  }
151 
152  void SocketAsyncHandler::safeRemove(SOCKET sock)
153  {
154  QMutexLocker locker(&mutex);
155  removeSelect(sock);
156  }
157 
158  void SocketAsyncHandler::select(SOCKET sock, HWND handle, unsigned int msg, long ev)
159  {
160  QMutexLocker locker(&mutex);
161 
162  if (sockets.contains(sock))
163  sockets.remove(sock);
164 
165  SockInfo info;
166  info.handle = handle;
167  info.msg = msg;
168  info.ev = ev;
169  sockets.insert(sock, info);
170  cond.wakeOne();
171  }
172 
174  {
175  do {
176  mutex.lock();
177 
178  while (!supposedToDie && sockets.isEmpty()) {
179  cond.wait(&mutex);
180  }
181 
182  if (supposedToDie) {
183  mutex.unlock();
184  break;
185  }
186 
187  // Copy current items to reduce lock time
188  // and to be able to use SendMessage
189  QMap<SOCKET, SockInfo> currentSockets = sockets;
190  mutex.unlock();
191 
192  fd_set readS, writeS, exS;
193  FD_ZERO(&readS);
194  FD_ZERO(&writeS);
195  FD_ZERO(&exS);
196 
197  int maxFd = 0;
198 
199  for (QMap<SOCKET, SockInfo>::iterator it = currentSockets.begin(); it != currentSockets.end(); ++it) {
200  const SockInfo &info = it.value();
201  int socket = it.key();
202  maxFd = qMax(maxFd, socket);
203 
204  if ((info.ev & FD_READ) || (info.ev & FD_CLOSE) || (info.ev & FD_ACCEPT))
205  FD_SET(socket, &readS);
206  if ((info.ev & FD_WRITE)|| (info.ev & FD_CONNECT))
207  FD_SET(socket, &writeS);
208  if (info.ev & FD_OOB)
209  FD_SET(socket, &exS);
210  }
211 
212  timeval timeout;
213  timeout.tv_sec = 0;
214  timeout.tv_usec = 50000;
215  int result = ::select(maxFd + 1, &readS, &writeS, &exS, &timeout);
216  if (result > 0) {
217  HWND handle;
218  unsigned int tmpMsg;
219  SOCKET sock;
220  HRESULT ret;
221  for (QMap<SOCKET, SockInfo>::const_iterator it = currentSockets.constBegin();
222  it != currentSockets.constEnd(); ++it) {
223  handle = (*it).handle;
224  tmpMsg = (*it).msg;
225  sock = it.key();
226  if (FD_ISSET(sock, &readS))
227  ret = SendMessage(handle, tmpMsg, sock, FD_READ);
228 
229  if (FD_ISSET(sock, &writeS))
230  ret = SendMessage(handle, tmpMsg, sock, FD_WRITE);
231 
232  if (FD_ISSET(sock, &exS))
233  ret = SendMessage(handle, tmpMsg, sock, FD_OOB);
234  }
235  }
236 
237 #ifdef QCE_ASYNC_DEBUG
238  else if (result == 0) { //timeout
239  qDebug(" WSAAsync select timeout");
240  } else if (result < 0) { // SocketError
241  // This might happen because of two reasons
242  // 1. We already closed a socket in between the copy and the select
243  // and thus select() returns an error
244  // 2. Something is really wrong, then
245  // ### Loop on all descriptors, try to select and remove the
246  // ### broken one.
247  qWarning("WSAAsync select error %d", WSAGetLastError());
248  }
249 #endif
250  } while(true);
251  }
252 } // namespace
253 
254 Q_GLOBAL_STATIC(SocketAsyncHandler, qt_async_handler)
255 
256 int WSAAsyncSelect(SOCKET sock, HWND handle, unsigned int msg, long ev)
257 {
258  if (sock == 0 || handle == 0 || handle == INVALID_HANDLE_VALUE) {
259  WSASetLastError(WSAEINVAL);
260  return SOCKET_ERROR;
261  }
262 
263  if (msg == 0 && ev == 0)
264  qt_async_handler()->safeRemove(sock);
265  else
266  qt_async_handler()->select(sock, handle, msg, ev);
267 
268  qt_async_handler()->start(QThread::LowPriority);
269  WSASetLastError(0);
270  return 0;
271 }
272 #else // QT_NO_THREAD
273 int WSAAsyncSelect(SOCKET, HWND, unsigned int, long)
274 {
275  return SOCKET_ERROR;
276 }
277 #endif
278 #endif // Q_OS_WINCE
279 
281 
282 struct QSockNot {
283  QSocketNotifier *obj;
284  int fd;
285 };
287 
288 struct WinTimerInfo { // internal timer info
290  int timerId;
291  int interval;
292  QObject *obj; // - object to receive events
295 };
296 
298 {
299 public:
300  inline QZeroTimerEvent(int timerId)
301  : QTimerEvent(timerId)
302  { t = QEvent::ZeroTimerEvent; }
303 };
304 
305 typedef QList<WinTimerInfo*> WinTimerVec; // vector of TimerInfo structs
306 typedef QHash<int, WinTimerInfo*> WinTimerDict; // fast dict of timers
307 
308 #if !defined(DWORD_PTR) && !defined(Q_WS_WIN64)
309 #define DWORD_PTR DWORD
310 #endif
311 
312 typedef MMRESULT(WINAPI *ptimeSetEvent)(UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT);
313 typedef MMRESULT(WINAPI *ptimeKillEvent)(UINT);
314 
317 
318 LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
319 
320 static void resolveTimerAPI()
321 {
322  static bool triedResolve = false;
323  if (!triedResolve) {
324 #ifdef Q_OS_WINCE
325  QSystemLibrary library(QLatin1String("Mmtimer"));
326 #else
327  QSystemLibrary library(QLatin1String("winmm"));
328 #endif
329  if (library.load()) {
330  qtimeSetEvent = (ptimeSetEvent)library.resolve("timeSetEvent");
331  qtimeKillEvent = (ptimeKillEvent)library.resolve("timeKillEvent");
332  }
333 
334  triedResolve = true;
335  }
336 }
337 
338 
340 {
342 public:
345 
346  DWORD threadId;
347 
348  bool interrupt;
349 
350  // internal window handle used for socketnotifiers/timers/etc
353 
354  // for controlling when to send posted events
356  int lastSerialNumber, sendPostedEventsWindowsTimerId;
358 
359  // timers
362  void registerTimer(WinTimerInfo *t);
363  void unregisterTimer(WinTimerInfo *t, bool closingDown = false);
364  void sendTimerEvent(int timerId);
365 
366  // socket notifiers
370  void doWsaAsyncSelect(int socket);
371 
373  void activateEventNotifier(QWinEventNotifier * wen);
374 
377 };
378 
380  : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0),
381  serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), wakeUps(0)
382 {
383  resolveTimerAPI();
384 }
385 
387 {
388  if (internalHwnd)
389  DestroyWindow(internalHwnd);
390  QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
391  UnregisterClass((wchar_t*)className.utf16(), qWinAppInst());
392 }
393 
395 {
397  QCoreApplication::sendEvent(wen, &event);
398 }
399 
400 // ### Qt 5: remove
401 Q_CORE_EXPORT bool winPeekMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin,
402  UINT wMsgFilterMax, UINT wRemoveMsg)
403 {
404  return PeekMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
405 }
406 
407 // ### Qt 5: remove
408 Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
409 {
410  return PostMessage(hWnd, msg, wParam, lParam);
411 }
412 
413 // ### Qt 5: remove
414 Q_CORE_EXPORT bool winGetMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin,
415  UINT wMsgFilterMax)
416 {
417  return GetMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax);
418 }
419 
420 // This function is called by a workerthread
421 void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/, DWORD_PTR user, DWORD_PTR /*reserved*/, DWORD_PTR /*reserved*/)
422 {
423  if (!timerId) // sanity check
424  return;
425  WinTimerInfo *t = (WinTimerInfo*)user;
426  Q_ASSERT(t);
428 }
429 
430 LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
431 {
432  if (message == WM_NCCREATE)
433  return true;
434 
435  MSG msg;
436  msg.hwnd = hwnd;
437  msg.message = message;
438  msg.wParam = wp;
439  msg.lParam = lp;
441  long result;
442  if (!app) {
443  if (message == WM_TIMER)
444  KillTimer(hwnd, wp);
445  return 0;
446  } else if (app->filterEvent(&msg, &result)) {
447  return result;
448  }
449 
450 #ifdef GWLP_USERDATA
451  QEventDispatcherWin32 *q = (QEventDispatcherWin32 *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
452 #else
453  QEventDispatcherWin32 *q = (QEventDispatcherWin32 *) GetWindowLong(hwnd, GWL_USERDATA);
454 #endif
456  if (q != 0)
457  d = q->d_func();
458 
459  if (message == WM_QT_SOCKETNOTIFIER) {
460  // socket notifier message
461  int type = -1;
462  switch (WSAGETSELECTEVENT(lp)) {
463  case FD_READ:
464  case FD_CLOSE:
465  case FD_ACCEPT:
466  type = 0;
467  break;
468  case FD_WRITE:
469  case FD_CONNECT:
470  type = 1;
471  break;
472  case FD_OOB:
473  type = 2;
474  break;
475  }
476  if (type >= 0) {
477  Q_ASSERT(d != 0);
478  QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except };
479  QSNDict *dict = sn_vec[type];
480 
481  QSockNot *sn = dict ? dict->value(wp) : 0;
482  if (sn) {
484  QCoreApplication::sendEvent(sn->obj, &event);
485  }
486  }
487  return 0;
488  } else if (message == WM_QT_SENDPOSTEDEVENTS
489  // we also use a Windows timer to send posted events when the message queue is full
490  || (message == WM_TIMER
492  && wp == (uint)d->sendPostedEventsWindowsTimerId)) {
493  int localSerialNumber = d->serialNumber;
494  if (localSerialNumber != d->lastSerialNumber) {
495  d->lastSerialNumber = localSerialNumber;
497  }
498  return 0;
499  } else if (message == WM_TIMER) {
500  Q_ASSERT(d != 0);
501  d->sendTimerEvent(wp);
502  return 0;
503  }
504 
505  return DefWindowProc(hwnd, message, wp, lp);
506 }
507 
508 static inline UINT inputTimerMask()
509 {
510  UINT result = QS_TIMER | QS_INPUT | QS_RAWINPUT;
511  // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of
512  // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8.
513 #if defined(_MSC_VER) && _MSC_VER >= 1700
515  result &= ~(QS_TOUCH | QS_POINTER);
516 #endif // _MSC_VER >= 1700
517  return result;
518 }
519 
520 LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
521 {
522  if (wp == PM_REMOVE) {
524  Q_ASSERT(q != 0);
525  if (q) {
526  MSG *msg = (MSG *) lp;
527  QEventDispatcherWin32Private *d = q->d_func();
528  int localSerialNumber = d->serialNumber;
529  static const UINT mask = inputTimerMask();
530  if (HIWORD(GetQueueStatus(mask)) == 0) {
531  // no more input or timer events in the message queue, we can allow posted events to be sent normally now
532  if (d->sendPostedEventsWindowsTimerId != 0) {
533  // stop the timer to send posted events, since we now allow the WM_QT_SENDPOSTEDEVENTS message
536  }
537  (void) d->wakeUps.fetchAndStoreRelease(0);
538  if (localSerialNumber != d->lastSerialNumber
539  // if this message IS the one that triggers sendPostedEvents(), no need to post it again
540  && (msg->hwnd != d->internalHwnd
541  || msg->message != WM_QT_SENDPOSTEDEVENTS)) {
542  PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);
543  }
544  } else if (d->sendPostedEventsWindowsTimerId == 0
545  && localSerialNumber != d->lastSerialNumber) {
546  // start a special timer to continue delivering posted events while
547  // there are still input and timer messages in the message queue
550  0, // we specify zero, but Windows uses USER_TIMER_MINIMUM
551  NULL);
552  // we don't check the return value of SetTimer()... if creating the timer failed, there's little
553  // we can do. we just have to accept that posted events will be starved
554  }
555  }
556  }
557 #ifdef Q_OS_WINCE
558  Q_UNUSED(code);
559  return 0;
560 #else
561  return CallNextHookEx(0, code, wp, lp);
562 #endif
563 }
564 
565 static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
566 {
567  // make sure that multiple Qt's can coexist in the same process
568  QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
569 
570  WNDCLASS wc;
571  wc.style = 0;
572  wc.lpfnWndProc = qt_internal_proc;
573  wc.cbClsExtra = 0;
574  wc.cbWndExtra = 0;
575  wc.hInstance = qWinAppInst();
576  wc.hIcon = 0;
577  wc.hCursor = 0;
578  wc.hbrBackground = 0;
579  wc.lpszMenuName = NULL;
580  wc.lpszClassName = reinterpret_cast<const wchar_t *> (className.utf16());
581 
582  RegisterClass(&wc);
583  HWND wnd = CreateWindow(wc.lpszClassName, // classname
584  wc.lpszClassName, // window name
585  0, // style
586  0, 0, 0, 0, // geometry
587  0, // parent
588  0, // menu handle
589  qWinAppInst(), // application
590  0); // windows creation data.
591 
592  if (!wnd) {
593  qWarning("QEventDispatcher: Failed to create QEventDispatcherWin32 internal window: %d\n", (int)GetLastError());
594  }
595 
596 #ifdef GWLP_USERDATA
597  SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)eventDispatcher);
598 #else
599  SetWindowLong(wnd, GWL_USERDATA, (LONG)eventDispatcher);
600 #endif
601 
602  return wnd;
603 }
604 
606 {
608 
610 
611  int ok = 0;
612  if (t->interval > 20 || !t->interval || !qtimeSetEvent) {
613  ok = 1;
614  if (!t->interval) // optimization for single-shot-zero-timer
616  else
617  ok = SetTimer(internalHwnd, t->timerId, (uint) t->interval, 0);
618  } else {
620  TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
621  if (ok == 0) { // fall back to normal timer if no more multimedia timers available
622  ok = SetTimer(internalHwnd, t->timerId, (uint) t->interval, 0);
623  }
624  }
625 
626  if (ok == 0)
627  qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer");
628 }
629 
631 {
632  // mark timer as unused
633  if (!QObjectPrivate::get(t->obj)->inThreadChangeEvent && !closingDown)
635 
636  if (t->interval == 0) {
638  } else if (t->fastTimerId != 0) {
641  } else if (internalHwnd) {
642  KillTimer(internalHwnd, t->timerId);
643  }
644  delete t;
645 }
646 
648 {
649  WinTimerInfo *t = timerDict.value(timerId);
650  if (t && !t->inTimerEvent) {
651  // send event, but don't allow it to recurse
652  t->inTimerEvent = true;
653 
654  QTimerEvent e(t->timerId);
656 
657  // timer could have been removed
658  t = timerDict.value(timerId);
659  if (t) {
660  t->inTimerEvent = false;
661  }
662  }
663 }
664 
666 {
668  int sn_event = 0;
669  if (sn_read.contains(socket))
670  sn_event |= FD_READ | FD_CLOSE | FD_ACCEPT;
671  if (sn_write.contains(socket))
672  sn_event |= FD_WRITE | FD_CONNECT;
673  if (sn_except.contains(socket))
674  sn_event |= FD_OOB;
675  // BoundsChecker may emit a warning for WSAAsyncSelect when sn_event == 0
676  // This is a BoundsChecker bug and not a Qt bug
677  WSAAsyncSelect(socket, internalHwnd, sn_event ? unsigned(WM_QT_SOCKETNOTIFIER) : unsigned(0), sn_event);
678 }
679 
681 {
683 
684  Q_ASSERT(!d->internalHwnd);
685  if (d->internalHwnd)
686  return;
687  d->internalHwnd = qt_create_internal_window(this);
688 
689 #ifndef Q_OS_WINCE
690  // setup GetMessage hook needed to drive our posted events
691  d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
692  if (!d->getMessageHook) {
693  qFatal("Qt: INTERNALL ERROR: failed to install GetMessage hook");
694  }
695 #endif
696 
697  // register all socket notifiers
698  QList<int> sockets = (d->sn_read.keys().toSet()
699  + d->sn_write.keys().toSet()
700  + d->sn_except.keys().toSet()).toList();
701  for (int i = 0; i < sockets.count(); ++i)
702  d->doWsaAsyncSelect(sockets.at(i));
703 
704  // start all normal timers
705  for (int i = 0; i < d->timerVec.count(); ++i)
706  d->registerTimer(d->timerVec.at(i));
707 
708  // trigger a call to sendPostedEvents()
709  wakeUp();
710 }
711 
714 {
715 }
716 
718 {
719 }
720 
721 bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
722 {
724 
725  if (!d->internalHwnd)
727 
728  d->interrupt = false;
729  emit awake();
730 
731  bool canWait;
732  bool retVal = false;
733  bool seenWM_QT_SENDPOSTEDEVENTS = false;
734  bool needWM_QT_SENDPOSTEDEVENTS = false;
735  do {
736  DWORD waitRet = 0;
737  HANDLE pHandles[MAXIMUM_WAIT_OBJECTS - 1];
738  QVarLengthArray<MSG> processedTimers;
739  while (!d->interrupt) {
740  DWORD nCount = d->winEventNotifierList.count();
741  Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);
742 
743  MSG msg;
744  bool haveMessage;
745 
746  if (!(flags & QEventLoop::ExcludeUserInputEvents) && !d->queuedUserInputEvents.isEmpty()) {
747  // process queued user input events
748  haveMessage = true;
749  msg = d->queuedUserInputEvents.takeFirst();
750  } else if(!(flags & QEventLoop::ExcludeSocketNotifiers) && !d->queuedSocketEvents.isEmpty()) {
751  // process queued socket events
752  haveMessage = true;
753  msg = d->queuedSocketEvents.takeFirst();
754  } else {
755  haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
756  if (haveMessage && (flags & QEventLoop::ExcludeUserInputEvents)
757  && ((msg.message >= WM_KEYFIRST
758  && msg.message <= WM_KEYLAST)
759  || (msg.message >= WM_MOUSEFIRST
760  && msg.message <= WM_MOUSELAST)
761  || msg.message == WM_MOUSEWHEEL
762  || msg.message == WM_MOUSEHWHEEL
763  || msg.message == WM_TOUCH
764 #ifndef QT_NO_GESTURES
765  || msg.message == WM_GESTURE
766  || msg.message == WM_GESTURENOTIFY
767 #endif
768  || msg.message == WM_CLOSE)) {
769  // queue user input events for later processing
770  haveMessage = false;
771  d->queuedUserInputEvents.append(msg);
772  }
773  if (haveMessage && (flags & QEventLoop::ExcludeSocketNotifiers)
774  && (msg.message == WM_QT_SOCKETNOTIFIER && msg.hwnd == d->internalHwnd)) {
775  // queue socket events for later processing
776  haveMessage = false;
777  d->queuedSocketEvents.append(msg);
778  }
779  }
780  if (!haveMessage) {
781  // no message - check for signalled objects
782  for (int i=0; i<(int)nCount; i++)
783  pHandles[i] = d->winEventNotifierList.at(i)->handle();
784  waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, 0, QS_ALLINPUT, MWMO_ALERTABLE);
785  if ((haveMessage = (waitRet == WAIT_OBJECT_0 + nCount))) {
786  // a new message has arrived, process it
787  continue;
788  }
789  }
790  if (haveMessage) {
791 #ifdef Q_OS_WINCE
792  // WinCE doesn't support hooks at all, so we have to call this by hand :(
793  (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg);
794 #endif
795 
796  if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
797  if (seenWM_QT_SENDPOSTEDEVENTS) {
798  // when calling processEvents() "manually", we only want to send posted
799  // events once
800  needWM_QT_SENDPOSTEDEVENTS = true;
801  continue;
802  }
803  seenWM_QT_SENDPOSTEDEVENTS = true;
804  } else if (msg.message == WM_TIMER) {
805  // avoid live-lock by keeping track of the timers we've already sent
806  bool found = false;
807  for (int i = 0; !found && i < processedTimers.count(); ++i) {
808  const MSG processed = processedTimers.constData()[i];
809  found = (processed.wParam == msg.wParam && processed.hwnd == msg.hwnd && processed.lParam == msg.lParam);
810  }
811  if (found)
812  continue;
813  processedTimers.append(msg);
814  } else if (msg.message == WM_QUIT) {
817  return false;
818  }
819 
820  if (!filterEvent(&msg)) {
821  TranslateMessage(&msg);
822  DispatchMessage(&msg);
823  }
824  } else if (waitRet < WAIT_OBJECT_0 + nCount) {
825  d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
826  } else {
827  // nothing todo so break
828  break;
829  }
830  retVal = true;
831  }
832 
833  // still nothing - wait for message or signalled objects
834  canWait = (!retVal
835  && !d->interrupt
836  && (flags & QEventLoop::WaitForMoreEvents));
837  if (canWait) {
838  DWORD nCount = d->winEventNotifierList.count();
839  Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);
840  for (int i=0; i<(int)nCount; i++)
841  pHandles[i] = d->winEventNotifierList.at(i)->handle();
842 
843  emit aboutToBlock();
844  waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
845  emit awake();
846  if (waitRet < WAIT_OBJECT_0 + nCount) {
847  d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
848  retVal = true;
849  }
850  }
851  } while (canWait);
852 
853  if (!seenWM_QT_SENDPOSTEDEVENTS && (flags & QEventLoop::EventLoopExec) == 0) {
854  // when called "manually", always send posted events
855  QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
856  }
857 
858  if (needWM_QT_SENDPOSTEDEVENTS)
859  PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);
860 
861  return retVal;
862 }
863 
865 {
866  MSG msg;
867  return qGlobalPostedEventsCount() || PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
868 }
869 
871 {
872  Q_ASSERT(notifier);
873  int sockfd = notifier->socket();
874  int type = notifier->type();
875 #ifndef QT_NO_DEBUG
876  if (sockfd < 0) {
877  qWarning("QSocketNotifier: Internal error");
878  return;
879  } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
880  qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
881  return;
882  }
883 #endif
884 
886  QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except };
887  QSNDict *dict = sn_vec[type];
888 
889  if (QCoreApplication::closingDown()) // ### d->exitloop?
890  return; // after sn_cleanup, don't reinitialize.
891 
892  if (dict->contains(sockfd)) {
893  const char *t[] = { "Read", "Write", "Exception" };
894  /* Variable "socket" below is a function pointer. */
895  qWarning("QSocketNotifier: Multiple socket notifiers for "
896  "same socket %d and type %s", sockfd, t[type]);
897  }
898 
899  QSockNot *sn = new QSockNot;
900  sn->obj = notifier;
901  sn->fd = sockfd;
902  dict->insert(sn->fd, sn);
903 
904  if (d->internalHwnd)
905  d->doWsaAsyncSelect(sockfd);
906 }
907 
909 {
910  Q_ASSERT(notifier);
911  int sockfd = notifier->socket();
912  int type = notifier->type();
913 #ifndef QT_NO_DEBUG
914  if (sockfd < 0) {
915  qWarning("QSocketNotifier: Internal error");
916  return;
917  } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
918  qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
919  return;
920  }
921 #endif
922 
924  QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except };
925  QSNDict *dict = sn_vec[type];
926  QSockNot *sn = dict->value(sockfd);
927  if (!sn)
928  return;
929 
930  dict->remove(sockfd);
931  delete sn;
932 
933  if (d->internalHwnd)
934  d->doWsaAsyncSelect(sockfd);
935 }
936 
937 void QEventDispatcherWin32::registerTimer(int timerId, int interval, QObject *object)
938 {
939  if (timerId < 1 || interval < 0 || !object) {
940  qWarning("QEventDispatcherWin32::registerTimer: invalid arguments");
941  return;
942  } else if (object->thread() != thread() || thread() != QThread::currentThread()) {
943  qWarning("QObject::startTimer: timers cannot be started from another thread");
944  return;
945  }
946 
948 
949  register WinTimerInfo *t = new WinTimerInfo;
950  t->dispatcher = this;
951  t->timerId = timerId;
952  t->interval = interval;
953  t->obj = object;
954  t->inTimerEvent = false;
955  t->fastTimerId = 0;
956 
957  if (d->internalHwnd)
958  d->registerTimer(t);
959 
960  d->timerVec.append(t); // store in timer vector
961  d->timerDict.insert(t->timerId, t); // store timers in dict
962 }
963 
965 {
966  if (timerId < 1) {
967  qWarning("QEventDispatcherWin32::unregisterTimer: invalid argument");
968  return false;
969  }
970  QThread *currentThread = QThread::currentThread();
971  if (thread() != currentThread) {
972  qWarning("QObject::killTimer: timers cannot be stopped from another thread");
973  return false;
974  }
975 
977  if (d->timerVec.isEmpty() || timerId <= 0)
978  return false;
979 
980  WinTimerInfo *t = d->timerDict.value(timerId);
981  if (!t)
982  return false;
983 
984  d->timerDict.remove(t->timerId);
985  d->timerVec.removeAll(t);
986  d->unregisterTimer(t);
987  return true;
988 }
989 
991 {
992  if (!object) {
993  qWarning("QEventDispatcherWin32::unregisterTimers: invalid argument");
994  return false;
995  }
996  QThread *currentThread = QThread::currentThread();
997  if (object->thread() != thread() || thread() != currentThread) {
998  qWarning("QObject::killTimers: timers cannot be stopped from another thread");
999  return false;
1000  }
1001 
1003  if (d->timerVec.isEmpty())
1004  return false;
1005  register WinTimerInfo *t;
1006  for (int i=0; i<d->timerVec.size(); i++) {
1007  t = d->timerVec.at(i);
1008  if (t && t->obj == object) { // object found
1009  d->timerDict.remove(t->timerId);
1010  d->timerVec.removeAt(i);
1011  d->unregisterTimer(t);
1012  --i;
1013  }
1014  }
1015  return true;
1016 }
1017 
1020 {
1021  if (!object) {
1022  qWarning("QEventDispatcherWin32:registeredTimers: invalid argument");
1023  return QList<TimerInfo>();
1024  }
1025 
1026  Q_D(const QEventDispatcherWin32);
1027  QList<TimerInfo> list;
1028  for (int i = 0; i < d->timerVec.size(); ++i) {
1029  const WinTimerInfo *t = d->timerVec.at(i);
1030  if (t && t->obj == object)
1031  list << TimerInfo(t->timerId, t->interval);
1032  }
1033  return list;
1034 }
1035 
1037 {
1038  if (!notifier) {
1039  qWarning("QWinEventNotifier: Internal error");
1040  return false;
1041  } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
1042  qWarning("QWinEventNotifier: event notifiers cannot be enabled from another thread");
1043  return false;
1044  }
1045 
1047 
1048  if (d->winEventNotifierList.contains(notifier))
1049  return true;
1050 
1051  if (d->winEventNotifierList.count() >= MAXIMUM_WAIT_OBJECTS - 2) {
1052  qWarning("QWinEventNotifier: Cannot have more than %d enabled at one time", MAXIMUM_WAIT_OBJECTS - 2);
1053  return false;
1054  }
1055  d->winEventNotifierList.append(notifier);
1056  return true;
1057 }
1058 
1060 {
1061  if (!notifier) {
1062  qWarning("QWinEventNotifier: Internal error");
1063  return;
1064  } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
1065  qWarning("QWinEventNotifier: event notifiers cannot be disabled from another thread");
1066  return;
1067  }
1068 
1070 
1071  int i = d->winEventNotifierList.indexOf(notifier);
1072  if (i != -1)
1073  d->winEventNotifierList.takeAt(i);
1074 }
1075 
1077 {
1079  //### this could break if events are removed/added in the activation
1080  for (int i=0; i<d->winEventNotifierList.count(); i++) {
1081 #if !defined(Q_OS_WINCE)
1082  if (WaitForSingleObjectEx(d->winEventNotifierList.at(i)->handle(), 0, TRUE) == WAIT_OBJECT_0)
1083  d->activateEventNotifier(d->winEventNotifierList.at(i));
1084 #else
1085  if (WaitForSingleObject(d->winEventNotifierList.at(i)->handle(), 0) == WAIT_OBJECT_0)
1086  d->activateEventNotifier(d->winEventNotifierList.at(i));
1087 #endif
1088  }
1089 }
1090 
1092 {
1094  d->serialNumber.ref();
1095  if (d->internalHwnd && d->wakeUps.testAndSetAcquire(0, 1)) {
1096  // post a WM_QT_SENDPOSTEDEVENTS to this thread if there isn't one already pending
1097  PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);
1098  }
1099 }
1100 
1102 {
1104  d->interrupt = true;
1105  wakeUp();
1106 }
1107 
1109 { }
1110 
1112 { }
1113 
1115 {
1117 
1118  // clean up any socketnotifiers
1119  while (!d->sn_read.isEmpty())
1120  unregisterSocketNotifier((*(d->sn_read.begin()))->obj);
1121  while (!d->sn_write.isEmpty())
1122  unregisterSocketNotifier((*(d->sn_write.begin()))->obj);
1123  while (!d->sn_except.isEmpty())
1124  unregisterSocketNotifier((*(d->sn_except.begin()))->obj);
1125 
1126  // clean up any timers
1127  for (int i = 0; i < d->timerVec.count(); ++i)
1128  d->unregisterTimer(d->timerVec.at(i), true);
1129  d->timerVec.clear();
1130  d->timerDict.clear();
1131 
1132 #ifndef Q_OS_WINCE
1133  if (d->getMessageHook)
1134  UnhookWindowsHookEx(d->getMessageHook);
1135  d->getMessageHook = 0;
1136 #endif
1137 }
1138 
1140 {
1142  if (e->type() == QEvent::ZeroTimerEvent) {
1143  QZeroTimerEvent *zte = static_cast<QZeroTimerEvent*>(e);
1144  WinTimerInfo *t = d->timerDict.value(zte->timerId());
1145  if (t) {
1146  t->inTimerEvent = true;
1147 
1148  QTimerEvent te(zte->timerId());
1150 
1151  t = d->timerDict.value(zte->timerId());
1152  if (t) {
1153  if (t->interval == 0 && t->inTimerEvent) {
1154  // post the next zero timer event as long as the timer was not restarted
1156  }
1157 
1158  t->inTimerEvent = false;
1159  }
1160  }
1161  return true;
1162  } else if (e->type() == QEvent::Timer) {
1163  QTimerEvent *te = static_cast<QTimerEvent*>(e);
1164  d->sendTimerEvent(te->timerId());
1165  }
1167 }
1168 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
T qobject_cast(QObject *object)
Definition: qobject.h:375
#define WM_MOUSEWHEEL
Definition: qt_windows.h:116
double d
Definition: qnumeric_p.h:62
QSocketNotifier * obj
#define QT_NO_GESTURES
const T * constData() const
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data)
virtual void run()
The starting point for the thread.
Definition: qthread.cpp:628
int type
Definition: qmetatype.cpp:239
bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags)
Processes pending events that match flags until there are no more events to process.
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
bool filterEvent(void *message)
Sends message through the event filter that was set by setEventFilter().
static mach_timebase_info_data_t info
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void unregisterTimer(WinTimerInfo *t, bool closingDown=false)
The QMutex class provides access serialization between threads.
Definition: qmutex.h:60
EventRef event
int remove(const Key &key)
Removes all the items that have the key from the hash.
Definition: qhash.h:784
void registerSocketNotifier(QSocketNotifier *notifier)
Registers notifier with the event loop.
The QAtomicInt class provides platform-independent atomic operations on integers. ...
Definition: qatomic.h:55
#define WM_MOUSEHWHEEL
Definition: qt_windows.h:119
#define it(className, varName)
static UINT inputTimerMask()
static void postEvent(QObject *receiver, QEvent *event)
Adds the event event, with the object receiver as the receiver of the event, to an event queue and re...
LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
static QAbstractEventDispatcher * instance(QThread *thread=0)
Returns a pointer to the event dispatcher object for the specified thread.
#define WM_GESTURENOTIFY
MMRESULT(WINAPI * ptimeKillEvent)(UINT)
static ptimeKillEvent qtimeKillEvent
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *)
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint, DWORD_PTR user, DWORD_PTR, DWORD_PTR)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
MMRESULT(WINAPI * ptimeSetEvent)(UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT)
quint16 u
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
void interrupt()
Interrupts event dispatching; i.
static const WinVersion WindowsVersion
the version of the Windows operating system on which the application is run (Windows only) ...
Definition: qglobal.h:1613
The QString class provides a Unicode character string.
Definition: qstring.h:83
QEventDispatcherWin32(QObject *parent=0)
static QList< QVariant > toList(char **buf, int count, T *=0)
Definition: qsql_ibase.cpp:472
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define WAIT_OBJECT_0
QPair< int, int > TimerInfo
Typedef for QPair<int, int>.
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
bool load(bool onlySystemDirectory=true)
#define Q_D(Class)
Definition: qglobal.h:2482
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
static QObjectPrivate * get(QObject *o)
Definition: qobject_p.h:177
QThreadData * threadData
Definition: qobject_p.h:195
void append(const T &t)
#define TIME_KILL_SYNCHRONOUS
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
const char * className
Definition: qwizard.cpp:137
Type type() const
Returns the socket event type specified to the constructor.
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void wakeUp()
Wakes up the event loop.
bool event(QEvent *e)
This virtual function receives events to an object and should return true if the event e was recogniz...
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
The QSocketNotifier class provides support for monitoring activity on a file descriptor.
#define Q_Q(Class)
Definition: qglobal.h:2483
void unregisterSocketNotifier(QSocketNotifier *notifier)
Unregisters notifier from the event dispatcher.
Q_CORE_EXPORT void qDebug(const char *,...)
static void quit()
Tells the application to exit with return code 0 (success).
static QThread * currentThread()
Returns a pointer to a QThread which manages the currently executing thread.
Definition: qthread.cpp:419
#define QT_WIN_CALLBACK
Definition: qglobal.h:1178
#define QS_RAWINPUT
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
Q_CORE_EXPORT bool winGetMessage(MSG *msg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
void awake()
This signal is emitted after the event loop returns from a function that could block.
QList< TimerInfo > registeredTimers(QObject *object) const
Returns a list of registered timers for object.
static ptimeSetEvent qtimeSetEvent
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
#define emit
Definition: qobjectdefs.h:76
QList< QWinEventNotifier * > winEventNotifierList
Q_CORE_EXPORT void qWarning(const char *,...)
uint inThreadChangeEvent
Definition: qobject.h:103
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
Definition: qcoreevent.h:346
unsigned int uint
Definition: qglobal.h:996
Q_CORE_EXPORT bool winPeekMessage(MSG *msg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
QList< WinTimerInfo * > WinTimerVec
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
bool hasPendingEvents()
Returns true if there is an event waiting; otherwise returns false.
#define WM_GESTURE
#define DWORD_PTR
void activateEventNotifier(QWinEventNotifier *wen)
QHash< int, QSockNot * > QSNDict
void * HANDLE
Definition: qnamespace.h:1671
int WSAAsyncSelect(SOCKET sock, HWND handle, unsigned int msg, long ev)
int count() const
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the map.
Definition: qmap.h:374
iterator begin()
Returns an STL-style iterator pointing to the first item in the map.
Definition: qmap.h:372
#define TRUE
Synonym for true.
Definition: qglobal.h:1018
HINSTANCE qWinAppInst()
Q_CORE_EXPORT void qFatal(const char *,...)
The QMap::const_iterator class provides an STL-style const iterator for QMap and QMultiMap.
Definition: qmap.h:301
The QCoreApplication class provides an event loop for console Qt applications.
struct tagMSG MSG
long HRESULT
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:380
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
void aboutToBlock()
This signal is emitted before the event loop calls a function that could block.
void * resolve(const char *symbol)
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
static bool closingDown()
Returns true if the application objects are being destroyed; otherwise returns false.
bool unregisterTimer(int timerId)
Unregisters the timer with the given timerId.
#define Q_CORE_EXPORT
Definition: qglobal.h:1449
The QMap::iterator class provides an STL-style non-const iterator for QMap and QMultiMap.
Definition: qmap.h:233
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:341
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:375
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
static void removePostedTimerEvent(QObject *object, int timerId)
friend LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM)
#define MWMO_ALERTABLE
QObject * parent
Definition: qobject.h:92
QFuture< T > run(Function function,...)
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
#define WSAGETSELECTEVENT(lParam)
void unregisterEventNotifier(QWinEventNotifier *notifier)
QZeroTimerEvent(int timerId)
QThread * thread() const
Returns the thread in which the object lives.
Definition: qobject.cpp:1419
Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
static void resolveTimerAPI()
bool filterEvent(void *message, long *result)
Sends message through the event filter that was set by setEventFilter().
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
The QThread class provides a platform-independent way to manage threads.
Definition: qthread.h:59
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
#define WM_TOUCH
int fetchAndStoreRelease(int newValue)
Atomic fetch-and-store.
bool registerEventNotifier(QWinEventNotifier *notifier)
void registerTimer(int timerId, int interval, QObject *object)
Register a timer with the specified timerId and interval for the given object.
uint qGlobalPostedEventsCount()
The QAbstractEventDispatcher class provides an interface to manage Qt&#39;s event queue.
void flush()
Flushes the event queue.
The QMap class is a template class that provides a skip-list-based dictionary.
Definition: qdatastream.h:67
bool unregisterTimers(QObject *object)
Unregisters all the timers associated with the given object.
int socket() const
Returns the socket identifier specified to the constructor.
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954
QHash< int, WinTimerInfo * > WinTimerDict
#define WM_NCCREATE