46 #include <private/qsystemlibrary_p.h> 55 #include <private/qthread_p.h> 62 #ifndef TIME_KILL_SYNCHRONOUS 63 # define TIME_KILL_SYNCHRONOUS 0x0100 68 # define QS_RAWINPUT 0x0000 70 # define QS_RAWINPUT 0x0400 75 # define WM_TOUCH 0x0240 77 #ifndef QT_NO_GESTURES 79 # define WM_GESTURE 0x0119 81 #ifndef WM_GESTURENOTIFY 82 # define WM_GESTURENOTIFY 0x011A 84 #endif // QT_NO_GESTURES 92 #if defined(Q_OS_WINCE) 105 class SocketAsyncHandler;
107 class SocketAsyncHandler :
public QThread 110 SocketAsyncHandler();
111 ~SocketAsyncHandler();
113 void select(SOCKET sock, HWND handle,
unsigned int msg,
long ev);
114 void removeSelect(SOCKET sock);
115 void safeRemove(SOCKET sock);
128 SocketAsyncHandler::SocketAsyncHandler()
129 : supposedToDie(
false)
133 SocketAsyncHandler::~SocketAsyncHandler()
136 supposedToDie =
true;
140 while (sockets.size() > 0)
141 removeSelect(sockets.begin().key());
144 void SocketAsyncHandler::removeSelect(SOCKET sock)
146 if (!sockets.contains(sock))
148 sockets.remove(sock);
152 void SocketAsyncHandler::safeRemove(SOCKET sock)
162 if (sockets.contains(sock))
163 sockets.remove(sock);
166 info.handle = handle;
169 sockets.insert(sock, info);
178 while (!supposedToDie && sockets.isEmpty()) {
192 fd_set readS, writeS, exS;
200 const SockInfo &
info =
it.value();
201 int socket =
it.key();
202 maxFd =
qMax(maxFd, socket);
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);
214 timeout.tv_usec = 50000;
215 int result =
::select(maxFd + 1, &readS, &writeS, &exS, &timeout);
223 handle = (*it).handle;
226 if (FD_ISSET(sock, &readS))
227 ret = SendMessage(handle, tmpMsg, sock, FD_READ);
229 if (FD_ISSET(sock, &writeS))
230 ret = SendMessage(handle, tmpMsg, sock, FD_WRITE);
232 if (FD_ISSET(sock, &exS))
233 ret = SendMessage(handle, tmpMsg, sock, FD_OOB);
237 #ifdef QCE_ASYNC_DEBUG 238 else if (result == 0) {
239 qDebug(
" WSAAsync select timeout");
240 }
else if (result < 0) {
247 qWarning(
"WSAAsync select error %d", WSAGetLastError());
258 if (sock == 0 || handle == 0 || handle == INVALID_HANDLE_VALUE) {
259 WSASetLastError(WSAEINVAL);
263 if (msg == 0 && ev == 0)
264 qt_async_handler()->safeRemove(sock);
266 qt_async_handler()->select(sock, handle, msg, ev);
272 #else // QT_NO_THREAD 308 #if !defined(DWORD_PTR) && !defined(Q_WS_WIN64) 309 #define DWORD_PTR DWORD 322 static bool triedResolve =
false;
329 if (library.
load()) {
363 void unregisterTimer(
WinTimerInfo *t,
bool closingDown =
false);
364 void sendTimerEvent(
int timerId);
370 void doWsaAsyncSelect(
int socket);
380 : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0),
381 serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), wakeUps(0)
402 UINT wMsgFilterMax, UINT wRemoveMsg)
404 return PeekMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
410 return PostMessage(hWnd, msg, wParam, lParam);
417 return GetMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax);
437 msg.message = message;
443 if (message == WM_TIMER)
490 || (message == WM_TIMER
499 }
else if (message == WM_TIMER) {
505 return DefWindowProc(hwnd, message, wp, lp);
513 #if defined(_MSC_VER) && _MSC_VER >= 1700 515 result &= ~(QS_TOUCH | QS_POINTER);
516 #endif // _MSC_VER >= 1700 522 if (wp == PM_REMOVE) {
530 if (HIWORD(GetQueueStatus(mask)) == 0) {
561 return CallNextHookEx(0, code, wp, lp);
578 wc.hbrBackground = 0;
579 wc.lpszMenuName = NULL;
580 wc.lpszClassName =
reinterpret_cast<const wchar_t *
> (className.
utf16());
583 HWND wnd = CreateWindow(wc.lpszClassName,
593 qWarning(
"QEventDispatcher: Failed to create QEventDispatcherWin32 internal window: %d\n", (
int)GetLastError());
597 SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)eventDispatcher);
599 SetWindowLong(wnd, GWL_USERDATA, (LONG)eventDispatcher);
627 qErrnoWarning(
"QEventDispatcherWin32::registerTimer: Failed to create a timer");
670 sn_event |= FD_READ | FD_CLOSE | FD_ACCEPT;
672 sn_event |= FD_WRITE | FD_CONNECT;
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");
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));
705 for (
int i = 0; i <
d->timerVec.count(); ++i)
706 d->registerTimer(
d->timerVec.at(i));
725 if (!
d->internalHwnd)
728 d->interrupt =
false;
733 bool seenWM_QT_SENDPOSTEDEVENTS =
false;
734 bool needWM_QT_SENDPOSTEDEVENTS =
false;
737 HANDLE pHandles[MAXIMUM_WAIT_OBJECTS - 1];
739 while (!
d->interrupt) {
740 DWORD nCount =
d->winEventNotifierList.count();
741 Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);
749 msg =
d->queuedUserInputEvents.takeFirst();
753 msg =
d->queuedSocketEvents.takeFirst();
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)
768 || msg.message == WM_CLOSE)) {
771 d->queuedUserInputEvents.append(msg);
773 if (haveMessage && (flags & QEventLoop::ExcludeSocketNotifiers)
777 d->queuedSocketEvents.append(msg);
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);
797 if (seenWM_QT_SENDPOSTEDEVENTS) {
800 needWM_QT_SENDPOSTEDEVENTS =
true;
803 seenWM_QT_SENDPOSTEDEVENTS =
true;
804 }
else if (msg.message == WM_TIMER) {
807 for (
int i = 0; !found && i < processedTimers.
count(); ++i) {
809 found = (processed.wParam == msg.wParam && processed.hwnd == msg.hwnd && processed.lParam == msg.lParam);
813 processedTimers.
append(msg);
814 }
else if (msg.message == WM_QUIT) {
821 TranslateMessage(&msg);
822 DispatchMessage(&msg);
825 d->activateEventNotifier(
d->winEventNotifierList.at(waitRet -
WAIT_OBJECT_0));
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();
844 waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT,
MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
847 d->activateEventNotifier(
d->winEventNotifierList.at(waitRet -
WAIT_OBJECT_0));
858 if (needWM_QT_SENDPOSTEDEVENTS)
873 int sockfd = notifier->
socket();
877 qWarning(
"QSocketNotifier: Internal error");
880 qWarning(
"QSocketNotifier: socket notifiers cannot be enabled from another thread");
886 QSNDict *sn_vec[3] = { &
d->sn_read, &
d->sn_write, &
d->sn_except };
893 const char *t[] = {
"Read",
"Write",
"Exception" };
895 qWarning(
"QSocketNotifier: Multiple socket notifiers for " 896 "same socket %d and type %s", sockfd, t[type]);
905 d->doWsaAsyncSelect(sockfd);
911 int sockfd = notifier->
socket();
915 qWarning(
"QSocketNotifier: Internal error");
918 qWarning(
"QSocketNotifier: socket notifiers cannot be disabled from another thread");
924 QSNDict *sn_vec[3] = { &
d->sn_read, &
d->sn_write, &
d->sn_except };
934 d->doWsaAsyncSelect(sockfd);
939 if (timerId < 1 || interval < 0 || !
object) {
940 qWarning(
"QEventDispatcherWin32::registerTimer: invalid arguments");
943 qWarning(
"QObject::startTimer: timers cannot be started from another thread");
960 d->timerVec.append(t);
967 qWarning(
"QEventDispatcherWin32::unregisterTimer: invalid argument");
971 if (
thread() != currentThread) {
972 qWarning(
"QObject::killTimer: timers cannot be stopped from another thread");
977 if (
d->timerVec.isEmpty() || timerId <= 0)
985 d->timerVec.removeAll(t);
986 d->unregisterTimer(t);
993 qWarning(
"QEventDispatcherWin32::unregisterTimers: invalid argument");
998 qWarning(
"QObject::killTimers: timers cannot be stopped from another thread");
1003 if (
d->timerVec.isEmpty())
1006 for (
int i=0; i<
d->timerVec.size(); i++) {
1007 t =
d->timerVec.at(i);
1008 if (t && t->
obj ==
object) {
1010 d->timerVec.removeAt(i);
1011 d->unregisterTimer(t);
1022 qWarning(
"QEventDispatcherWin32:registeredTimers: invalid argument");
1028 for (
int i = 0; i <
d->timerVec.size(); ++i) {
1030 if (t && t->
obj ==
object)
1039 qWarning(
"QWinEventNotifier: Internal error");
1042 qWarning(
"QWinEventNotifier: event notifiers cannot be enabled from another thread");
1048 if (
d->winEventNotifierList.contains(notifier))
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);
1055 d->winEventNotifierList.append(notifier);
1062 qWarning(
"QWinEventNotifier: Internal error");
1065 qWarning(
"QWinEventNotifier: event notifiers cannot be disabled from another thread");
1071 int i =
d->winEventNotifierList.indexOf(notifier);
1073 d->winEventNotifierList.takeAt(i);
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));
1085 if (WaitForSingleObject(
d->winEventNotifierList.at(i)->handle(), 0) ==
WAIT_OBJECT_0)
1086 d->activateEventNotifier(
d->winEventNotifierList.at(i));
1094 d->serialNumber.ref();
1095 if (
d->internalHwnd &&
d->wakeUps.testAndSetAcquire(0, 1)) {
1104 d->interrupt =
true;
1119 while (!
d->sn_read.isEmpty())
1121 while (!
d->sn_write.isEmpty())
1123 while (!
d->sn_except.isEmpty())
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();
1133 if (
d->getMessageHook)
1134 UnhookWindowsHookEx(
d->getMessageHook);
1135 d->getMessageHook = 0;
1151 t =
d->timerDict.value(zte->
timerId());
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
T qobject_cast(QObject *object)
const T * constData() const
QEventDispatcherWin32Private()
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data)
virtual void run()
The starting point for the thread.
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
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.
void unregisterTimer(WinTimerInfo *t, bool closingDown=false)
The QMutex class provides access serialization between threads.
int remove(const Key &key)
Removes all the items that have the key from the hash.
void registerSocketNotifier(QSocketNotifier *notifier)
Registers notifier with the event loop.
The QAtomicInt class provides platform-independent atomic operations on integers. ...
#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.
MMRESULT(WINAPI * ptimeKillEvent)(UINT)
QList< MSG > queuedUserInputEvents
static ptimeKillEvent qtimeKillEvent
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *)
void sendTimerEvent(int timerId)
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
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)
int count(const T &t) const
Returns the number of occurrences of value in the list.
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) ...
The QString class provides a Unicode character string.
QEventDispatcherWin32(QObject *parent=0)
static QList< QVariant > toList(char **buf, int count, T *=0)
QPair< int, int > TimerInfo
Typedef for QPair<int, int>.
The QObject class is the base class of all Qt objects.
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
bool load(bool onlySystemDirectory=true)
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
static QObjectPrivate * get(QObject *o)
#define TIME_KILL_SYNCHRONOUS
const T value(const Key &key) const
Returns the value associated with the key.
Type type() const
Returns the socket event type specified to the constructor.
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
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.
The QSocketNotifier class provides support for monitoring activity on a file descriptor.
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.
#define QT_BEGIN_NAMESPACE
This macro expands to.
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.
QList< MSG > queuedSocketEvents
void doWsaAsyncSelect(int socket)
static ptimeSetEvent qtimeSetEvent
void registerTimer(WinTimerInfo *t)
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
const T & at(int i) const
Returns the item at index position i in the list.
QList< QWinEventNotifier * > winEventNotifierList
Q_CORE_EXPORT void qWarning(const char *,...)
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
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.
void activateEventNotifier(QWinEventNotifier *wen)
QHash< int, QSockNot * > QSNDict
int WSAAsyncSelect(SOCKET sock, HWND handle, unsigned int msg, long ev)
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the map.
int sendPostedEventsWindowsTimerId
iterator begin()
Returns an STL-style iterator pointing to the first item in the map.
#define TRUE
Synonym for true.
~QEventDispatcherWin32Private()
Q_CORE_EXPORT void qFatal(const char *,...)
The QMap::const_iterator class provides an STL-style const iterator for QMap and QMultiMap.
The QCoreApplication class provides an event loop for console Qt applications.
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the map...
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
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)
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.
The QMap::iterator class provides an STL-style non-const iterator for QMap and QMultiMap.
The QTimerEvent class contains parameters that describe a timer event.
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
static QCoreApplication * instance()
Returns a pointer to the application's QCoreApplication (or QApplication) instance.
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
static void removePostedTimerEvent(QObject *object, int timerId)
void createInternalHwnd()
static void releaseTimerId(int id)
friend LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM)
QFuture< T > run(Function function,...)
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
#define WSAGETSELECTEVENT(lParam)
void unregisterEventNotifier(QWinEventNotifier *notifier)
QZeroTimerEvent(int timerId)
QThread * thread() const
Returns the thread in which the object lives.
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.
Type type() const
Returns the event type.
The QThread class provides a platform-independent way to manage threads.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
void activateEventNotifiers()
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's event queue.
void flush()
Flushes the event queue.
The QMap class is a template class that provides a skip-list-based dictionary.
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 '\0\'-terminated array of unsigned shorts.
void qErrnoWarning(const char *msg,...)
QHash< int, WinTimerInfo * > WinTimerDict