aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/purple/purple.c
diff options
context:
space:
mode:
authorjgeboski <jgeboski@gmail.com>2016-06-24 16:21:42 -0400
committerMarius Halden <marius.h@lden.org>2016-07-13 09:32:00 +0200
commitf10e02c3db78cb1ebeef559c8094048904b7ec6c (patch)
tree0da413d94aac26e6b43cfd2c66994ed04ef919be /protocols/purple/purple.c
parente6314bd1c75979f6ec71cd1301239bccca7618a4 (diff)
purple: added room listing support
Diffstat (limited to 'protocols/purple/purple.c')
-rw-r--r--protocols/purple/purple.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/protocols/purple/purple.c b/protocols/purple/purple.c
index c10d435b..114fec82 100644
--- a/protocols/purple/purple.c
+++ b/protocols/purple/purple.c
@@ -365,6 +365,21 @@ static void purple_login(account_t *acc)
}
}
+static void purple_chatlist_free(struct im_connection *ic)
+{
+ bee_chat_info_t *ci;
+ GSList *l = ic->chatlist;
+
+ while (l) {
+ ci = l->data;
+ l = g_slist_delete_link(l, l);
+
+ g_free(ci->title);
+ g_free(ci->topic);
+ g_free(ci);
+ }
+}
+
static void purple_logout(struct im_connection *ic)
{
struct purple_data *pd = ic->proto_data;
@@ -382,6 +397,7 @@ static void purple_logout(struct im_connection *ic)
purple_account_set_enabled(pd->account, "BitlBee", FALSE);
purple_connections = g_slist_remove(purple_connections, ic);
purple_accounts_remove(pd->account);
+ purple_chatlist_free(ic);
g_hash_table_destroy(pd->input_requests);
g_free(pd);
}
@@ -745,6 +761,18 @@ struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, c
return imcb_chat_new(ic, room);
}
+void purple_chat_list(struct im_connection *ic, const char *server)
+{
+ PurpleRoomlist *list;
+ struct purple_data *pd = ic->proto_data;
+
+ list = purple_roomlist_get_list(pd->account->gc);
+
+ if (list == NULL) {
+ imcb_log(ic, "Room listing unsupported by this purple plugin");
+ }
+}
+
void purple_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *handle);
static void purple_ui_init();
@@ -1280,6 +1308,116 @@ static PurplePrivacyUiOps bee_privacy_uiops =
prplcb_privacy_deny_removed, /* deny_removed */
};
+static void prplcb_roomlist_create(PurpleRoomlist *list)
+{
+ struct purple_roomlist_data *rld;
+
+ list->ui_data = rld = g_new0(struct purple_roomlist_data, 1);
+ rld->topic = -1;
+ rld->userc = -1;
+}
+
+static void prplcb_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
+{
+ gint topic = -1;
+ GList *l;
+ guint i;
+ PurpleRoomlistField *field;
+ struct purple_roomlist_data *rld = list->ui_data;
+
+ for (i = 0, l = fields; l; i++, l = l->next) {
+ field = l->data;
+
+ /* Use the first visible string field as a fallback topic */
+ if (i != 0 && topic < 0 && !field->hidden &&
+ field->type == PURPLE_ROOMLIST_FIELD_STRING) {
+ topic = i;
+ }
+
+ if ((g_strcasecmp(field->name, "description") == 0) ||
+ (g_strcasecmp(field->name, "topic") == 0)) {
+ if (field->type == PURPLE_ROOMLIST_FIELD_STRING) {
+ rld->topic = i;
+ }
+ } else if (g_strcasecmp(field->name, "users") == 0) {
+ if (field->type == PURPLE_ROOMLIST_FIELD_INT) {
+ rld->userc = i;
+ }
+ }
+ }
+
+ if (rld->topic < 0) {
+ rld->topic = topic;
+ }
+}
+
+static void prplcb_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room)
+{
+ bee_chat_info_t *ci;
+ const char *title;
+ const char *topic;
+ GList *fields;
+ gpointer data;
+ struct purple_roomlist_data *rld = list->ui_data;
+
+ fields = purple_roomlist_room_get_fields(room);
+ title = purple_roomlist_room_get_name(room);
+
+ if (rld->topic >= 0) {
+ topic = g_list_nth_data(fields, rld->topic);
+ } else {
+ topic = NULL;
+ }
+
+ ci = g_new(bee_chat_info_t, 1);
+ ci->title = g_strdup(title);
+ ci->topic = g_strdup(topic);
+ rld->chats = g_slist_prepend(rld->chats, ci);
+
+ if (rld->userc >= 0) {
+ data = g_list_nth_data(fields, rld->userc);
+ ci->userc = GPOINTER_TO_INT(data);
+ } else {
+ ci->userc = -1;
+ }
+}
+
+static void prplcb_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progress)
+{
+ struct im_connection *ic;
+ struct purple_roomlist_data *rld = list->ui_data;
+
+ if (in_progress) {
+ return;
+ }
+
+ ic = purple_ic_by_pa(list->account);
+ purple_chatlist_free(ic);
+
+ ic->chatlist = g_slist_reverse(rld->chats);
+ rld->chats = NULL;
+
+ bee_chat_list_finish(ic);
+ purple_roomlist_unref(list);
+}
+
+static void prplcb_roomlist_destroy(PurpleRoomlist *list)
+{
+ /* bee_chat_list_finish() frees rld->chats */
+ g_free(list->ui_data);
+ list->ui_data = NULL;
+}
+
+static PurpleRoomlistUiOps bee_roomlist_uiops =
+{
+ NULL, /* show_with_account */
+ prplcb_roomlist_create, /* create */
+ prplcb_roomlist_set_fields, /* set_fields */
+ prplcb_roomlist_add_room, /* add_room */
+ prplcb_roomlist_in_progress, /* in_progress */
+ prplcb_roomlist_destroy, /* destroy */
+};
+
static void prplcb_debug_print(PurpleDebugLevel level, const char *category, const char *arg_s)
{
fprintf(stderr, "DEBUG %s: %s", category, arg_s);
@@ -1444,6 +1582,7 @@ static void purple_ui_init()
purple_conversations_set_ui_ops(&bee_conv_uiops);
purple_request_set_ui_ops(&bee_request_uiops);
purple_privacy_set_ui_ops(&bee_privacy_uiops);
+ purple_roomlist_set_ui_ops(&bee_roomlist_uiops);
purple_notify_set_ui_ops(&bee_notify_uiops);
purple_accounts_set_ui_ops(&bee_account_uiops);
purple_xfers_set_ui_ops(&bee_xfer_uiops);
@@ -1535,6 +1674,7 @@ void purple_initmodule()
funcs.chat_kick = purple_chat_kick;
funcs.chat_leave = purple_chat_leave;
funcs.chat_join = purple_chat_join;
+ funcs.chat_list = purple_chat_list;
funcs.transfer_request = purple_transfer_request;
help = g_string_new("BitlBee libpurple module supports the following IM protocols:\n");