pidgin/quail/quail-redux
Another attempt at implementing a Qt Glib Windows Event loop, based on advice from Thiago Macieira
--- a/Quail-redux.pro Thu Sep 05 10:31:00 2013 +0100
+++ b/Quail-redux.pro Fri Sep 13 13:58:43 2013 +0100
@@ -1,166 +1,169 @@
-DEFINES += APP_DISPLAY_VERSION=\\\"0.1.0\\\"
-DEFINES += APP_MAJOR_VERSION=\\\"0\\\"
-VERSION = $${APP_DISPLAY_VERSION}
-CONFIG = qt warn_on debug_and_release
-DEFINES += APP_NAME=\\\"Quail\\\"
-DEFINES += QUAIL_PREFS_ROOT=\\\"/quail\\\"
-DEFINES += UI_ID=\\\"quail\\\"
-# Check that we have the repository folder
-exists(.hg):DEFINES += BUILDREVISION=\\\"$$system( hg parent --template \"{node}\")\\\"
-else:DEFINES += BUILDREVISION=\\\"NOTBUILTFROMSOURCEREPOSITORY\\\"
-# DEFINES += BUILDTIME=\\\"$$system('time/T')\\\"
-# DEFINES += BUILDDATE=\\\"$$system('echo %date%')\\\"
-# DEFINES += BUILDTIME=\\\"$$system(date '+%H:%M.%s')\\\"
-# DEFINES += BUILDDATE=\\\"$$system(date '+%d/%m/%y')\\\"
-greaterThan(QT_MAJOR_VERSION, 4) {
- src/QuailAccountBox.h \
- src/QuailAccountEditor.h \
- src/QuailAccountsWindow.h \
- src/QuailBListWindow.h \
- src/QuailConnectionMeter.h \
- src/QuailConvButton.h \
- src/QuailConvWindow.h \
- src/QuailDebugWindow.h \
- src/QuailImageUtils.h \
- src/QuailInputDialog.h \
- src/QuailMainWindow.h \
- src/QuailMultiLineEdit.h \
- src/QuailPrefsDialog.h \
- src/QuailProtocolBox.h \
- src/QuailProtocolUtils.h \
- src/QuailConvDisplay.h \
- src/QuailStatusSelector.h \
- src/QuailAccountBox.cpp \
- src/QuailAccountEditor.cpp \
- src/QuailAccountsWindow.cpp \
- src/QuailBListWindow.cpp \
- src/QuailBuddyList.cpp \
- src/QuailConnectionMeter.cpp \
- src/QuailConvButton.cpp \
- src/QuailConvWindow.cpp \
- src/QuailDebugWindow.cpp \
- src/QuailEventLoop.cpp \
- src/QuailImageUtils.cpp \
- src/QuailInputDialog.cpp \
- src/QuailMainWindow.cpp \
- src/QuailMultiLineEdit.cpp \
- src/QuailPrefsDialog.cpp \
- src/QuailProtocolBox.cpp \
- src/QuailProtocolUtils.cpp \
- src/QuailTabWidget.cpp \
- src/QuailConvDisplay.cpp \
- src/QuailStatusSelector.cpp \
- CONFIG += link_pkgconfig
- PKGCONFIG += purple glib-2.0 gmodule-2.0
- INCLUDEPATH += /cygdrive/c/dev/win32-dev/gtk_2_0-2.14/include/glib-2.0 \
- /cygdrive/c/dev/win32-dev/gtk_2_0-2.14/include/glib-2.0/include \
- /cygdrive/c/dev/pidgin-main \
- c:/dev/win32-dev/gtk_2_0-2.14/include/glib-2.0 \
- C:/dev/win32-dev/gtk_2_0-2.14/lib/glib-2.0/include
- LIBS += -L"C:/dev/win32-dev/gtk-2.24.10/lib"
- LIBS += -L"C:/dev/pidgin-main/libpurple"
- LIBS += -L"C:/Qt/4.8.5/lib"
- LIBS += -L"/cygdrive/c/Qt/4.8.5/lib"
- LIBS += -llibpurple -lglib-2.0 -lgmodule-2.0
-INCLUDEPATH += $$(LIBPURPLE_ROOT)
-#INCLUDEPATH += $$(QTDIR)
- android/AndroidManifest.xml \
- android/res/layout/splash.xml \
- android/res/values/libs.xml \
- android/res/values/strings.xml \
- android/res/values-de/strings.xml \
- android/res/values-el/strings.xml \
- android/res/values-es/strings.xml \
- android/res/values-et/strings.xml \
- android/res/values-fa/strings.xml \
- android/res/values-fr/strings.xml \
- android/res/values-id/strings.xml \
- android/res/values-it/strings.xml \
- android/res/values-ja/strings.xml \
- android/res/values-ms/strings.xml \
- android/res/values-nb/strings.xml \
- android/res/values-nl/strings.xml \
- android/res/values-pl/strings.xml \
- android/res/values-pt-rBR/strings.xml \
- android/res/values-ro/strings.xml \
- android/res/values-rs/strings.xml \
- android/res/values-ru/strings.xml \
- android/res/values-zh-rCN/strings.xml \
- android/res/values-zh-rTW/strings.xml \
- android/src/org/kde/necessitas/ministro/IMinistro.aidl \
- android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl \
- android/src/org/qtproject/qt5/android/bindings/QtActivity.java \
- android/src/org/qtproject/qt5/android/bindings/QtApplication.java \
+DEFINES += APP_DISPLAY_VERSION=\\\"0.1.0\\\" +DEFINES += APP_MAJOR_VERSION=\\\"0\\\" +VERSION = $${APP_DISPLAY_VERSION} +CONFIG = qt warn_on debug_and_release +DEFINES += APP_NAME=\\\"Quail\\\" +DEFINES += QUAIL_PREFS_ROOT=\\\"/quail\\\" +DEFINES += UI_ID=\\\"quail\\\" +# Check that we have the repository folder +exists(.hg):DEFINES += BUILDREVISION=\\\"$$system( hg parent --template \"{node}\")\\\" +else:DEFINES += BUILDREVISION=\\\"NOTBUILTFROMSOURCEREPOSITORY\\\" +# DEFINES += BUILDTIME=\\\"$$system('time/T')\\\" +# DEFINES += BUILDDATE=\\\"$$system('echo %date%')\\\" +# DEFINES += BUILDTIME=\\\"$$system(date '+%H:%M.%s')\\\" +# DEFINES += BUILDDATE=\\\"$$system(date '+%d/%m/%y')\\\" +greaterThan(QT_MAJOR_VERSION, 4) { + src/QuailAccountBox.h \ + src/QuailAccountEditor.h \ + src/QuailAccountsWindow.h \ + src/QuailBListWindow.h \ + src/QuailConnectionMeter.h \ + src/QuailConvButton.h \ + src/QuailConvWindow.h \ + src/QuailDebugWindow.h \ + src/QuailImageUtils.h \ + src/QuailInputDialog.h \ + src/QuailMainWindow.h \ + src/QuailMultiLineEdit.h \ + src/QuailPrefsDialog.h \ + src/QuailProtocolBox.h \ + src/QuailProtocolUtils.h \ + src/QuailConvDisplay.h \ + src/QuailStatusSelector.h \ + src/QuailAccountBox.cpp \ + src/QuailAccountEditor.cpp \ + src/QuailAccountsWindow.cpp \ + src/QuailBListWindow.cpp \ + src/QuailBuddyList.cpp \ + src/QuailConnectionMeter.cpp \ + src/QuailConvButton.cpp \ + src/QuailConvWindow.cpp \ + src/QuailDebugWindow.cpp \ + src/QuailEventLoop.cpp \ + src/QuailImageUtils.cpp \ + src/QuailInputDialog.cpp \ + src/QuailMainWindow.cpp \ + src/QuailMultiLineEdit.cpp \ + src/QuailPrefsDialog.cpp \ + src/QuailProtocolBox.cpp \ + src/QuailProtocolUtils.cpp \ + src/QuailTabWidget.cpp \ + src/QuailConvDisplay.cpp \ + src/QuailStatusSelector.cpp \ + CONFIG += link_pkgconfig + PKGCONFIG += purple glib-2.0 gmodule-2.0 + HEADERS += src/QuailWinGlibEventLoop.h + SOURCES += src/QuailWinGlibEventLoop.cpp + INCLUDEPATH += /cygdrive/c/dev/win32-dev/gtk_2_0-2.14/include/glib-2.0 \ + /cygdrive/c/dev/win32-dev/gtk_2_0-2.14/include/glib-2.0/include \ + /cygdrive/c/dev/pidgin-main \ + c:/dev/win32-dev/gtk_2_0-2.14/include/glib-2.0 \ + C:/dev/win32-dev/gtk_2_0-2.14/lib/glib-2.0/include + LIBS += -L"C:/dev/win32-dev/gtk-2.24.10/lib" + LIBS += -L"C:/dev/pidgin-main/libpurple" + LIBS += -L"C:/Qt/4.8.5/lib" + LIBS += -L"/cygdrive/c/Qt/4.8.5/lib" + LIBS += -llibpurple -lglib-2.0 -lgmodule-2.0 +INCLUDEPATH += $$(LIBPURPLE_ROOT) +#INCLUDEPATH += $$(QTDIR) + android/AndroidManifest.xml \ + android/res/layout/splash.xml \ + android/res/values/libs.xml \ + android/res/values/strings.xml \ + android/res/values-de/strings.xml \ + android/res/values-el/strings.xml \ + android/res/values-es/strings.xml \ + android/res/values-et/strings.xml \ + android/res/values-fa/strings.xml \ + android/res/values-fr/strings.xml \ + android/res/values-id/strings.xml \ + android/res/values-it/strings.xml \ + android/res/values-ja/strings.xml \ + android/res/values-ms/strings.xml \ + android/res/values-nb/strings.xml \ + android/res/values-nl/strings.xml \ + android/res/values-pl/strings.xml \ + android/res/values-pt-rBR/strings.xml \ + android/res/values-ro/strings.xml \ + android/res/values-rs/strings.xml \ + android/res/values-ru/strings.xml \ + android/res/values-zh-rCN/strings.xml \ + android/res/values-zh-rTW/strings.xml \ + android/src/org/kde/necessitas/ministro/IMinistro.aidl \ + android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl \ + android/src/org/qtproject/qt5/android/bindings/QtActivity.java \ + android/src/org/qtproject/qt5/android/bindings/QtApplication.java \ --- a/src/QuailEventLoop.h Thu Sep 05 10:31:00 2013 +0100
+++ b/src/QuailEventLoop.h Fri Sep 13 13:58:43 2013 +0100
@@ -30,6 +30,12 @@
/* http://harmattan-dev.nokia.com/docs/library/html/qt4/qabstracteventdispatcher.html */
#include <QAbstractEventDispatcher>
+ QQuailTimer *quailTimer; class QQuailTimer : public QTimer
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/QuailWinGlibEventLoop.cpp Fri Sep 13 13:58:43 2013 +0100
@@ -0,0 +1,5 @@
+#include "QuailWinGlibEventLoop.h" +QuailWinGlibEventLoop::QuailWinGlibEventLoop() --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/QuailWinGlibEventLoop.h Fri Sep 13 13:58:43 2013 +0100
@@ -0,0 +1,149 @@
+#ifndef QUAILWINGLIBEVENTLOOP_H +#define QUAILWINGLIBEVENTLOOP_H +#include "QtCore/qt_windows.h" +#include <QAbstractEventDispatcher> +typedef struct _GMainContext GMainContext; +class QWinEventNotifier; +class QuailEventDispatcherWinGlibPrivate; +LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); +class QuailEventDispatcherWinGlib : public QAbstractEventDispatcher + Q_DECLARE_PRIVATE(QuailEventDispatcherWinGlib) + void createInternalHwnd(); + explicit QuailEventDispatcherWinGlib(QObject parent = 0); + explicit QuailEventDispatcherWinGlib(GMainContext *context, QObject *parent = 0); + ~QuailEventDispatcherWinGlib(); + bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags); + bool hasPendingEvents(); + void registerSocketNotifier(QSocketNotifier *notifier); + void unregisterSocketNotifier(QSocketNotifier *notifier); + void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object); + bool unregisterTimer(int timerId); + bool unregisterTimers(QObject *object); + QList<TimerInfo> registeredTimers(QObject *object) const; + bool registerEventNotifier(QWinEventNotifier *notifier); + void unregisterEventNotifier(QWinEventNotifier *notifier); + void activateEventNotifiers(); + int remainingTime(int timerId); + static bool versionSupported(); + QEventDispatcherWinGlib(QuailEventDispatcherWinGlibPrivate &dd, QObject *parent = 0); + virtual void sendPostedEvents(); + friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); + friend LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM); +struct GPostEventSource; +struct GSocketNotifierSource; +struct GIdleTimerSource; +typedef QHash<int, QSockNot *> QSNDict; +struct WinTimerInfo { // internal timer info + Qt::TimerType timerType; + quint64 timeout; // - when to actually fire + QObject *obj; // - object to receive events +class QZeroTimerEvent : public QTimerEvent + explicit inline QZeroTimerEvent(int timerId) + { t = QEvent::ZeroTimerEvent; } +typedef QList<WinTimerInfo*> WinTimerVec; // vector of TimerInfo structs +typedef QHash<int, WinTimerInfo*> WinTimerDict; // fast dict of timers +class Q_CORE_EXPORT QuailEventDispatcherWinGlibPrivate : public QAbstractEventDispatcherPrivate + Q_DECLARE_PUBLIC(QEventDispatcherWinGlib) + QEventDispatcherWinGlibPrivate(); + QEventDispatcherWinGlibPrivate(GMainContext *context = 0); + ~QEventDispatcherWinGlibPrivate(); + GMainContext *mainContext; + GPostEventSource *postEventSource; + GSocketNotifierSource *socketNotifierSource; + GTimerSource *timerSource; + GIdleTimerSource *idleTimerSource; + void runTimersOnceWithNormalPriority(); + // internal window handle used for socketnotifiers/timers/etc + // for controlling when to send posted events + QAtomicInt serialNumber; + int lastSerialNumber, sendPostedEventsWindowsTimerId; + WinTimerDict timerDict; + void registerTimer(WinTimerInfo *t); + void unregisterTimer(WinTimerInfo *t); + void sendTimerEvent(int timerId); + void doWsaAsyncSelect(int socket); + QList<QWinEventNotifier *> winEventNotifierList; + void activateEventNotifier(QWinEventNotifier * wen); + QList<MSG> queuedUserInputEvents; + QList<MSG> queuedSocketEvents; +#endif // QUAILWINGLIBEVENTLOOP_H --- a/src/main.cpp Thu Sep 05 10:31:00 2013 +0100
+++ b/src/main.cpp Fri Sep 13 13:58:43 2013 +0100
@@ -20,14 +20,19 @@
#include "QuailEventLoop.h"
+#include "QuailWinGlibEventLoop.h" #include "QuailMainWindow.h"
int main(int argc, char *argv[])
- QuailEventLoop quailEventLoop;
+ QuailWinGlibEventLoop quailEventLoop; QApplication a(argc, argv);