pidgin/quail/qpurple
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpurple.cpp Mon Jul 26 01:12:37 2010 -0500
@@ -0,0 +1,188 @@
+#include "qpurpleionotifier.h" +#include "qpurpletimer.h" + // unique handle for our input events (QPurpleIONotifiers and QPurpleTimers) + unsigned int unique_handle = 0; + QMap< int , QPurpleIONotifier* > notifierMap; + QMap< int , QPurpleTimer* > timerMap; + // Event loop functions + static guint qt_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function, + PurpleGLibIOClosure *closure = g_new0(PurpleGLibIOClosure, 1); + closure->function = function; + // modified from the nullclient source to integrate with Qt + handle = unique_handle++; // this will be unique, certainly + notifierMap[handle] = new QPurpleIONotifier(fd, closure, condition); + static gboolean qt_input_remove(guint handle) { + QPurpleIONotifier *tmp = notifierMap.take(handle); + if (!tmp->defaultConstructed) { + static guint qt_timer_add(guint interval, GSourceFunc function, gpointer data) { + int handle = unique_handle++; + timerMap[handle] = new QPurpleTimer(function, data, interval); + static guint qt_timer_add_seconds(guint interval, GSourceFunc function, gpointer data) { + return qt_timer_add(interval * 1000,function, data); + static gboolean qt_timer_remove(guint handle) { + QPurpleTimer *tmp = timerMap.take(handle); + if (!tmp->defaultConstructed) { // we removed something + static PurpleEventLoopUiOps qt_eventloops = + qt_write_conv(PurpleConversation *conv, const char *who, const char *alias, + const char *message, PurpleMessageFlags flags, time_t mtime) + printf("(%s) %s %s: %s\n", purple_conversation_get_name(conv), + purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)), + static PurpleConversationUiOps null_conv_uiops = + NULL, /* create_conversation */ + NULL, /* destroy_conversation */ + qt_write_conv, /* write_conv */ + NULL, /* chat_add_users */ + NULL, /* chat_rename_user */ + NULL, /* chat_remove_users */ + NULL, /* chat_update_user */ + NULL, /* custom_smiley_add */ + NULL, /* custom_smiley_write */ + NULL, /* custom_smiley_close */ + NULL, /* send_confirm */ + * This should initialize the UI components for all the modules. Here we + * just initialize the UI for conversations. + purple_conversations_set_ui_ops(&null_conv_uiops); + static PurpleCoreUiOps null_core_uiops = + /* Set a custom user directory (optional) */ + purple_util_set_user_dir(CUSTOM_USER_DIRECTORY); + /* We do not want any debugging for now to keep the noise to a minimum. */ + purple_debug_set_enabled(FALSE); + /* Set the core-uiops, which is used to + * - initialize the ui specific preferences. + * - initialize the debug ui. + * - initialize the ui components for all the modules. + * - uninitialize the ui components for all the modules when the core terminates. + purple_core_set_ui_ops(&null_core_uiops); + /* Set the uiops for the eventloop. If your client is glib-based, you can safely + * copy this verbatim. */ + purple_eventloop_set_ui_ops(&qt_eventloops); + /* Set path to search for plugins. The core (libpurple) takes care of loading the + * core-plugins, which includes the protocol-plugins. So it is not essential to add + * any path here, but it might be desired, especially for ui-specific plugins. */ + purple_plugins_add_search_path(CUSTOM_PLUGIN_PATH); + /* Now that all the essential stuff has been set, let's try to init the core. It's + * necessary to provide a non-NULL name for the current ui to the core. This name + * is used by stuff that depends on this ui, for example the ui-specific plugins. */ + if (!purple_core_init(UI_ID)) { + /* Initializing the core failed. Terminate. */ + "libpurple initialization failed. Dumping core.\n" + "Please report this!\n"); + /* Create and load the buddylist. */ + purple_set_blist(purple_blist_new()); + /* Load the preferences. */ + /* Load the desired plugins. The client should save the list of loaded plugins in + * the preferences using purple_plugins_save_loaded(PLUGIN_SAVE_PREF) */ + purple_plugins_load_saved(PLUGIN_SAVE_PREF); + /* Load the pounces. */ + //purple_pounces_load(); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpurple.h Mon Jul 26 01:12:37 2010 -0500
@@ -0,0 +1,35 @@
+#include <QSocketNotifier> +#define CUSTOM_USER_DIRECTORY "/dev/null" +#define CUSTOM_PLUGIN_PATH "" +#define PLUGIN_SAVE_PREF "/purple/nullclient/plugins/saved" +#define PURPLE_GLIB_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) +#define PURPLE_GLIB_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) + void init(); // call this in main to start libpurple + typedef struct _PurpleGLibIOClosure { + PurpleInputFunction function; --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpurple.pro Mon Jul 26 01:12:37 2010 -0500
@@ -0,0 +1,20 @@
+# ------------------------------------------------- +# Project created by QtCreator 2010-07-16T23:59:24 +# ------------------------------------------------- +DEFINES += QPURPLE_LIBRARY +unix:INCLUDEPATH += /usr/include/glib-2.0 \ + /usr/lib/glib-2.0/include \ +unx:LIBS += -lglib-2.0 \ +SOURCES += qpurple.cpp \ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpurple.pro.user Mon Jul 26 01:12:37 2010 -0500
@@ -0,0 +1,280 @@
+<!DOCTYPE QtCreatorProject> + <variable>RunConfiguration0-Arguments</variable> + <valuelist type="QVariantList"/> + <variable>RunConfiguration0-BaseEnvironmentBase</variable> + <value type="int">2</value> + <variable>RunConfiguration0-Executable</variable> + <value type="QString"></value> + <variable>RunConfiguration0-RunConfiguration.name</variable> + <value type="QString">Custom Executable</value> + <variable>RunConfiguration0-UseTerminal</variable> + <value type="bool">false</value> + <variable>RunConfiguration0-UserEnvironmentChanges</variable> + <valuelist type="QVariantList"/> + <variable>RunConfiguration0-UserName</variable> + <value type="QString"></value> + <variable>RunConfiguration0-UserSetName</variable> + <value type="bool">false</value> + <variable>RunConfiguration0-WorkingDirectory</variable> + <value type="QString">$BUILDDIR</value> + <variable>RunConfiguration0-type</variable> + <value type="QString">ProjectExplorer.CustomExecutableRunConfiguration</value> + <variable>activeRunConfiguration</variable> + <value type="int">0</value> + <variable>activebuildconfiguration</variable> + <value type="QString">Debug</value> + <variable>buildConfiguration-Debug</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">Debug</value> + <value key="QtVersionId" type="int">0</value> + <value key="ToolChain" type="int">0</value> + <value key="buildConfiguration" type="int">2</value> + <variable>buildConfiguration-Release</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">Release</value> + <value key="QtVersionId" type="int">0</value> + <value key="buildConfiguration" type="int">0</value> + <variable>buildconfiguration-Debug-buildstep0</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">Debug</value> + <valuelist key="abstractProcess.Environment" type="QVariantList"> + <value type="QString">DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-EzWakNHelF,guid=6dc600df2a6620e42996ce584c40c96f</value> + <value type="QString">DEFAULTS_PATH=/usr/share/gconf/gnome.default.path</value> + <value type="QString">DESKTOP_SESSION=gnome</value> + <value type="QString">DISPLAY=:0.0</value> + <value type="QString">GDMSESSION=gnome</value> + <value type="QString">GDM_KEYBOARD_LAYOUT=us dvorak</value> + <value type="QString">GDM_LANG=en_US.utf8</value> + <value type="QString">GNOME_DESKTOP_SESSION_ID=this-is-deprecated</value> + <value type="QString">GNOME_KEYRING_CONTROL=/tmp/keyring-u6YlUq</value> + <value type="QString">GNOME_KEYRING_PID=1825</value> + <value type="QString">GTK_MODULES=canberra-gtk-module</value> + <value type="QString">HOME=/home/gatlin</value> + <value type="QString">LANG=en_US.utf8</value> + <value type="QString">LD_LIBRARY_PATH=/usr/lib/qtcreator:</value> + <value type="QString">LOGNAME=gatlin</value> + <value type="QString">MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path</value> + <value type="QString">ORBIT_SOCKETDIR=/tmp/orbit-gatlin</value> + <value type="QString">PATH=/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games</value> + <value type="QString">PWD=/home/gatlin</value> + <value type="QString">QTDIR=/usr/share/qt4</value> + <value type="QString">SESSION_MANAGER=local/deuteronomy:@/tmp/.ICE-unix/1843,unix/deuteronomy:/tmp/.ICE-unix/1843</value> + <value type="QString">SHELL=/bin/bash</value> + <value type="QString">SPEECHD_PORT=7560</value> + <value type="QString">SSH_AGENT_PID=1877</value> + <value type="QString">SSH_AUTH_SOCK=/tmp/keyring-u6YlUq/ssh</value> + <value type="QString">USER=gatlin</value> + <value type="QString">USERNAME=gatlin</value> + <value type="QString">XAUTHORITY=/var/run/gdm/auth-for-gatlin-9iZ97u/database</value> + <value type="QString">XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/etc/xdg</value> + <value type="QString">XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/</value> + <value type="QString">XDG_SESSION_COOKIE=2e4dc913ddc6151b5764b6894c1ec7ea-1279314287.412731-421931655</value> + <valuelist key="abstractProcess.arguments" type="QVariantList"> + <value type="QString">/home/gatlin/code/hermes/qpurple/qpurple.pro</value> + <value type="QString">-spec</value> + <value type="QString">linux-g++</value> + <value type="QString">-r</value> + <value type="QString">CONFIG+=debug</value> + <value key="abstractProcess.command" type="QString">/usr/bin/qmake-qt4</value> + <value key="abstractProcess.enabled" type="bool">true</value> + <value key="abstractProcess.workingDirectory" type="QString">/home/gatlin/code/hermes/qpurple</value> + <variable>buildconfiguration-Debug-buildstep1</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">Debug</value> + <valuelist key="abstractProcess.Environment" type="QVariantList"> + <value type="QString">DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-EzWakNHelF,guid=6dc600df2a6620e42996ce584c40c96f</value> + <value type="QString">DEFAULTS_PATH=/usr/share/gconf/gnome.default.path</value> + <value type="QString">DESKTOP_SESSION=gnome</value> + <value type="QString">DISPLAY=:0.0</value> + <value type="QString">GDMSESSION=gnome</value> + <value type="QString">GDM_KEYBOARD_LAYOUT=us dvorak</value> + <value type="QString">GDM_LANG=en_US.utf8</value> + <value type="QString">GNOME_DESKTOP_SESSION_ID=this-is-deprecated</value> + <value type="QString">GNOME_KEYRING_CONTROL=/tmp/keyring-u6YlUq</value> + <value type="QString">GNOME_KEYRING_PID=1825</value> + <value type="QString">GTK_MODULES=canberra-gtk-module</value> + <value type="QString">HOME=/home/gatlin</value> + <value type="QString">LANG=en_US.utf8</value> + <value type="QString">LD_LIBRARY_PATH=/usr/lib/qtcreator:</value> + <value type="QString">LOGNAME=gatlin</value> + <value type="QString">MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path</value> + <value type="QString">ORBIT_SOCKETDIR=/tmp/orbit-gatlin</value> + <value type="QString">PATH=/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games</value> + <value type="QString">PWD=/home/gatlin</value> + <value type="QString">QTDIR=/usr/share/qt4</value> + <value type="QString">SESSION_MANAGER=local/deuteronomy:@/tmp/.ICE-unix/1843,unix/deuteronomy:/tmp/.ICE-unix/1843</value> + <value type="QString">SHELL=/bin/bash</value> + <value type="QString">SPEECHD_PORT=7560</value> + <value type="QString">SSH_AGENT_PID=1877</value> + <value type="QString">SSH_AUTH_SOCK=/tmp/keyring-u6YlUq/ssh</value> + <value type="QString">USER=gatlin</value> + <value type="QString">USERNAME=gatlin</value> + <value type="QString">XAUTHORITY=/var/run/gdm/auth-for-gatlin-9iZ97u/database</value> + <value type="QString">XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/etc/xdg</value> + <value type="QString">XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/</value> + <value type="QString">XDG_SESSION_COOKIE=2e4dc913ddc6151b5764b6894c1ec7ea-1279314287.412731-421931655</value> + <value key="abstractProcess.IgnoreReturnValue" type="bool">false</value> + <valuelist key="abstractProcess.arguments" type="QVariantList"> + <value type="QString">-w</value> + <value key="abstractProcess.command" type="QString">/usr/bin/make</value> + <value key="abstractProcess.enabled" type="bool">true</value> + <value key="abstractProcess.workingDirectory" type="QString">/home/gatlin/code/hermes/qpurple</value> + <variable>buildconfiguration-Debug-cleanstep0</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">Debug</value> + <valuelist key="abstractProcess.Environment" type="QVariantList"> + <value type="QString">DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-EzWakNHelF,guid=6dc600df2a6620e42996ce584c40c96f</value> + <value type="QString">DEFAULTS_PATH=/usr/share/gconf/gnome.default.path</value> + <value type="QString">DESKTOP_SESSION=gnome</value> + <value type="QString">DISPLAY=:0.0</value> + <value type="QString">GDMSESSION=gnome</value> + <value type="QString">GDM_KEYBOARD_LAYOUT=us dvorak</value> + <value type="QString">GDM_LANG=en_US.utf8</value> + <value type="QString">GNOME_DESKTOP_SESSION_ID=this-is-deprecated</value> + <value type="QString">GNOME_KEYRING_CONTROL=/tmp/keyring-u6YlUq</value> + <value type="QString">GNOME_KEYRING_PID=1825</value> + <value type="QString">GTK_MODULES=canberra-gtk-module</value> + <value type="QString">HOME=/home/gatlin</value> + <value type="QString">LANG=en_US.utf8</value> + <value type="QString">LD_LIBRARY_PATH=/usr/lib/qtcreator:</value> + <value type="QString">LOGNAME=gatlin</value> + <value type="QString">MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path</value> + <value type="QString">ORBIT_SOCKETDIR=/tmp/orbit-gatlin</value> + <value type="QString">PATH=/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games</value> + <value type="QString">PWD=/home/gatlin</value> + <value type="QString">QTDIR=/usr/share/qt4</value> + <value type="QString">SESSION_MANAGER=local/deuteronomy:@/tmp/.ICE-unix/1843,unix/deuteronomy:/tmp/.ICE-unix/1843</value> + <value type="QString">SHELL=/bin/bash</value> + <value type="QString">SPEECHD_PORT=7560</value> + <value type="QString">SSH_AGENT_PID=1877</value> + <value type="QString">SSH_AUTH_SOCK=/tmp/keyring-u6YlUq/ssh</value> + <value type="QString">USER=gatlin</value> + <value type="QString">USERNAME=gatlin</value> + <value type="QString">XAUTHORITY=/var/run/gdm/auth-for-gatlin-9iZ97u/database</value> + <value type="QString">XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/etc/xdg</value> + <value type="QString">XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/</value> + <value type="QString">XDG_SESSION_COOKIE=2e4dc913ddc6151b5764b6894c1ec7ea-1279314287.412731-421931655</value> + <value key="abstractProcess.IgnoreReturnValue" type="bool">true</value> + <valuelist key="abstractProcess.arguments" type="QVariantList"> + <value type="QString">clean</value> + <value type="QString">-w</value> + <value key="abstractProcess.command" type="QString">/usr/bin/make</value> + <value key="abstractProcess.enabled" type="bool">true</value> + <value key="abstractProcess.workingDirectory" type="QString">/home/gatlin/code/hermes/qpurple</value> + <value key="cleanConfig" type="bool">true</value> + <valuelist key="makeargs" type="QVariantList"> + <value type="QString">clean</value> + <variable>buildconfiguration-Release-buildstep0</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">Release</value> + <variable>buildconfiguration-Release-buildstep1</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">Release</value> + <variable>buildconfiguration-Release-cleanstep0</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">Release</value> + <variable>buildconfigurations</variable> + <valuelist type="QVariantList"> + <value type="QString">Debug</value> + <value type="QString">Release</value> + <variable>buildstep0</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString"></value> + <value key="mkspec" type="QString"></value> + <variable>buildstep1</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString"></value> + <variable>buildsteps</variable> + <valuelist type="QVariantList"> + <value type="QString">trolltech.qt4projectmanager.qmake</value> + <value type="QString">trolltech.qt4projectmanager.make</value> + <variable>cleanstep0</variable> + <valuemap type="QVariantMap"> + <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString"></value> + <value key="clean" type="bool">true</value> + <variable>cleansteps</variable> + <valuelist type="QVariantList"> + <value type="QString">trolltech.qt4projectmanager.make</value> + <variable>defaultFileEncoding</variable> + <value type="QByteArray">System</value> + <variable>project</variable> + <valuemap type="QVariantMap"/> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpurpleionotifier.cpp Mon Jul 26 01:12:37 2010 -0500
@@ -0,0 +1,40 @@
+#include "qpurpleionotifier.h" + QPurpleIONotifier::QPurpleIONotifier() + : defaultConstructed(1) { + QPurpleIONotifier::QPurpleIONotifier (int fd, PurpleGLibIOClosure *c, PurpleInputCondition pic) + : closure(c), purpleInputCondition(pic), defaultConstructed(0) { + //if (pic & PURPLE_GLIB_WRITE_COND) { + if (pic & PURPLE_INPUT_WRITE) { + this->writeCond = new QSocketNotifier(fd, QSocketNotifier::Write); + QObject::connect(this->writeCond, SIGNAL(activated(int)), this, SLOT(callFunc(int))); + this->writeCond = NULL; } + if (pic & PURPLE_INPUT_READ) { + this->readCond = new QSocketNotifier(fd, QSocketNotifier::Read); + QObject::connect(this->readCond, SIGNAL(activated(int)), this, SLOT(callFunc(int))); + this->readCond = NULL; } + QPurpleIONotifier::~QPurpleIONotifier() { + if (this->readCond != NULL) { + this->readCond->setEnabled(false); + delete this->readCond; } + if (this->writeCond != NULL) { + this->writeCond->setEnabled(false); + delete this->writeCond; } + // analogous to purple_glib_io_invoke from nullclient + void QPurpleIONotifier::callFunc(int fd) { + closure->function(closure->data, fd, + this->purpleInputCondition); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpurpleionotifier.h Mon Jul 26 01:12:37 2010 -0500
@@ -0,0 +1,25 @@
+#ifndef QPURPLEIONOTIFIER_H +#define QPURPLEIONOTIFIER_H + class QPurpleIONotifier : QObject { + Q_OBJECT // required by Qt + QSocketNotifier *readCond, *writeCond; + PurpleGLibIOClosure *closure; + PurpleInputCondition purpleInputCondition; + QPurpleIONotifier(int fd, PurpleGLibIOClosure *c, PurpleInputCondition pic); + int defaultConstructed; +#endif // QPURPLEIONOTIFIER_H --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpurpletimer.cpp Mon Jul 26 01:12:37 2010 -0500
@@ -0,0 +1,30 @@
+#include "qpurpletimer.h" + QPurpleTimer::QPurpleTimer() + : func(NULL), data(NULL), defaultConstructed(1) { + QPurpleTimer::QPurpleTimer(GSourceFunc f, gpointer d, int i) + : func(f), data(d), defaultConstructed(0) { + this->timer = new QTimer(); + this->timer->setInterval(i); + connect(this->timer, SIGNAL(timeout()),this, SLOT(callFunc())); + QPurpleTimer::~QPurpleTimer() { + void QPurpleTimer::callFunc() { + gboolean res = this->func(this->data); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpurpletimer.h Mon Jul 26 01:12:37 2010 -0500
@@ -0,0 +1,25 @@
+ class QPurpleTimer : QObject { + Q_OBJECT // required by Qt + QPurpleTimer(GSourceFunc f, gpointer d, int i); + int defaultConstructed; +#endif // QPURPLETIMER_H