# HG changeset patch # User Mikael Berthe # Date 1162118580 -3600 # Node ID ed697234bd39e526f6cb26cb30ade07fc43daf9f # Parent b33ca4e1c37d05ed4d99524ee202fbe01132db8c Chat states receival (Alexis Hildebrandt) Patch from Alexis Hildebrandt, slightly modified (mostly coding style updates). diff -r b33ca4e1c37d -r ed697234bd39 mcabber/src/jabglue.c --- a/mcabber/src/jabglue.c Sat Oct 28 18:14:22 2006 +0200 +++ b/mcabber/src/jabglue.c Sun Oct 29 11:43:00 2006 +0100 @@ -51,6 +51,7 @@ static void statehandler(jconn, int); static void packethandler(jconn, jpacket); +void handle_state_events(char* from, xmlnode xmldata); static void logger(jconn j, int io, const char *buf) { @@ -429,6 +430,22 @@ y = xmlnode_insert_tag(x, "subject"); xmlnode_insert_cdata(y, subject, (unsigned) -1); } + + // TODO: insert event notifications request +#undef USE_JEP_85 +#ifdef USE_JEP_85 +#define NS_CHAT_STATES "http://jabber.org/features/chatstates" + // JEP-85 + xmlnode event = xmlnode_insert_tag(x, "composing"); + xmlnode_put_attrib(event, "xmlns", NS_CHAT_STATES); +#else + // JEP-22 + xmlnode event = xmlnode_insert_tag(x, "x"); + xmlnode_put_attrib(event, "xmlns", NS_EVENT); + xmlnode_insert_tag(event, "composing"); +#endif + + jab_send(jc, x); xmlnode_free(x); @@ -1422,6 +1439,8 @@ } } + handle_state_events(from, xmldata); + // Not used yet... x = xml_get_xmlns(xmldata, NS_ENCRYPTED); if (x && (p = xmlnode_get_data(x)) != NULL) { @@ -1440,6 +1459,52 @@ g_free(tmp); } +void handle_state_events(char* from, xmlnode xmldata) +{ + xmlnode x = NULL; + char *rname = strchr(from, JID_RESOURCE_SEPARATOR) + 1; + char *jid = jidtodisp(from); + GSList *slist = roster_find(jid, jidsearch, ROSTER_TYPE_USER); + if (slist == NULL) return; + int jep85 = 0; + + guint events = buddy_resource_getevents(slist->data, rname); + + x = xml_get_xmlns(xmldata, NS_EVENT); + if (x == NULL) { + x = xmldata; + jep85 = 1; + } + + xmlnode tag = xmlnode_get_tag(x, "composing"); + if (tag != NULL) { + events |= ROSTER_EVENT_COMPOSING; + } else if (!jep85) { + events &= ~ROSTER_EVENT_COMPOSING; + } + + if (jep85) { + tag = xmlnode_get_tag(x, "paused"); + if (tag != NULL) { + events &= ~ROSTER_EVENT_COMPOSING; + } + } + + // clear composing and set new message event + // if message contains message body + if (xmlnode_get_tag_data(xmldata, "body") != NULL) { + events |= ROSTER_EVENT_MSG; + events &= ~ROSTER_EVENT_COMPOSING; + } + + buddy_resource_setevents(slist->data, rname, events); + + scr_UpdateBuddyWindow(); + scr_DrawRoster(); + + g_free(jid); +} + static void evscallback_subscription(eviqs *evp, guint evcontext) { char *barejid; diff -r b33ca4e1c37d -r ed697234bd39 mcabber/src/roster.c --- a/mcabber/src/roster.c Sat Oct 28 18:14:22 2006 +0200 +++ b/mcabber/src/roster.c Sun Oct 29 11:43:00 2006 +0100 @@ -51,6 +51,7 @@ enum imrole role; enum imaffiliation affil; gchar *realjid; /* for chatrooms, if buddy's real jid is known */ + guint events; } res; /* This is a private structure type for the roster */ @@ -1062,6 +1063,32 @@ return 0; } +guint buddy_resource_getevents(gpointer rosterdata, const char *resname) +{ + roster *roster_usr = rosterdata; + res *p_res = get_resource(roster_usr, resname); + if (p_res) + return p_res->events; + return ROSTER_EVENT_NONE; +} + +void buddy_resource_setevents(gpointer rosterdata, const char *resname, + guint events) +{ + roster *roster_usr = rosterdata; + res *p_res = get_resource(roster_usr, resname); + if (p_res) + p_res->events = events; + + /* + // update group + roster_usr = roster_usr->list->data; + p_res = get_resource(roster_usr, ""); + if (p_res) + p_res->events = events; + */ +} + enum imrole buddy_getrole(gpointer rosterdata, const char *resname) { roster *roster_usr = rosterdata; diff -r b33ca4e1c37d -r ed697234bd39 mcabber/src/roster.h --- a/mcabber/src/roster.h Sat Oct 28 18:14:22 2006 +0200 +++ b/mcabber/src/roster.h Sun Oct 29 11:43:00 2006 +0100 @@ -74,6 +74,22 @@ #define ROSTER_FLAG_USRLOCK (1U<<3) // Node should not be removed from buddylist // ROSTER_FLAG_LOCAL (1U<<4) // Buddy not on server's roster (??) + +/* Message event and chat state flags */ +#define ROSTER_EVENT_NONE 0U +#define ROSTER_EVENT_MSG 1U +/* JEP-22 Message Events */ +#define ROSTER_EVENT_OFFLINE (1U<<1) +#define ROSTER_EVENT_DELIVERED (1U<<2) +#define ROSTER_EVENT_DISPLAYED (1U<<3) +/* JEP-22 & JEP-85 */ +#define ROSTER_EVENT_COMPOSING (1U<<4) +/* JEP-85 Chat State Notifications */ +#define ROSTER_EVENT_ACTIVE (1U<<5) +#define ROSTER_EVENT_PAUSED (1U<<6) +#define ROSTER_EVENT_INACTIVE (1U<<7) +#define ROSTER_EVENT_GONE (1U<<8) + extern GList *buddylist; extern GList *current_buddy; extern GList *alternate_buddy; @@ -135,6 +151,9 @@ GSList *buddy_getresources_locale(gpointer rosterdata); void buddy_resource_setname(gpointer rosterdata, const char *resname, const char *newname); +void buddy_resource_setevents(gpointer rosterdata, const char *resname, + guint event); +guint buddy_resource_getevents(gpointer rosterdata, const char *resname); enum imrole buddy_getrole(gpointer rosterdata, const char *resname); enum imaffiliation buddy_getaffil(gpointer rosterdata, const char *resname); const char *buddy_getrjid(gpointer rosterdata, const char *resname); diff -r b33ca4e1c37d -r ed697234bd39 mcabber/src/screen.c --- a/mcabber/src/screen.c Sat Oct 28 18:14:22 2006 +0200 +++ b/mcabber/src/screen.c Sun Oct 29 11:43:00 2006 +0100 @@ -1168,6 +1168,7 @@ for (i=0; idata : ""); + if (events) { + if (events & ROSTER_EVENT_MSG && false) { // FIXME: not yet. + pending = '#'; + break; + } else if (events & ROSTER_EVENT_COMPOSING) { + pending = '+'; + break; + } + } + } + // Display message notice if there is a message flag, but not // for unfolded groups. if (ismsg && (!isgrp || ishid)) {