--- a/libpurple/eventloop.c Thu Jun 15 11:21:45 2017 -0500 +++ b/libpurple/eventloop.c Thu Jun 15 11:35:00 2017 -0500 @@ -21,8 +21,17 @@ #include "internal.h" #include "eventloop.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) + static PurpleEventLoopUiOps *eventloop_ui_ops = NULL; +typedef struct _PurpleIOClosure { + PurpleInputFunction function; + guint result; + gpointer data; +} PurpleIOClosure; + guint purple_timeout_add(guint interval, GSourceFunc function, gpointer data) { @@ -41,20 +50,61 @@ return g_source_remove(tag); } +static gboolean +purple_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data) +{ + PurpleIOClosure *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; + +#ifdef _WIN32 + if(!purple_cond) { + return TRUE; + } +#endif /* _WIN32 */ + + closure->function(closure->data, g_io_channel_unix_get_fd(source), + purple_cond); + + return TRUE; +} + guint purple_input_add(int source, PurpleInputCondition condition, PurpleInputFunction func, gpointer user_data) { - PurpleEventLoopUiOps *ops = purple_eventloop_get_ui_ops(); + PurpleIOClosure *closure = g_new0(PurpleIOClosure, 1); + GIOChannel *channel; + GIOCondition cond = 0; + + closure->function = func; + closure->data = user_data; + + if (condition & PURPLE_INPUT_READ) + cond |= PURPLE_GLIB_READ_COND; + if (condition & PURPLE_INPUT_WRITE) + cond |= PURPLE_GLIB_WRITE_COND; - return ops->input_add(source, condition, func, user_data); +#ifdef _WIN32 + channel = g_io_channel_win32_new_socket(source); +#else + channel = g_io_channel_unix_new(source); +#endif + + closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, + cond, purple_io_invoke, closure, g_free); + + g_io_channel_unref(channel); + return closure->result; } gboolean purple_input_remove(guint tag) { - PurpleEventLoopUiOps *ops = purple_eventloop_get_ui_ops(); - - return ops->input_remove(tag); + return g_source_remove(tag); } int