summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/weechat.c58
-rw-r--r--src/rexmpp.c1
-rw-r--r--src/rexmpp.h2
-rw-r--r--src/rexmpp_roster.c12
4 files changed, 73 insertions, 0 deletions
diff --git a/examples/weechat.c b/examples/weechat.c
index d247eb3..0c26f6e 100644
--- a/examples/weechat.c
+++ b/examples/weechat.c
@@ -140,6 +140,7 @@ int my_xml_in_cb (struct weechat_rexmpp *wr, xmlNodePtr node) {
buf = weechat_buffer_new (from,
&query_input_cb, wr, NULL,
&query_close_cb, wr, NULL);
+ weechat_buffer_set(buf, "nicklist", "1");
}
if (resource_removed) {
from[i] = '/'; /* restore */
@@ -157,6 +158,39 @@ int my_xml_in_cb (struct weechat_rexmpp *wr, xmlNodePtr node) {
xmlFree(from);
}
}
+ if (rexmpp_xml_match(node, "jabber:client", "presence")) {
+ char *presence_type = xmlGetProp(node, "type");
+ char *jid = xmlGetProp(node, "from");
+ int i;
+ char *resource = "";
+ for (i = 0; i < strlen(jid); i++) {
+ if (jid[i] == '/') {
+ jid[i] = 0;
+ resource = jid + i + 1;
+ break;
+ }
+ }
+ if (rexmpp_xml_find_child(node, "http://jabber.org/protocol/muc#user", "x")) {
+ /* Update MUC nicklist */
+ struct t_gui_buffer *buf = weechat_buffer_search("rexmpp", jid);
+ if (buf != NULL) {
+ if (presence_type != NULL && strcmp(presence_type, "unavailable") == 0) {
+ struct t_gui_nick *nick =
+ weechat_nicklist_search_nick(buf, NULL, resource);
+ if (nick != NULL) {
+ weechat_nicklist_remove_nick(buf, nick);
+ }
+ } else {
+ weechat_nicklist_add_nick(buf, NULL, resource,
+ "bar_fg", "", "lightgreen", 1);
+ }
+ }
+ }
+ free(jid);
+ if (presence_type != NULL) {
+ free(presence_type);
+ }
+ }
free(xml_buf);
return 0;
}
@@ -194,6 +228,7 @@ my_input_cb (const struct weechat_rexmpp *wr, void *data,
buf = weechat_buffer_new (jid,
&query_input_cb, wr, NULL,
&query_close_cb, wr, NULL);
+ weechat_buffer_set(buf, "nicklist", "1");
}
} else if (input_data[0] == 'j' && input_data[1] == ' ') {
char *jid = input_data + 2;
@@ -219,14 +254,35 @@ my_input_cb (const struct weechat_rexmpp *wr, void *data,
buf = weechat_buffer_new (jid,
&muc_input_cb, wrm, NULL,
&muc_close_cb, wrm, NULL);
+ weechat_buffer_set(buf, "nicklist", "1");
}
}
return WEECHAT_RC_OK;
}
+void my_roster_modify_cb (struct weechat_rexmpp *wr, xmlNodePtr item) {
+ char *subscription = xmlGetProp(item, "subscription");
+ char *jid = xmlGetProp(item, "jid");
+ if (subscription != NULL && strcmp(subscription, "remove") == 0) {
+ /* delete */
+ weechat_nicklist_remove_nick(wr->server_buffer, jid);
+ } else {
+ /* add or modify */
+ weechat_nicklist_add_nick(wr->server_buffer, NULL, jid,
+ "bar_fg", "", "lightgreen", 1);
+ }
+ free(jid);
+ if (subscription != NULL) {
+ free(subscription);
+ }
+}
+
int
my_close_cb (struct weechat_rexmpp *wr, void *data, struct t_gui_buffer *buffer)
{
+ /* todo: close MUC buffers first? or at least mark them somehow, so
+ that they won't attempt to send "unavailable" presence on
+ closing. */
wr->server_buffer = NULL;
rexmpp_stop(&wr->rexmpp_state);
return WEECHAT_RC_OK;
@@ -331,6 +387,7 @@ command_xmpp_cb (const void *pointer, void *data,
wr->server_buffer = weechat_buffer_new (argv[1],
&my_input_cb, wr, NULL,
&my_close_cb, wr, NULL);
+ weechat_buffer_set(wr->server_buffer, "nicklist", "1");
wr->password = strdup(argv[2]);
wr->hooks = weechat_arraylist_new(42, 0, 0, NULL, NULL, hook_free_cb, NULL);
rexmpp_t *s = &wr->rexmpp_state;
@@ -339,6 +396,7 @@ command_xmpp_cb (const void *pointer, void *data,
s->sasl_property_cb = my_sasl_property_cb;
s->xml_in_cb = my_xml_in_cb;
s->xml_out_cb = my_xml_out_cb;
+ s->roster_modify_cb = my_roster_modify_cb;
fd_set read_fds, write_fds;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
diff --git a/src/rexmpp.c b/src/rexmpp.c
index 02dcf5b..c4c1e1c 100644
--- a/src/rexmpp.c
+++ b/src/rexmpp.c
@@ -268,6 +268,7 @@ rexmpp_err_t rexmpp_init (rexmpp_t *s, const char *jid)
s->sasl_property_cb = NULL;
s->xml_in_cb = NULL;
s->xml_out_cb = NULL;
+ s->roster_modify_cb = NULL;
s->ping_delay = 600;
s->ping_requested = 0;
s->last_network_activity = 0;
diff --git a/src/rexmpp.h b/src/rexmpp.h
index 9f748cf..6157f86 100644
--- a/src/rexmpp.h
+++ b/src/rexmpp.h
@@ -202,6 +202,7 @@ typedef void (*log_function_t) (rexmpp_t *s, int priority, const char *format, v
typedef int (*sasl_property_cb_t) (rexmpp_t *s, Gsasl_property prop);
typedef int (*xml_in_cb_t) (rexmpp_t *s, xmlNodePtr node);
typedef int (*xml_out_cb_t) (rexmpp_t *s, xmlNodePtr node);
+typedef void (*roster_modify_cb_t) (rexmpp_t *s, xmlNodePtr item);
/** @brief Complete connection state */
struct rexmpp
@@ -248,6 +249,7 @@ struct rexmpp
sasl_property_cb_t sasl_property_cb;
xml_in_cb_t xml_in_cb;
xml_out_cb_t xml_out_cb;
+ roster_modify_cb_t roster_modify_cb;
/* Stream-related state. */
char *assigned_jid;
diff --git a/src/rexmpp_roster.c b/src/rexmpp_roster.c
index 8479c14..3d62613 100644
--- a/src/rexmpp_roster.c
+++ b/src/rexmpp_roster.c
@@ -81,6 +81,9 @@ rexmpp_err_t rexmpp_modify_roster (rexmpp_t *s, xmlNodePtr item) {
if (subscription != NULL) {
free(subscription);
}
+ if (s->roster_modify_cb != NULL) {
+ s->roster_modify_cb(s, item);
+ }
return ret;
}
@@ -93,6 +96,15 @@ void rexmpp_roster_set (rexmpp_t *s, xmlNodePtr query) {
}
s->roster_ver = xmlGetProp(query, "ver");
s->roster_items = xmlCopyNodeList(xmlFirstElementChild(query));
+ if (s->roster_modify_cb != NULL) {
+ xmlNodePtr item;
+ for (item = xmlFirstElementChild(query);
+ item != NULL;
+ item = xmlNextElementSibling(item))
+ {
+ s->roster_modify_cb(s, item);
+ }
+ }
}
void rexmpp_roster_cache_read (rexmpp_t *s) {