--- /dev/null
+#include <purple.h>
+
+#include <glib.h>
+
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "c_purple.h"
+
+#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)
+
+typedef struct _PurpleGLibIOClosure {
+ PurpleInputFunction function;
+ guint result;
+ gpointer data;
+} PurpleGLibIOClosure;
+
+static void purple_glib_io_destroy(gpointer data)
+{
+ g_free(data);
+}
+
+static gboolean purple_glib_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ PurpleGLibIOClosure *closure = data;
+ PurpleInputCondition purple_cond = 0;
+
+ if (condition & PURPLE_GLIB_READ_COND)
+ purple_cond |= PURPLE_INPUT_READ;
+ if (condition & PURPLE_GLIB_WRITE_COND)
+ purple_cond |= PURPLE_INPUT_WRITE;
+
+ closure->function(closure->data, g_io_channel_unix_get_fd(source),
+ purple_cond);
+
+ return TRUE;
+}
+
+static guint glib_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function,
+ gpointer data)
+{
+ PurpleGLibIOClosure *closure = g_new0(PurpleGLibIOClosure, 1);
+ GIOChannel *channel;
+ GIOCondition cond = 0;
+
+ closure->function = function;
+ closure->data = data;
+
+ if (condition & PURPLE_INPUT_READ)
+ cond |= PURPLE_GLIB_READ_COND;
+ if (condition & PURPLE_INPUT_WRITE)
+ cond |= PURPLE_GLIB_WRITE_COND;
+
+ channel = g_io_channel_unix_new(fd);
+ closure->result = g_io_add_watch_full(channel, 0, cond,
+ purple_glib_io_invoke, closure, purple_glib_io_destroy);
+
+ g_io_channel_unref(channel);
+ return closure->result;
+}
+
+static PurpleEventLoopUiOps glib_eventloops =
+{
+ g_timeout_add,
+ g_source_remove,
+ glib_input_add,
+ g_source_remove,
+ NULL,
+#if GLIB_CHECK_VERSION(2,14,0)
+ g_timeout_add_seconds,
+#else
+ NULL,
+#endif
+
+ /* padding */
+ NULL,
+ NULL,
+ NULL
+};
+/*** End of the eventloop functions. ***/
+
+/*** Conversation uiops ***/
+/* FIXME: Revisit this function. Is it needed? How it should be more general?*/
+static void
+write_conv(PurpleConversation *conv, const char *who, const char *alias,
+ const char *message, PurpleMessageFlags flags, time_t mtime)
+{
+ const char *name;
+ if (alias && *alias)
+ name = alias;
+ else if (who && *who)
+ name = who;
+ else
+ name = NULL;
+
+ printf("(%s) %s %s: %s\n", purple_conversation_get_name(conv),
+ purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),
+ name, message);
+}
+
+static PurpleConversationUiOps conv_uiops =
+{
+ NULL, /* create_conversation */
+ NULL, /* destroy_conversation */
+ NULL, /* write_chat */
+ NULL, /* write_im */
+ 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
+};
+
+/* FIXME: Is this a valid struct? */
+static void
+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(&conv_uiops);
+}
+
+static PurpleCoreUiOps core_uiops =
+{
+ NULL,
+ NULL,
+ ui_init,
+ NULL,
+
+ /* padding */
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+void init_libpurple(void)
+{
+ /* Set a custom user directory (optional) */
+ /* FIXME: Put a valid carman directory here*/
+ 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);
+
+ purple_core_set_ui_ops(&core_uiops);
+
+ purple_eventloop_set_ui_ops(&glib_eventloops);
+
+ purple_plugins_add_search_path(CUSTOM_PLUGIN_PATH);
+
+ if (!purple_core_init(UI_ID)) {
+ /* Initializing the core failed. Terminate. */
+ fprintf(stderr,
+ "libpurple initialization failed. Dumping core.\n"
+ "Please report this!\n");
+ abort();
+ }
+ printf("libpurple initialized");
+}
cdef extern from "time.h":
ctypedef long int time_t
-include "glib.pxd"
-include "core/account.pxd"
-include "core/blist.pxd"
-include "core/connection.pxd"
-include "core/core.pxd"
-include "core/debug.pxd"
-include "core/eventloop.pxd"
-include "core/idle.pxd"
-include "core/plugin.pxd"
-include "core/pounce.pxd"
-include "core/prefs.pxd"
-include "core/util.pxd"
+class Core(object):
+ def init(self):
+ init_libpurple()
+
+include "c_purple.pxd"
+#include "glib.pxd"
+#include "core/account.pxd"
+#include "core/blist.pxd"
+#include "core/connection.pxd"
+#include "core/core.pxd"
+#include "core/debug.pxd"
+#include "core/eventloop.pxd"
+#include "core/idle.pxd"
+#include "core/plugin.pxd"
+#include "core/pounce.pxd"
+#include "core/prefs.pxd"
+#include "core/util.pxd"
cflags = Popen(['pkg-config', '--cflags', 'purple'], stdout=PIPE).communicate()[0].split()
ldflags = Popen(['pkg-config', '--libs', 'purple'], stdout=PIPE).communicate()[0].split()
+print ldflags
class pypurple_build_ext(build_ext):
def finalize_options(self):
author ='Bruno Abinader',
author_email='bruno.abinader@openbossa.org',
ext_modules=[Extension('purple',
- sources=['purple.pyx'],
+ sources=['c_purple.c','purple.pyx'],
extra_compile_args=cflags,
extra_link_args=ldflags)],
cmdclass = {'build_ext': pypurple_build_ext},