Qt 4.8
Classes | Macros | Typedefs | Enumerations | Functions | Variables
qeventdispatcher_win.cpp File Reference
#include "qeventdispatcher_win_p.h"
#include "qcoreapplication.h"
#include "qhash.h"
#include <private/qsystemlibrary_p.h>
#include "qpair.h"
#include "qset.h"
#include "qsocketnotifier.h"
#include "qvarlengtharray.h"
#include "qwineventnotifier_p.h"
#include "qabstracteventdispatcher_p.h"
#include "qcoreapplication_p.h"
#include <private/qthread_p.h>
#include <winsock.h>
#include <qthread.h>
#include <qmap.h>
#include <qmutex.h>

Go to the source code of this file.

Classes

class  QEventDispatcherWin32Private
 
struct  QSockNot
 
class  QZeroTimerEvent
 
struct  WinTimerInfo
 

Macros

#define DWORD_PTR   DWORD
 
#define QS_RAWINPUT   0x0000
 
#define TIME_KILL_SYNCHRONOUS   0x0100
 
#define WM_GESTURE   0x0119
 
#define WM_GESTURENOTIFY   0x011A
 
#define WM_TOUCH   0x0240
 

Typedefs

typedef MMRESULT(WINAPI * ptimeKillEvent) (UINT)
 
typedef MMRESULT(WINAPI * ptimeSetEvent) (UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT)
 
typedef QHash< int, QSockNot * > QSNDict
 
typedef QHash< int, WinTimerInfo * > WinTimerDict
 
typedef QList< WinTimerInfo * > WinTimerVec
 

Enumerations

enum  { WM_QT_SOCKETNOTIFIER = WM_USER, WM_QT_SENDPOSTEDEVENTS = WM_USER + 1, SendPostedEventsWindowsTimerId = ~1u }
 

Functions

static UINT inputTimerMask ()
 
uint qGlobalPostedEventsCount ()
 
static HWND qt_create_internal_window (const QEventDispatcherWin32 *eventDispatcher)
 
void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc (uint timerId, uint, DWORD_PTR user, DWORD_PTR, DWORD_PTR)
 
LRESULT QT_WIN_CALLBACK qt_GetMessageHook (int code, WPARAM wp, LPARAM lp)
 
LRESULT QT_WIN_CALLBACK qt_internal_proc (HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
 
HINSTANCE qWinAppInst ()
 
static void resolveTimerAPI ()
 
Q_CORE_EXPORT bool winGetMessage (MSG *msg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
 
Q_CORE_EXPORT bool winPeekMessage (MSG *msg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
 
Q_CORE_EXPORT bool winPostMessage (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
int WSAAsyncSelect (SOCKET sock, HWND handle, unsigned int msg, long ev)
 

Variables

static ptimeKillEvent qtimeKillEvent = 0
 
static ptimeSetEvent qtimeSetEvent = 0
 

Macro Definition Documentation

◆ DWORD_PTR

#define DWORD_PTR   DWORD

◆ QS_RAWINPUT

#define QS_RAWINPUT   0x0000

Definition at line 68 of file qeventdispatcher_win.cpp.

Referenced by inputTimerMask().

◆ TIME_KILL_SYNCHRONOUS

#define TIME_KILL_SYNCHRONOUS   0x0100

◆ WM_GESTURE

#define WM_GESTURE   0x0119

Definition at line 79 of file qeventdispatcher_win.cpp.

Referenced by QEventDispatcherWin32::processEvents(), and QtWndProc().

◆ WM_GESTURENOTIFY

#define WM_GESTURENOTIFY   0x011A

Definition at line 82 of file qeventdispatcher_win.cpp.

Referenced by QEventDispatcherWin32::processEvents().

◆ WM_TOUCH

#define WM_TOUCH   0x0240

Definition at line 75 of file qeventdispatcher_win.cpp.

Referenced by QEventDispatcherWin32::processEvents().

Typedef Documentation

◆ ptimeKillEvent

typedef MMRESULT(WINAPI * ptimeKillEvent) (UINT)

Definition at line 313 of file qeventdispatcher_win.cpp.

◆ ptimeSetEvent

typedef MMRESULT(WINAPI * ptimeSetEvent) (UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT)

Definition at line 312 of file qeventdispatcher_win.cpp.

◆ QSNDict

typedef QHash<int, QSockNot *> QSNDict

Definition at line 286 of file qeventdispatcher_win.cpp.

◆ WinTimerDict

Definition at line 306 of file qeventdispatcher_win.cpp.

◆ WinTimerVec

Definition at line 305 of file qeventdispatcher_win.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
WM_QT_SOCKETNOTIFIER 
WM_QT_SENDPOSTEDEVENTS 
SendPostedEventsWindowsTimerId 

Definition at line 86 of file qeventdispatcher_win.cpp.

Function Documentation

◆ inputTimerMask()

static UINT inputTimerMask ( )
inlinestatic

Definition at line 508 of file qeventdispatcher_win.cpp.

Referenced by qt_GetMessageHook().

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 }
static const WinVersion WindowsVersion
the version of the Windows operating system on which the application is run (Windows only) ...
Definition: qglobal.h:1613
#define QS_RAWINPUT

◆ qGlobalPostedEventsCount()

uint qGlobalPostedEventsCount ( )

Definition at line 348 of file qcoreapplication.cpp.

Referenced by QEventDispatcherWin32::hasPendingEvents().

349 {
350  QThreadData *currentThreadData = QThreadData::current();
351  return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
352 }
QPostEventList postEventList
Definition: qthread_p.h:266
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
static QThreadData * current()

◆ qt_create_internal_window()

static HWND qt_create_internal_window ( const QEventDispatcherWin32 eventDispatcher)
static

Definition at line 565 of file qeventdispatcher_win.cpp.

Referenced by QEventDispatcherWin32::createInternalHwnd().

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 }
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
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QString class provides a Unicode character string.
Definition: qstring.h:83
const char * className
Definition: qwizard.cpp:137
Q_CORE_EXPORT void qWarning(const char *,...)
HINSTANCE qWinAppInst()
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290

◆ qt_fast_timer_proc()

void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc ( uint  timerId,
uint  ,
DWORD_PTR  user,
DWORD_PTR  ,
DWORD_PTR   
)

Definition at line 421 of file qeventdispatcher_win.cpp.

Referenced by QEventDispatcherWin32Private::registerTimer().

422 {
423  if (!timerId) // sanity check
424  return;
425  WinTimerInfo *t = (WinTimerInfo*)user;
426  Q_ASSERT(t);
428 }
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...
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:341

◆ qt_GetMessageHook()

LRESULT QT_WIN_CALLBACK qt_GetMessageHook ( int  code,
WPARAM  wp,
LPARAM  lp 
)

Definition at line 520 of file qeventdispatcher_win.cpp.

Referenced by QEventDispatcherWin32::createInternalHwnd().

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 }
double d
Definition: qnumeric_p.h:62
static UINT inputTimerMask()
static QAbstractEventDispatcher * instance(QThread *thread=0)
Returns a pointer to the event dispatcher object for the specified thread.
T * qobject_cast(QObject *object)
Definition: qobject.h:375
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
struct tagMSG MSG
#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
int fetchAndStoreRelease(int newValue)
Atomic fetch-and-store.

◆ qt_internal_proc()

LRESULT QT_WIN_CALLBACK qt_internal_proc ( HWND  hwnd,
UINT  message,
WPARAM  wp,
LPARAM  lp 
)

Definition at line 430 of file qeventdispatcher_win.cpp.

Referenced by qt_create_internal_window(), and QEventDispatcherWin32Private::~QEventDispatcherWin32Private().

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) {
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 }
double d
Definition: qnumeric_p.h:62
QSocketNotifier * obj
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data)
int type
Definition: qmetatype.cpp:239
EventRef event
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QThreadData * threadData
Definition: qobject_p.h:195
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
unsigned int uint
Definition: qglobal.h:996
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
The QCoreApplication class provides an event loop for console Qt applications.
struct tagMSG MSG
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
#define WSAGETSELECTEVENT(lParam)
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
#define WM_NCCREATE

◆ qWinAppInst()

HINSTANCE qWinAppInst ( )

Definition at line 58 of file qcoreapplication_win.cpp.

Referenced by qt_create_internal_window(), and QEventDispatcherWin32Private::~QEventDispatcherWin32Private().

59 {
60  return GetModuleHandle(0);
61 }

◆ resolveTimerAPI()

static void resolveTimerAPI ( )
static

Definition at line 320 of file qeventdispatcher_win.cpp.

Referenced by QEventDispatcherWin32Private::QEventDispatcherWin32Private().

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 }
MMRESULT(WINAPI * ptimeKillEvent)(UINT)
static ptimeKillEvent qtimeKillEvent
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
MMRESULT(WINAPI * ptimeSetEvent)(UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT)
static ptimeSetEvent qtimeSetEvent

◆ winGetMessage()

Q_CORE_EXPORT bool winGetMessage ( MSG msg,
HWND  hWnd,
UINT  wMsgFilterMin,
UINT  wMsgFilterMax 
)

Definition at line 414 of file qeventdispatcher_win.cpp.

416 {
417  return GetMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax);
418 }

◆ winPeekMessage()

Q_CORE_EXPORT bool winPeekMessage ( MSG msg,
HWND  hWnd,
UINT  wMsgFilterMin,
UINT  wMsgFilterMax,
UINT  wRemoveMsg 
)

Definition at line 401 of file qeventdispatcher_win.cpp.

403 {
404  return PeekMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
405 }

◆ winPostMessage()

Q_CORE_EXPORT bool winPostMessage ( HWND  hWnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 408 of file qeventdispatcher_win.cpp.

409 {
410  return PostMessage(hWnd, msg, wParam, lParam);
411 }

◆ WSAAsyncSelect()

int WSAAsyncSelect ( SOCKET  sock,
HWND  handle,
unsigned int  msg,
long  ev 
)

Definition at line 256 of file qeventdispatcher_win.cpp.

Referenced by QEventDispatcherWin32Private::doWsaAsyncSelect().

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 }

Variable Documentation

◆ qtimeKillEvent

ptimeKillEvent qtimeKillEvent = 0
static

◆ qtimeSetEvent

ptimeSetEvent qtimeSetEvent = 0
static