rendered paste body--- qeventdispatcher_win.cpp.org 2010-10-07 23:49:29.006076200 +0200
+++ qeventdispatcher_win.cpp 2010-10-11 06:22:25.585665000 +0200
@@ -97,6 +97,326 @@
#include <qmutex.h>
QT_END_INCLUDE_NAMESPACE
+
+
+#include <qthreadstorage.h>
+#include <stdarg.h>
+
+extern "C"
+{
+ void elog_add (char *msg, ...);
+}
+
+#define ELOG_MAX 2048
+#define ELOG_MSG 64
+struct elog_data_entry_s
+{
+ char msg[ELOG_MSG];
+};
+
+struct elog_data_s
+{
+ int idx;
+
+ struct elog_data_entry_s *entry;
+};
+
+QThreadStorage<struct elog_data_s *> elog_data;
+
+/* Logging infrastructure. */
+void
+elog_add (char *msg, ...)
+{
+ struct elog_data_s *data;
+ va_list ap;
+ SYSTEMTIME stime;
+ int len;
+
+ if (!elog_data.hasLocalData())
+ {
+ data = (struct elog_data_s *) qMalloc (sizeof (struct elog_data_s));
+ memset (data, 0x00, sizeof (struct elog_data_s));
+ data->entry = (struct elog_data_entry_s *) qMalloc (ELOG_MAX * sizeof (struct elog_data_entry_s));
+ printf ("@@@ ### @@@ Event log for thread 0x%x at %p/%p\n", GetCurrentThreadId(), data, data->entry);
+ elog_data.setLocalData(data);
+ }
+ else
+ data = elog_data.localData();
+
+ memset (&data->entry[data->idx], 0x00, sizeof (struct elog_data_entry_s));
+
+ GetLocalTime (&stime);
+ sprintf (data->entry[data->idx].msg, "%02i%02i%02i ",
+ stime.wHour, stime.wMinute, stime.wSecond);
+ len = strlen (data->entry[data->idx].msg);
+ va_start (ap, msg);
+ _vsnprintf (data->entry[data->idx].msg + len, ELOG_MSG - len, msg, ap);
+ va_end (ap);
+
+ data->idx++;
+ if (data->idx == ELOG_MAX)
+ data->idx = 0;
+
+ /* Mark the current position for easier human inspection. */
+ memset (&data->entry[data->idx], 0xff, sizeof (struct elog_data_entry_s));
+}
+
+
+static const char *
+elog_msg_to_str (MSG *msg)
+{
+ switch (msg->message)
+ {
+ case WM_TOUCH:
+ return "WM_TOUCH";
+#ifndef QT_NO_GESTURES
+ case WM_GESTURE:
+ return "WM_GESTURES";
+ case WM_GESTURENOTIFY:
+ return "WM_GESTURENOTIFY";
+#endif // QT_NO_GESTURES
+ case WM_QT_SOCKETNOTIFIER:
+ return "WM_QT_SOCKETNOTIFIER";
+ case WM_QT_SENDPOSTEDEVENTS:
+ return "WM_QT_SENDPOSTEDEVENTS";
+ case WM_APP:
+ return "WM_APP";
+ case WM_ACTIVATE:
+ return "WM_ACTIVATE";
+ case WM_CANCELMODE:
+ return "WM_CANCELMODE";
+ case WM_CAPTURECHANGED:
+ return "WM_CAPTURECHANGED";
+ case WM_CHAR:
+ return "WM_CHAR";
+ case WM_CHARTOITEM:
+ return "WM_CHARTOITEM";
+ case WM_CLEAR:
+ return "WM_CLEAR";
+ case WM_CLOSE:
+ return "WM_CLOSE";
+ case WM_COMMAND:
+ return "WM_COMMAND";
+ case WM_COMPAREITEM:
+ return "WM_COMPAREITEM";
+ case WM_CONTEXTMENU:
+ return "WM_CONTEXTMENU";
+ case WM_COPY:
+ return "WM_COPY";
+ case WM_COPYDATA:
+ return "WM_COPYDATA";
+ case WM_CREATE:
+ return "WM_CREATE";
+ case WM_CTLCOLORBTN:
+ return "WM_CTLCOLORBTN";
+ case WM_CTLCOLORDLG:
+ return "WM_CTLCOLORDLG";
+ case WM_CTLCOLOREDIT:
+ return "WM_CTLCOLOREDIT";
+ case WM_CTLCOLORLISTBOX:
+ return "WM_CTLCOLORLISTBOX";
+ case WM_CTLCOLORMSGBOX:
+ return "WM_CTLCOLORMSGBOX";
+ case WM_CTLCOLORSCROLLBAR:
+ return "WM_CTLCOLORSCROLLBAR";
+ case WM_CTLCOLORSTATIC:
+ return "WM_CTLCOLORSTATIC";
+ case WM_CUT:
+ return "WM_CUT";
+ case WM_DEADCHAR:
+ return "WM_DEADCHAR";
+ case WM_DELETEITEM:
+ return "WM_DELETEITEM";
+ case WM_DESTROY:
+ return "WM_DESTROY";
+ case WM_DESTROYCLIPBOARD:
+ return "WM_DESTROYCLIPBOARD";
+ case WM_DRAWITEM:
+ return "WM_DRAWITEM";
+ case WM_ENABLE:
+ return "WM_ENABLE";
+ case WM_ENTERIDLE:
+ return "WM_ENTERIDLE";
+ case WM_ENTERMENULOOP:
+ return "WM_ENTERMENULOOP";
+ case WM_ERASEBKGND:
+ return "WM_ERASEBKGND";
+ case WM_EXITMENULOOP:
+ return "WM_EXITMENULOOP";
+ case WM_FONTCHANGE:
+ return "WM_FONTCHANGE";
+ case WM_GETDLGCODE:
+ return "WM_GETDLGCODE";
+ case WM_GETFONT:
+ return "WM_GETFONT";
+ case WM_GETICON:
+ return "WM_GETICON";
+ case WM_GETTEXT:
+ return "WM_GETTEXT";
+ case WM_GETTEXTLENGTH:
+ return "WM_GETTEXTLENGTH";
+ case WM_HELP:
+ return "WM_HELP";
+#ifdef _WIN32_WCE
+ case WM_HIBERNATE:
+ return "WM_HIBERNATE";
+#endif
+ case WM_HOTKEY:
+ return "WM_HOTKEY";
+ case WM_HSCROLL:
+ return "WM_HSCROLL";
+ case WM_INITDIALOG:
+ return "WM_INITDIALOG";
+ case WM_INITMENUPOPUP:
+ return "WM_INITMENUPOPUP";
+#if (_WIN32_WINNT >= 0x0501)
+ case WM_INPUT:
+ return "WM_INPUT";
+#endif
+ case WM_INPUTLANGCHANGE:
+ return "WM_INPUTLANGCHANGE";
+ case WM_INPUTLANGCHANGEREQUEST:
+ return "WM_INPUTLANGCHANGEREQUEST";
+ case WM_KEYDOWN:
+ return "WM_KEYDOWN";
+ case WM_KEYUP:
+ return "WM_KEYUP";
+ case WM_KILLFOCUS:
+ return "WM_KILLFOCUS";
+ case WM_MEASUREITEM:
+ return "WM_MEASUREITEM";
+ case WM_MENUCHAR:
+ return "WM_MENUCHAR";
+ case WM_MOVE:
+ return "WM_MOVE";
+ case WM_NCCREATE:
+ return "WM_NCCREATE";
+ case WM_NCDESTROY:
+ return "WM_NCDESTROY";
+#if (_WIN32_WINNT >= 0x0500)
+ case WM_NCXBUTTONDOWN:
+ return "WM_NCXBUTTONDOWN";
+ case WM_NCXBUTTONUP:
+ return "WM_NCXBUTTONUP";
+ case WM_NCXBUTTONDBLCLK:
+ return "WM_NCXBUTTONDBLCLK";
+ case WM_NCMOUSEHOVER:
+ return "WM_NCMOUSEHOVER";
+ case WM_NCMOUSELEAVE:
+ return "WM_NCMOUSELEAVE";
+#endif
+ case WM_NEXTDLGCTL:
+ return "WM_NEXTDLGCTL";
+ case WM_NOTIFY:
+ return "WM_NOTIFY";
+ case WM_NULL:
+ return "WM_NULL";
+ case WM_PAINT:
+ return "WM_PAINT";
+ case WM_PASTE:
+ return "WM_PASTE";
+ case WM_QUERYDRAGICON:
+ return "WM_QUERYDRAGICON";
+ case WM_QUERYNEWPALETTE:
+ return "WM_QUERYNEWPALETTE";
+ case WM_QUIT:
+ return "WM_QUIT";
+ case WM_RENDERALLFORMATS:
+ return "WM_RENDERALLFORMATS";
+ case WM_RENDERFORMAT:
+ return "WM_RENDERFORMAT";
+ case WM_SETCURSOR:
+ return "WM_SETCURSOR";
+ case WM_SETFOCUS:
+ return "WM_SETFOCUS";
+ case WM_SETFONT:
+ return "WM_SETFONT";
+ case WM_SETICON:
+ return "WM_SETICON";
+ case WM_SETREDRAW:
+ return "WM_SETREDRAW";
+ case WM_SETTEXT:
+ return "WM_SETTEXT";
+ case WM_SETTINGCHANGE:
+ return "WM_SETTINGCHANGE";
+ case WM_SHOWWINDOW:
+ return "WM_SHOWWINDOW";
+ case WM_SIZE:
+ return "WM_SIZE";
+ case WM_STYLECHANGED:
+ return "WM_STYLECHANGED";
+ case WM_SYSCHAR:
+ return "WM_SYSCHAR";
+ case WM_SYSCOLORCHANGE:
+ return "WM_SYSCOLORCHANGE";
+ case WM_SYSCOMMAND:
+ return "WM_SYSCOMMAND";
+ case WM_SYSDEADCHAR:
+ return "WM_SYSDEADCHAR";
+ case WM_SYSKEYDOWN:
+ return "WM_SYSKEYDOWN";
+ case WM_SYSKEYUP:
+ return "WM_SYSKEYUP";
+ case WM_TIMER:
+ return "WM_TIMER";
+ case WM_UNDO:
+ return "WM_UNDO";
+ case WM_VKEYTOITEM:
+ return "WM_VKEYTOITEM";
+ case WM_VSCROLL:
+ return "WM_VSCROLL";
+ case WM_WINDOWPOSCHANGED:
+ return "WM_WINDOWPOSCHANGED";
+ case WM_KEYLAST:
+ return "WM_KEYLAST";
+ case WM_MOUSEMOVE:
+ return "WM_MOUSEMOVE";
+ case WM_LBUTTONDOWN:
+ return "WM_LBUTTONDOWN";
+ case WM_LBUTTONUP:
+ return "WM_LBUTTONUP";
+ case WM_LBUTTONDBLCLK:
+ return "WM_LBUTTONDBLCLK";
+ case WM_RBUTTONDOWN:
+ return "WM_RBUTTONDOWN";
+ case WM_RBUTTONUP:
+ return "WM_RBUTTONUP";
+ case WM_RBUTTONDBLCLK:
+ return "WM_RBUTTONDBLCLK";
+ case WM_MBUTTONDOWN:
+ return "WM_MBUTTONDOWN";
+ case WM_MBUTTONUP:
+ return "WM_MBUTTONUP";
+ case WM_MBUTTONDBLCLK:
+ return "WM_MBUTTONDBLCLK";
+ case WM_MOUSEWHEEL:
+ return "WM_MOUSEWHEEL";
+#if (_WIN32_WINNT >= 0x0500)
+ case WM_XBUTTONDOWN:
+ return "WM_XBUTTONDOWN";
+ case WM_XBUTTONUP:
+ return "WM_XBUTTONUP";
+ case WM_XBUTTONDBLCLK:
+ return "WM_XBUTTONDBLCLK";
+ case WM_MOUSELAST:
+ return "WM_MOUSELAST";
+#else
+ case WM_MOUSELAST:
+ return "WM_MOUSELAST";
+#endif
+ default:
+ return "unknown";
+ }
+}
+
+void
+elog_msg (MSG *msg)
+{
+ elog_add ("msg %p (0x%x): %s\n", msg, msg->message,
+ elog_msg_to_str (msg));
+}
+
+
//#define QCE_ASYNC_DEBUG
namespace {
@@ -401,6 +721,7 @@
void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen)
{
QEvent event(QEvent::WinEventAct);
+ elog_add ("activateEventNotifier %p\n", wen);
QCoreApplication::sendEvent(wen, &event);
}
@@ -706,6 +1027,8 @@
{
Q_D(QEventDispatcherWin32);
+ elog_add ("processEvents(0x%x)\n", int(flags));
+
if (!d->internalHwnd)
createInternalHwnd();
@@ -731,10 +1054,14 @@
// process queued user input events
haveMessage = true;
msg = d->queuedUserInputEvents.takeFirst();
+ elog_add ("haveMessage: queuedUserInputEvents %p (0x%x)\n", msg, msg.message);
+ elog_msg (&msg);
} else if(!(flags & QEventLoop::ExcludeSocketNotifiers) && !d->queuedSocketEvents.isEmpty()) {
// process queued socket events
haveMessage = true;
msg = d->queuedSocketEvents.takeFirst();
+ elog_add ("haveMessage: queuedSocketEvents %p (0x%x)\n", msg, msg.message);
+ elog_msg (&msg);
} else {
haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
if (haveMessage && (flags & QEventLoop::ExcludeUserInputEvents)
@@ -753,37 +1080,48 @@
// queue user input events for later processing
haveMessage = false;
d->queuedUserInputEvents.append(msg);
+ elog_add ("queued: UserInputEvents %p (0x%x)\n", msg, msg.message);
+ elog_msg (&msg);
}
if (haveMessage && (flags & QEventLoop::ExcludeSocketNotifiers)
&& (msg.message == WM_QT_SOCKETNOTIFIER && msg.hwnd == d->internalHwnd)) {
// queue socket events for later processing
haveMessage = false;
d->queuedSocketEvents.append(msg);
+ elog_add ("queued: SocketEvents %p (0x%x)\n", msg, msg.message);
+ elog_msg (&msg);
}
}
if (!haveMessage) {
// no message - check for signalled objects
for (int i=0; i<(int)nCount; i++)
pHandles[i] = d->winEventNotifierList.at(i)->handle();
+ elog_add ("MWFMOE: count = %i\n", nCount);
waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, 0, QS_ALLINPUT, MWMO_ALERTABLE);
if ((haveMessage = (waitRet == WAIT_OBJECT_0 + nCount))) {
// a new message has arrived, process it
+ elog_add ("MWFMOE: message arrived, starting over\n");
continue;
}
}
if (haveMessage) {
+
#ifdef Q_OS_WINCE
// WinCE doesn't support hooks at all, so we have to call this by hand :(
(void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg);
#endif
+ elog_add ("MWFMOE: qt_GetMessageHook: %p (0x%x)\n", msg, msg.message);
+ elog_msg (&msg);
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
if (seenWM_QT_SENDPOSTEDEVENTS) {
// when calling processEvents() "manually", we only want to send posted
// events once
needWM_QT_SENDPOSTEDEVENTS = true;
+ elog_add ("MWFMOE: needWM_QT_SENDPOSTEDEVENTS = true\n");
continue;
}
+ elog_add ("MWFMOE: seenWM_QT_SENDPOSTEDEVENTS = true\n");
seenWM_QT_SENDPOSTEDEVENTS = true;
} else if (msg.message == WM_TIMER) {
// avoid live-lock by keeping track of the timers we've already sent
@@ -793,21 +1131,29 @@
found = (processed.wParam == msg.wParam && processed.hwnd == msg.hwnd && processed.lParam == msg.lParam);
}
if (found)
+ {
+ elog_add ("MWFMOE: timer processed already\n");
continue;
- processedTimers.append(msg);
+ }
+ elog_add ("MWFMOE: timer not processed yet\n");
+ processedTimers.append(msg);
} else if (msg.message == WM_QUIT) {
+ elog_add ("MWFMOE: quit!\n");
if (QCoreApplication::instance())
QCoreApplication::instance()->quit();
return false;
}
if (!filterEvent(&msg)) {
+ elog_add ("MWFMOE: not filtered, dispatching msg %p (0x%x)\n", msg, msg.message);
+ elog_msg (&msg);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + nCount) {
d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
} else {
+ elog_add ("no message, no event\n");
// nothing todo so break
break;
}
@@ -819,14 +1165,17 @@
&& !d->interrupt
&& (flags & QEventLoop::WaitForMoreEvents));
if (canWait) {
+ elog_add ("still nothing, waiting\n");
DWORD nCount = d->winEventNotifierList.count();
Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);
for (int i=0; i<(int)nCount; i++)
pHandles[i] = d->winEventNotifierList.at(i)->handle();
+ elog_add ("MWFMOE: count = %i (blocking)\n", nCount);
emit aboutToBlock();
waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
emit awake();
+ elog_add ("MWFMOE: waitRet = %i\n", waitRet);
if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + nCount) {
d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
retVal = true;
@@ -835,12 +1184,17 @@
} while (canWait);
if (!seenWM_QT_SENDPOSTEDEVENTS && (flags & QEventLoop::EventLoopExec) == 0) {
+ elog_add ("sendPostedEvents\n");
// when called "manually", always send posted events
QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
}
if (needWM_QT_SENDPOSTEDEVENTS)
+ {
+ elog_add ("PostMessage\n");
PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);
+ }
+ elog_add ("processEvents leave\n");
return retVal;
}