pidgin/quail/qpurple

Parents e8af10acac1a
Children ccb0603bc6f4
Turn QPurple into a class so that it can emit signals to a UI
  • +1 -0
    .hgignore
  • +186 -166
    qpurple.cpp
  • +39 -4
    qpurple.h
  • +1 -0
    qpurple.pro
  • +1 -0
    qpurpleionotifier.h
  • --- a/.hgignore Fri Jun 14 16:11:00 2013 +0100
    +++ b/.hgignore Mon Jun 17 07:24:52 2013 +0100
    @@ -4,6 +4,7 @@
    *.user
    *~
    Quail.exe
    +libqpurple*
    *.pdb
    *.o
    *.lib
    --- a/qpurple.cpp Fri Jun 14 16:11:00 2013 +0100
    +++ b/qpurple.cpp Mon Jun 17 07:24:52 2013 +0100
    @@ -5,185 +5,205 @@
    namespace QPurple {
    - // 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
    +// unique handle for our input events (QPurpleIONotifiers and QPurpleTimers)
    +unsigned int unique_handle = 0;
    - static guint qt_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function,
    - gpointer data)
    - {
    - PurpleGLibIOClosure *closure = g_new0(PurpleGLibIOClosure, 1);
    - int handle;
    -
    - closure->function = function;
    - closure->data = data;
    +QMap< int , QPurpleIONotifier* > notifierMap;
    +QMap< int , QPurpleTimer* > timerMap;
    - // modified from the nullclient source to integrate with Qt
    - handle = unique_handle++; // this will be unique, certainly
    - notifierMap[handle] = new QPurpleIONotifier(fd, closure, condition);
    -
    - return handle;
    - }
    +// Event loop functions
    +static guint
    +QPurpleCore::qpurple_input_add(gint fd,
    + PurpleInputCondition condition,
    + PurpleInputFunction function,
    + gpointer data)
    +{
    + PurpleGLibIOClosure *closure = g_new0(PurpleGLibIOClosure, 1);
    + int handle;
    - static gboolean qt_input_remove(guint handle) {
    - int toReturn = 0;
    - QPurpleIONotifier *tmp = notifierMap.take(handle);
    - if (!tmp->defaultConstructed) {
    - toReturn = 1;
    - delete tmp; }
    - return toReturn;
    - }
    + closure->function = function;
    + closure->data = data;
    - static guint qt_timer_add(guint interval, GSourceFunc function, gpointer data) {
    - int handle = unique_handle++;
    - timerMap[handle] = new QPurpleTimer(function, data, interval);
    - return handle;
    - }
    + // 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 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) {
    - int toReturn = 0;
    - QPurpleTimer *tmp = timerMap.take(handle);
    - if (!tmp->defaultConstructed) { // we removed something
    - toReturn = 1;
    - delete tmp; }
    -
    - return toReturn;
    - }
    + return handle;
    +}
    - static PurpleEventLoopUiOps qt_eventloops =
    - {
    - qt_timer_add,
    - qt_timer_remove,
    - qt_input_add,
    - qt_input_remove,
    - NULL,
    - qt_timer_add_seconds,
    +static gboolean
    +QPurpleCore::qpurple_input_remove(guint handle)
    +{
    + int toReturn = 0;
    + QPurpleIONotifier *tmp = notifierMap.take(handle);
    + if (!tmp->defaultConstructed) {
    + toReturn = 1;
    + delete tmp; }
    + return toReturn;
    +}
    - /* padding */
    - NULL,
    - NULL,
    - NULL
    - };
    -
    - static void
    - qt_write_conv(PurpleConversation *conv, const char *who, const char *alias,
    - const char *message, PurpleMessageFlags flags, time_t mtime)
    - {
    - Q_UNUSED(alias)
    - Q_UNUSED(flags)
    - printf("(%s) %s %s: %s\n", purple_conversation_get_name(conv),
    - purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),
    - who, message);
    - }
    +static guint
    +QPurpleCore::qpurple_timer_add(guint interval,
    + GSourceFunc function,
    + gpointer data)
    +{
    + int handle = unique_handle++;
    + timerMap[handle] = new QPurpleTimer(function, data, interval);
    + return handle;
    +}
    - static PurpleConversationUiOps null_conv_uiops =
    - {
    - NULL, /* create_conversation */
    - NULL, /* destroy_conversation */
    - NULL, /* write_chat */
    - NULL, /* write_im */
    - qt_write_conv, /* write_conv */
    - NULL, /* chat_add_users */
    - NULL, /* chat_rename_user */
    - NULL, /* chat_remove_users */
    - NULL, /* chat_update_user */
    - NULL, /* present */
    - NULL, /* has_focus */
    - NULL, /* custom_smiley_add */
    - NULL, /* custom_smiley_write */
    - NULL, /* custom_smiley_close */
    - NULL, /* send_confirm */
    - NULL,
    - NULL,
    - NULL,
    - NULL
    - };
    +static guint
    +QPurpleCore::qpurple_timer_add_seconds(guint interval,
    + GSourceFunc function,
    + gpointer data)
    +{
    + return qpurple_timer_add(interval * 1000,function, data);
    +}
    - static void
    - qt_ui_init(void)
    - {
    - /**
    - * 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 gboolean
    +QPurpleCore::qpurple_timer_remove(guint handle)
    +{
    + int toReturn = 0;
    + QPurpleTimer *tmp = timerMap.take(handle);
    + if (!tmp->defaultConstructed) { // we removed something
    + toReturn = 1;
    + delete tmp; }
    - static PurpleCoreUiOps null_core_uiops =
    - {
    - NULL,
    - NULL,
    - qt_ui_init,
    - NULL,
    -
    - /* padding */
    - NULL,
    - NULL,
    - NULL,
    - NULL
    - };
    + return toReturn;
    +}
    - static void
    - _init_libpurple(void)
    - {
    - /* 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);
    +static PurpleEventLoopUiOps qpurple_eventloops =
    +{
    + qpurple_timer_add,
    + qpurple_timer_remove,
    + qpurple_input_add,
    + qpurple_input_remove,
    + NULL,
    + qpurple_timer_add_seconds,
    - /* 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. */
    - fprintf(stderr,
    - "libpurple initialization failed. Dumping core.\n"
    - "Please report this!\n");
    - abort();
    - }
    + /* padding */
    + NULL,
    + NULL,
    + NULL
    +};
    - /* Create and load the buddylist. */
    - purple_set_blist(purple_blist_new());
    - purple_blist_load();
    -
    - /* Load the preferences. */
    - purple_prefs_load();
    -
    - /* 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();
    - }
    +static void
    +QPurpleCore::qpurple_write_conv(PurpleConversation *conv,
    + const char *who,
    + const char *alias,
    + const char *message,
    + PurpleMessageFlags flags,
    + time_t mtime)
    +{
    + Q_UNUSED(alias)
    + Q_UNUSED(flags)
    + printf("(%s) %s %s: %s\n", purple_conversation_get_name(conv),
    + purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),
    + who, message);
    }
    -void qpurple_init() {
    - QPurple::_init_libpurple();
    +static PurpleConversationUiOps qpurple_conv_uiops =
    +{
    + NULL, /* create_conversation */
    + NULL, /* destroy_conversation */
    + NULL, /* write_chat */
    + NULL, /* write_im */
    + qpurple_write_conv, /* write_conv */
    + NULL, /* chat_add_users */
    + NULL, /* chat_rename_user */
    + NULL, /* chat_remove_users */
    + NULL, /* chat_update_user */
    + NULL, /* present */
    + NULL, /* has_focus */
    + NULL, /* custom_smiley_add */
    + NULL, /* custom_smiley_write */
    + NULL, /* custom_smiley_close */
    + NULL, /* send_confirm */
    + NULL,
    + NULL,
    + NULL,
    + NULL
    +};
    +
    +static void
    +QPurpleCore::qpurple_ui_init(void)
    +{
    + /**
    + * This should initialize the UI components for all the modules. Here we
    + * just initialize the UI for conversations.
    + */
    + purple_conversations_set_ui_ops(&qpurple_conv_uiops);
    }
    +
    +static PurpleCoreUiOps qpurple_core_uiops =
    +{
    + NULL,
    + NULL,
    + qpurple_ui_init,
    + NULL,
    +
    + /* padding */
    + NULL,
    + NULL,
    + NULL,
    + NULL
    +};
    +
    +static void
    +QPurpleCore::_init_libpurple(void)
    +{
    + /* 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(&qpurple_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(&qpurple_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. */
    + fprintf(stderr,
    + "libpurple initialization failed. Dumping core.\n"
    + "Please report this!\n");
    + abort();
    + }
    +
    + /* Create and load the buddylist. */
    + purple_set_blist(purple_blist_new());
    + purple_blist_load();
    +
    + /* Load the preferences. */
    + purple_prefs_load();
    +
    + /* 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();
    +}
    +
    +void
    +QPurpleCore::qpurple_init() {
    + QPurpleCore::_init_libpurple();
    +}
    +
    +}
    --- a/qpurple.h Fri Jun 14 16:11:00 2013 +0100
    +++ b/qpurple.h Mon Jun 17 07:24:52 2013 +0100
    @@ -15,21 +15,56 @@
    #define CUSTOM_USER_DIRECTORY "/dev/null"
    #define CUSTOM_PLUGIN_PATH ""
    -#define PLUGIN_SAVE_PREF "/purple/nullclient/plugins/saved"
    -#define UI_ID "hermes"
    +#define PLUGIN_SAVE_PREF "/purple/qpurple/plugins/saved"
    +#define UI_ID "quail"
    #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)
    namespace QPurple {
    +class QPurpleCore : QObject
    +{
    + Q_OBJECT
    +
    + QPurpleCore();
    + ~QPurpleCore();
    +
    typedef struct _PurpleGLibIOClosure {
    PurpleInputFunction function;
    guint result;
    gpointer data;
    } PurpleGLibIOClosure;
    +
    + void qpurple_init(); // call this in main to start libpurple
    +
    +signals:
    +
    +
    +private:
    + static guint qpurple_input_add(gint fd,
    + PurpleInputCondition condition,
    + PurpleInputFunction function,
    + gpointer data);
    + static gboolean qpurple_input_remove(guint handle);
    + static guint qpurple_timer_add(guint interval,
    + GSourceFunc function,
    + gpointer data);
    + static guint qpurple_timer_add_seconds(guint interval,
    + GSourceFunc function,
    + gpointer data);
    + static gboolean qpurple_timer_remove(guint handle);
    + static void qpurple_write_conv(PurpleConversation *conv,
    + const char *who,
    + const char *alias,
    + const char *message,
    + PurpleMessageFlags flags,
    + time_t mtime);
    + static void _init_libpurple(void);
    + static void qpurple_ui_init(void);
    +
    +};
    +
    }
    -void qpurple_init(); // call this in main to start libpurple
    -
    #endif
    --- a/qpurple.pro Fri Jun 14 16:11:00 2013 +0100
    +++ b/qpurple.pro Mon Jun 17 07:24:52 2013 +0100
    @@ -36,3 +36,4 @@
    HEADERS += qpurple.h \
    qpurpletimer.h \
    qpurpleionotifier.h
    +
    --- a/qpurpleionotifier.h Fri Jun 14 16:11:00 2013 +0100
    +++ b/qpurpleionotifier.h Mon Jun 17 07:24:52 2013 +0100
    @@ -2,6 +2,7 @@
    #define QPURPLEIONOTIFIER_H
    #include "qpurple.h"
    +#include "purple.h"
    namespace QPurple {