Mercurial > pidgin
changeset 29435:11cb7f2bb6e8
Add a PURPLE_STATUS_MOOD primitive and change ICQ to use it.
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Mon, 17 Nov 2008 00:43:59 +0000 |
parents | 1034b0d09398 |
children | b92ae9c512ec |
files | ChangeLog.API libpurple/protocols/jabber/jabber.c libpurple/protocols/oscar/family_buddy.c libpurple/protocols/oscar/family_locate.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h libpurple/protocols/oscar/tlv.c libpurple/status.c libpurple/status.h pidgin/gtkblist.c pidgin/gtksavedstatuses.c |
diffstat | 11 files changed, 254 insertions(+), 155 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog.API Sun Nov 16 19:17:27 2008 +0000 +++ b/ChangeLog.API Mon Nov 17 00:43:59 2008 +0000 @@ -1,5 +1,10 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.6.0 (??/??/????): + libpurple: + Added: + * PURPLE_STATUS_MOOD as a new PurpleStatusPrimitive + version 2.5.0 (08/18/2008): libpurple: Added:
--- a/libpurple/protocols/jabber/jabber.c Sun Nov 16 19:17:27 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Mon Nov 17 00:43:59 2008 +0000 @@ -1658,7 +1658,7 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), NULL); - types = g_list_append(types, type); + types = g_list_prepend(types, type); priority_value = purple_value_new(PURPLE_TYPE_INT); purple_value_set_int(priority_value, 1); @@ -1672,7 +1672,7 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), NULL); - types = g_list_append(types, type); + types = g_list_prepend(types, type); priority_value = purple_value_new(PURPLE_TYPE_INT); purple_value_set_int(priority_value, 0); @@ -1686,7 +1686,7 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), NULL); - types = g_list_append(types, type); + types = g_list_prepend(types, type); priority_value = purple_value_new(PURPLE_TYPE_INT); purple_value_set_int(priority_value, 0); @@ -1700,7 +1700,7 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), NULL); - types = g_list_append(types, type); + types = g_list_prepend(types, type); priority_value = purple_value_new(PURPLE_TYPE_INT); purple_value_set_int(priority_value, 0); @@ -1714,11 +1714,11 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), NULL); - types = g_list_append(types, type); + types = g_list_prepend(types, type); /* if(js->protocol_version == JABBER_PROTO_0_9) - m = g_list_append(m, _("Invisible")); + "Invisible" */ type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE, @@ -1726,7 +1726,7 @@ NULL, FALSE, TRUE, FALSE, "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL); - types = g_list_append(types, type); + types = g_list_prepend(types, type); type = purple_status_type_new_with_attrs(PURPLE_STATUS_TUNE, "tune", NULL, TRUE, TRUE, TRUE, @@ -1740,9 +1740,9 @@ PURPLE_TUNE_YEAR, _("Tune Year"), purple_value_new(PURPLE_TYPE_INT), PURPLE_TUNE_URL, _("Tune URL"), purple_value_new(PURPLE_TYPE_STRING), NULL); - types = g_list_append(types, type); + types = g_list_prepend(types, type); - return types; + return g_list_reverse(types); } static void
--- a/libpurple/protocols/oscar/family_buddy.c Sun Nov 16 19:17:27 2008 +0000 +++ b/libpurple/protocols/oscar/family_buddy.c Mon Nov 17 00:43:59 2008 +0000 @@ -225,9 +225,17 @@ aim_locate_autofetch_away_message(od, userinfo.sn); if (snac->subtype == SNAC_SUBTYPE_BUDDY_ONCOMING && - userinfo.capabilities & OSCAR_CAPABILITY_XTRAZ && userinfo.customicon > 0) - icq_im_xstatus_request(od, userinfo.sn); + userinfo.capabilities & OSCAR_CAPABILITY_XTRAZ) { + PurpleAccount *account = purple_connection_get_account(od->gc); + PurpleBuddy *buddy = purple_find_buddy(account, userinfo.sn); + if (buddy) { + PurplePresence *presence = purple_buddy_get_presence(buddy); + + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOOD)) + icq_im_xstatus_request(od, userinfo.sn); + } + } aim_info_free(&userinfo); return ret;
--- a/libpurple/protocols/oscar/family_locate.c Sun Nov 16 19:17:27 2008 +0000 +++ b/libpurple/protocols/oscar/family_locate.c Mon Nov 17 00:43:59 2008 +0000 @@ -252,13 +252,11 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }; -#define AIM_CUSTOM_ICONS_COUNT 35 - static const struct { - char *filename; + char *mood; char *descriptivename; guint8 data[16]; -} aim_custom_icons[AIM_CUSTOM_ICONS_COUNT] = { +} aim_custom_icons[] = { /* empty X-Status for the case when customicon == 0 */ {NULL, NULL, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -443,8 +441,6 @@ cur->sessionlen = userinfo->sessionlen; if (userinfo->capabilities != 0) cur->capabilities = userinfo->capabilities; - if (userinfo->customicon != 0) - cur->customicon = userinfo->customicon; cur->present |= userinfo->present; @@ -643,11 +639,11 @@ return flags; } -gint32 -aim_get_custom_icon(OscarData *od, ByteStream *bs, int len) +static const char * +aim_receive_custom_icon(OscarData *od, ByteStream *bs, int len) { int offset; - gint32 result = -1; + const char *result = NULL; for (offset = 0; byte_stream_empty(bs) && (offset < len); offset += 0x10) { /* check wheather this capability is a custom user icon */ @@ -656,10 +652,10 @@ cap = byte_stream_getraw(bs, 0x10); - for (i = 1; i < AIM_CUSTOM_ICONS_COUNT; i++) { + for (i = 1; i < G_N_ELEMENTS(aim_custom_icons); i++) { if (memcmp(&aim_custom_icons[i].data, cap, 0x10) == 0) { purple_debug_misc("oscar", "Custom status icon: %s\n", aim_custom_icons[i].descriptivename); - result = i; + result = aim_custom_icons[i].mood; break; /* should only match once... */ } } @@ -759,36 +755,36 @@ g_free(info->away_encoding); } -#define ICQMOODS_COUNT 23 +static const struct { + char *icqmood; + const char *mood; +} icqmoods[] = { + {"icqmood0", "shopping"}, + {"icqmood1", "bathing"}, + {"icqmood2", "yawn"}, + {"icqmood3", "party"}, + {"icqmood4", "beer"}, + {"icqmood5", "thinking"}, + {"icqmood6", "plate"}, + {"icqmood7", "tv"}, + {"icqmood8", "meeting"}, + {"icqmood9", "coffee"}, + {"icqmood10", "music"}, + {"icqmood11", "suit"}, + {"icqmood12", "cinema"}, + {"icqmood13", "smile-big"}, + {"icqmood14", "phone"}, + {"icqmood15", "console"}, + {"icqmood16", "studying"}, + {"icqmood17", "sick"}, + {"icqmood18", "sleepy"}, + {"icqmood19", "surfing"}, + {"icqmood20", "internet"}, + {"icqmood21", "working"}, + {"icqmood22", "typing"}, + {"icqmood23", "angry"}, + {NULL, 0} -static const struct { - char *mood; - gint32 icon_num; -} icqmoods[ICQMOODS_COUNT] = { - {"icqmood0", 3}, - {"icqmood1", 12}, - {"icqmood2", 18}, - {"icqmood3", 24}, - {"icqmood4", 30}, - {"icqmood5", 1}, - {"icqmood6", 7}, - {"icqmood7", 13}, - {"icqmood8", 19}, - {"icqmood9", 25}, - {"icqmood10", 31}, - {"icqmood11", 11}, - {"icqmood12", 8}, - {"icqmood13", 14}, - {"icqmood14", 20}, - {"icqmood15", 26}, - {"icqmood16", 32}, - {"icqmood17", 9}, - {"icqmood18", 15}, - {"icqmood19", 21}, - {"icqmood20", 27}, - {"icqmood21", 33}, - {"icqmood22", 10}, - {"icqmood23", 6}, }; /* @@ -946,13 +942,23 @@ outinfo->present |= AIM_USERINFO_PRESENT_ICQDATA; } else if (type == 0x000d) { + PurpleAccount *account = purple_connection_get_account(od->gc); + const char *mood; + /* * OSCAR Capability information */ outinfo->capabilities |= aim_locate_getcaps(od, bs, length); outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES; byte_stream_setpos(bs, curpos); - outinfo->customicon = aim_get_custom_icon(od, bs, length); + + mood = aim_receive_custom_icon(od, bs, length); + if (mood) + purple_prpl_got_user_status(account, outinfo->sn, "mood", + PURPLE_MOOD_NAME, mood, + NULL); + else + purple_prpl_got_user_status_deactive(account, outinfo->sn, "mood"); } else if (type == 0x000e) { /* @@ -1083,33 +1089,34 @@ } break; case 0x000e: { /* ICQ mood */ - char *mood; + PurpleAccount *account = purple_connection_get_account(od->gc); + char *icqmood; gint32 i; - gint32 icon_num = -1; + const char *mood = NULL; - mood = byte_stream_getstr(bs, length2); + icqmood = byte_stream_getstr(bs, length2); - /* The official clients allow - * you to set your custom icon - * to the "default" icon, to - * allow setting a status - * message. We'll ignore it. - */ - if (!*mood) - break; - - for (i = 0; i < ICQMOODS_COUNT; i++) - if (!strcmp(mood, icqmoods[i].mood)) { - icon_num = icqmoods[i].icon_num; - break; /* should only match once... */ + /* icqmood = "" means X-Status + * with no mood icon. */ + if (*icqmood) { + for (i = 0; icqmoods[i].icqmood; i++) { + if (!strcmp(icqmood, icqmoods[i].icqmood)) { + mood = icqmoods[i].mood; + break; /* should only match once... */ + } } - if (icon_num >= 0) - outinfo->customicon = icon_num; + if (!mood) + purple_debug_warning("oscar", "Unknown icqmood: %s\n", icqmood); + } + g_free(icqmood); + + if (mood) + purple_prpl_got_user_status(account, outinfo->sn, "mood", + PURPLE_MOOD_NAME, mood, + NULL); else - purple_debug_warning("oscar", "Unknown icqmood: %s\n", mood); - - g_free(mood); + purple_prpl_got_user_status_deactive(account, outinfo->sn, "mood"); } break; } @@ -1155,6 +1162,10 @@ return 0; } +/* Apparently, this is never called. + * If you activate it, figure out a way to know what mood to pass to + * aim_tlvlist_add_caps() below. --rlaager */ +#if 0 /* * Inverse of aim_info_extract() */ @@ -1190,8 +1201,9 @@ } #endif - if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES) - aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities, info->customicon); + if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES) { + aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities, NULL); + } if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN) aim_tlvlist_add_32(&tlvlist, (guint16)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen); @@ -1202,6 +1214,7 @@ return 0; } +#endif /* * Subtype 0x0001 @@ -1391,6 +1404,10 @@ aim_locate_setcaps(OscarData *od, guint32 caps) { FlapConnection *conn; + PurpleAccount *account = purple_connection_get_account(od->gc); + PurplePresence *presence = purple_account_get_presence(account); + PurpleStatus *status = purple_presence_get_status(presence, "mood"); + const char *mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; @@ -1398,7 +1415,7 @@ if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE))) return -EINVAL; - aim_tlvlist_add_caps(&tlvlist, 0x0005, caps, purple_account_get_int(purple_connection_get_account(od->gc), "customicon", -1)); + aim_tlvlist_add_caps(&tlvlist, 0x0005, caps, mood); byte_stream_new(&bs, aim_tlvlist_size(tlvlist)); @@ -1482,11 +1499,21 @@ /* Caps will be 5 */ if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) { ByteStream cbs; + PurpleAccount *account = purple_connection_get_account(od->gc); + const char *mood; + byte_stream_init(&cbs, tlv->value, tlv->length); userinfo->capabilities = aim_locate_getcaps(od, &cbs, tlv->length); byte_stream_rewind(&cbs); - userinfo->customicon = aim_get_custom_icon(od, &cbs, tlv->length); userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES; + + mood = aim_receive_custom_icon(od, &cbs, tlv->length); + if (mood) + purple_prpl_got_user_status(account, userinfo->sn, "mood", + PURPLE_MOOD_NAME, mood, + NULL); + else + purple_prpl_got_user_status_deactive(account, userinfo->sn, "mood"); } aim_tlvlist_free(tlvlist); @@ -1714,32 +1741,43 @@ return 0; } -guint32 -aim_get_custom_icons_count() +#if 1 //rlaager +size_t aim_get_custom_icons_count(void) { - return AIM_CUSTOM_ICONS_COUNT; + return G_N_ELEMENTS(aim_custom_icons); } -char* -aim_get_custom_icon_filename(gint32 no) +char* aim_get_custom_icon_mood(gint32 no) { - if (no >= AIM_CUSTOM_ICONS_COUNT || no < 1) + if (no >= G_N_ELEMENTS(aim_custom_icons) || no < 1) return NULL; - return aim_custom_icons[no].filename; + return aim_custom_icons[no].mood; } -char* -aim_get_custom_icon_descriptivename(gint32 no) +char* aim_get_custom_icon_descriptivename(gint32 no) { - if (no >= AIM_CUSTOM_ICONS_COUNT || no < 1) + if (no >= G_N_ELEMENTS(aim_custom_icons) || no < 1) return NULL; return aim_custom_icons[no].descriptivename; } +#endif guint8* -aim_get_custom_icon_data(gint32 no) +aim_get_custom_icon_data(const char *mood) { - if (no >= AIM_CUSTOM_ICONS_COUNT || no < 1) + int i; + + if (!(mood && *mood)) return NULL; - return (guint8 *)aim_custom_icons[no].data; + + for (i = 1; i < G_N_ELEMENTS(aim_custom_icons); i++) { + /* We check that descriptivename is not NULL to exclude + * duplicates, like the typing duplicate. */ + if (aim_custom_icons[i].descriptivename && + aim_custom_icons[i].mood && + !strcmp(mood, aim_custom_icons[i].mood)) { + return (guint8 *)aim_custom_icons[i].data; + } + } + return NULL; }
--- a/libpurple/protocols/oscar/oscar.c Sun Nov 16 19:17:27 2008 +0000 +++ b/libpurple/protocols/oscar/oscar.c Mon Nov 17 00:43:59 2008 +0000 @@ -4865,6 +4865,10 @@ if (!purple_account_is_connected(account)) return; + /* There's no need to do the stuff below for mood updates. */ + if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) + return; + /* Set the AIM-style away message for both AIM and ICQ accounts */ oscar_set_info_and_status(account, FALSE, NULL, TRUE, status); @@ -5853,7 +5857,6 @@ } if (userinfo != NULL ) { - const char *icon; if (userinfo->flags & AIM_FLAG_ADMINISTRATOR) return "admin"; if (userinfo->flags & AIM_FLAG_ACTIVEBUDDY) @@ -5862,8 +5865,11 @@ return "secure"; if (userinfo->icqinfo.status & AIM_ICQ_STATE_BIRTHDAY) return "birthday"; - if ((icon = aim_get_custom_icon_filename(userinfo->customicon))) - return icon; + + /* Make the mood icon override anything below this. */ + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOOD)) + return NULL; + if (userinfo->capabilities & OSCAR_CAPABILITY_HIPTOP) return "hiptop"; } @@ -6181,9 +6187,14 @@ NULL, TRUE, TRUE, FALSE); status_types = g_list_prepend(status_types, type); - status_types = g_list_reverse(status_types); - - return status_types; + type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD, + "mood", NULL, TRUE, is_icq, TRUE, + PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new(PURPLE_TYPE_STRING), + PURPLE_MOOD_COMMENT, _("Mood Comment"), purple_value_new(PURPLE_TYPE_STRING), + NULL); + status_types = g_list_prepend(status_types, type); + + return g_list_reverse(status_types); } static void oscar_ssi_editcomment(struct name_data *data, const char *text) { @@ -6751,87 +6762,98 @@ purple_xfer_request(xfer); } +/* XXX: rlaager wants UI in the UI. */ +#if 1 static void -oscar_show_icq_custom_icons_cb(PurpleConnection *gc, PurpleRequestFields *fields) { +oscar_show_icq_moods_cb(PurpleConnection *gc, PurpleRequestFields *fields) { OscarData *od = gc->proto_data; - PurpleAccount *account = purple_connection_get_account(gc); PurpleRequestField *f; GList *l; - f = purple_request_fields_get_field(fields, "customicon"); + f = purple_request_fields_get_field(fields, "mood"); l = purple_request_field_list_get_selected(f); if (l) { - gpointer d = purple_request_field_list_get_data(f, l->data); - purple_account_set_int(account, "customicon", GPOINTER_TO_INT(d)); - } - + const char *mood = purple_request_field_list_get_data(f, l->data); + PurpleAccount *account = purple_connection_get_account(gc); + + if (mood != NULL) { + purple_account_set_status(account, "mood", TRUE, + PURPLE_MOOD_NAME, mood, + NULL); + } else { + purple_account_set_status(account, "mood", FALSE, NULL); + } + } + aim_locate_setcaps(od, purple_caps); } static void -oscar_show_icq_custom_icons(PurplePluginAction *action) +oscar_show_icq_moods(PurplePluginAction *action) { - guint32 i; - gint32 customicon; PurpleConnection *gc = (PurpleConnection *) action->context; PurpleAccount *account = purple_connection_get_account(gc); + PurplePresence *presence = purple_account_get_presence(account); + PurpleStatus *status = purple_presence_get_status(presence, "mood"); + const char *current_mood; PurpleRequestFields *fields; PurpleRequestFieldGroup *g; PurpleRequestField *f; + guint32 i; char* na_fn; - customicon = purple_account_get_int(account, "customicon", 0); - + current_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); + fields = purple_request_fields_new(); g = purple_request_field_group_new(NULL); - - f = purple_request_field_list_new("customicon", _("Choose a custom status icon")); + + f = purple_request_field_list_new("mood", _("Please select your mood from the list.")); na_fn = g_build_filename("pixmaps", "pidgin", "emblems", "16", "not-authorized.png", NULL); - purple_request_field_list_add_icon(f, _("None"), na_fn, GINT_TO_POINTER(-1)); - if (customicon == 0) + purple_request_field_list_add_icon(f, _("None"), na_fn, NULL); + if (current_mood == NULL) purple_request_field_list_add_selected(f, _("None")); g_free(na_fn); /* TODO: rlaager wants this sorted. */ for (i = 1; i < aim_get_custom_icons_count(); i++) { - const char *icon_filename = aim_get_custom_icon_filename(i); + const char *mood = aim_get_custom_icon_mood(i); const char *icon_desc = aim_get_custom_icon_descriptivename(i); char *icon_path; char *filename; - if (icon_filename == NULL || icon_desc == NULL) + if (mood == NULL || icon_desc == NULL) continue; - icon_path = g_strdup_printf("%s.png", icon_filename); + icon_path = g_strdup_printf("%s.png", mood); filename = g_build_filename("pixmaps", "pidgin", "emblems", "16", icon_path, NULL); g_free(icon_path); purple_request_field_list_add_icon(f, _(icon_desc), - filename, GINT_TO_POINTER(i)); + filename, (gpointer)mood); g_free(filename); - if (customicon == i) + if (current_mood && !strcmp(current_mood, mood)) purple_request_field_list_add_selected(f, _(icon_desc)); } purple_request_field_group_add_field(g, f); purple_request_fields_add_group(fields, g); - purple_request_fields(gc, _("Custom Status Icon"), _("Custom Status Icon"), + purple_request_fields(gc, _("Edit User Mood"), _("Edit User Mood"), NULL, fields, - _("OK"), G_CALLBACK(oscar_show_icq_custom_icons_cb), + _("OK"), G_CALLBACK(oscar_show_icq_moods_cb), _("Cancel"), NULL, purple_connection_get_account(gc), NULL, NULL, gc); } - +#endif GList * oscar_actions(PurplePlugin *plugin, gpointer context) @@ -6875,10 +6897,13 @@ act = purple_plugin_action_new(_("Set Privacy Options..."), oscar_show_icq_privacy_opts); menu = g_list_prepend(menu, act); - - act = purple_plugin_action_new(_("Set Custom Status Icon..."), - oscar_show_icq_custom_icons); + +/* XXX: rlaager wants UI in the UI. */ +#if 1 + act = purple_plugin_action_new(_("Set Mood..."), + oscar_show_icq_moods); menu = g_list_prepend(menu, act); +#endif } else {
--- a/libpurple/protocols/oscar/oscar.h Sun Nov 16 19:17:27 2008 +0000 +++ b/libpurple/protocols/oscar/oscar.h Mon Nov 17 00:43:59 2008 +0000 @@ -1028,7 +1028,6 @@ guint32 onlinesince; /* time_t */ guint32 sessionlen; /* in seconds */ guint32 capabilities; - gint32 customicon; struct { guint32 status; guint32 ipaddr; @@ -1106,12 +1105,15 @@ guint32 aim_locate_getcaps_short(OscarData *od, ByteStream *bs, int len); void aim_info_free(aim_userinfo_t *); int aim_info_extract(OscarData *od, ByteStream *bs, aim_userinfo_t *); +#if 0 int aim_putuserinfo(ByteStream *bs, aim_userinfo_t *info); -gint32 aim_get_custom_icon(OscarData *od, ByteStream *bs, int len); -guint32 aim_get_custom_icons_count(void); -char* aim_get_custom_icon_filename(gint32 no); -char* aim_get_custom_icon_descriptivename(gint32 no); -guint8* aim_get_custom_icon_data(gint32 no); +#endif +#if 1 +size_t aim_get_custom_icons_count(void); //rlaager +char* aim_get_custom_icon_mood(gint32 no);// rlaager +char* aim_get_custom_icon_descriptivename(gint32 no); // rlaager +#endif +guint8* aim_get_custom_icon_data(const char *mood); int icq_im_xstatus_request(OscarData *od, const char *sn); /* 0x0003 - family_buddy.c */ @@ -1442,7 +1444,7 @@ int aim_tlvlist_add_16(GSList **list, const guint16 type, const guint16 value); int aim_tlvlist_add_32(GSList **list, const guint16 type, const guint32 value); int aim_tlvlist_add_str(GSList **list, const guint16 type, const char *value); -int aim_tlvlist_add_caps(GSList **list, const guint16 type, const guint32 caps, gint32 customicon); +int aim_tlvlist_add_caps(GSList **list, const guint16 type, const guint32 caps, const char *mood); int aim_tlvlist_add_userinfo(GSList **list, guint16 type, aim_userinfo_t *userinfo); int aim_tlvlist_add_chatroom(GSList **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance); int aim_tlvlist_add_frozentlvlist(GSList **list, guint16 type, GSList **tl);
--- a/libpurple/protocols/oscar/tlv.c Sun Nov 16 19:17:27 2008 +0000 +++ b/libpurple/protocols/oscar/tlv.c Mon Nov 17 00:43:59 2008 +0000 @@ -407,7 +407,7 @@ * @param caps Bitfield of capability flags to send * @return The size of the value added. */ -int aim_tlvlist_add_caps(GSList **list, const guint16 type, const guint32 caps, const gint32 customicon) +int aim_tlvlist_add_caps(GSList **list, const guint16 type, const guint32 caps, const char *mood) { guint8 buf[256]; /* TODO: Don't use a fixed length buffer */ ByteStream bs; @@ -421,10 +421,9 @@ byte_stream_putcaps(&bs, caps); /* adding of custom icon GUID */ - data = aim_get_custom_icon_data(customicon); - if (data != NULL) { + data = aim_get_custom_icon_data(mood); + if (data != NULL) byte_stream_putraw(&bs, data, 16); - } return aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), buf); }
--- a/libpurple/status.c Sun Nov 16 19:17:27 2008 +0000 +++ b/libpurple/status.c Mon Nov 17 00:43:59 2008 +0000 @@ -135,6 +135,7 @@ -200, /* extended away */ -400, /* mobile */ 0, /* tune */ + 0, /* mood */ -10, /* idle, special case. */ -5, /* idle time, special case. */ 10 /* Offline messageable */ @@ -155,15 +156,16 @@ } const status_primitive_map[] = { - { PURPLE_STATUS_UNSET, "unset", N_("Unset") }, - { PURPLE_STATUS_OFFLINE, "offline", N_("Offline") }, - { PURPLE_STATUS_AVAILABLE, "available", N_("Available") }, - { PURPLE_STATUS_UNAVAILABLE, "unavailable", N_("Do not disturb") }, - { PURPLE_STATUS_INVISIBLE, "invisible", N_("Invisible") }, - { PURPLE_STATUS_AWAY, "away", N_("Away") }, - { PURPLE_STATUS_EXTENDED_AWAY, "extended_away", N_("Extended away") }, - { PURPLE_STATUS_MOBILE, "mobile", N_("Mobile") }, - { PURPLE_STATUS_TUNE, "tune", N_("Listening to music") } + { PURPLE_STATUS_UNSET, "unset", N_("Unset") }, + { PURPLE_STATUS_OFFLINE, "offline", N_("Offline") }, + { PURPLE_STATUS_AVAILABLE, "available", N_("Available") }, + { PURPLE_STATUS_UNAVAILABLE, "unavailable", N_("Do not disturb") }, + { PURPLE_STATUS_INVISIBLE, "invisible", N_("Invisible") }, + { PURPLE_STATUS_AWAY, "away", N_("Away") }, + { PURPLE_STATUS_EXTENDED_AWAY, "extended_away", N_("Extended away") }, + { PURPLE_STATUS_MOBILE, "mobile", N_("Mobile") }, + { PURPLE_STATUS_TUNE, "tune", N_("Listening to music"), }, + { PURPLE_STATUS_MOOD, "mood", N_("Feeling") }, }; const char *
--- a/libpurple/status.h Sun Nov 16 19:17:27 2008 +0000 +++ b/libpurple/status.h Mon Nov 17 00:43:59 2008 +0000 @@ -96,8 +96,7 @@ */ /* * If you add a value to this enum, make sure you update - * the status_primitive_map array in status.c and the special-cases for idle - * and offline-messagable just below it. + * the status_primitive_map and primitive_scores arrays in status.c. */ typedef enum { @@ -110,6 +109,7 @@ PURPLE_STATUS_EXTENDED_AWAY, PURPLE_STATUS_MOBILE, PURPLE_STATUS_TUNE, + PURPLE_STATUS_MOOD, PURPLE_STATUS_NUM_PRIMITIVES } PurpleStatusPrimitive; @@ -129,6 +129,9 @@ #define PURPLE_TUNE_URL "tune_url" #define PURPLE_TUNE_FULL "tune_full" +#define PURPLE_MOOD_NAME "mood" +#define PURPLE_MOOD_COMMENT "moodtext" + #ifdef __cplusplus extern "C" { #endif
--- a/pidgin/gtkblist.c Sun Nov 16 19:17:27 2008 +0000 +++ b/pidgin/gtkblist.c Mon Nov 17 00:43:59 2008 +0000 @@ -3606,7 +3606,7 @@ PurplePluginProtocolInfo *prpl_info; const char *name = NULL; char *filename, *path; - PurplePresence *p; + PurplePresence *presence = NULL; if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { if(!gtknode->contact_expanded) { @@ -3616,8 +3616,8 @@ } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { buddy = (PurpleBuddy*)node; gtkbuddynode = node->ui_data; - p = purple_buddy_get_presence(buddy); - if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) { + presence = purple_buddy_get_presence(buddy); + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOBILE)) { path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "mobile.png", NULL); return _pidgin_blist_get_cached_emblem(path); @@ -3639,13 +3639,17 @@ return _pidgin_blist_get_cached_emblem(path); } - p = purple_buddy_get_presence(buddy); - if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) { + /* If we came through the contact code flow above, we didn't need + * to get the presence until now. */ + if (presence == NULL) + presence = purple_buddy_get_presence(buddy); + + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOBILE)) { path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "mobile.png", NULL); return _pidgin_blist_get_cached_emblem(path); } - if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_TUNE)) { + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) { path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "music.png", NULL); return _pidgin_blist_get_cached_emblem(path); } @@ -3659,9 +3663,15 @@ name = prpl_info->list_emblem(buddy); if (name == NULL) { - PurpleStatus *status = purple_presence_get_active_status(p); - name = purple_status_get_attr_string(status, "mood"); - if(!(name && *name)) + PurpleStatus *status; + + if (!purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOOD)) + return NULL; + + status = purple_presence_get_status(presence, "mood"); + name = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); + + if (!(name && *name)) return NULL; }
--- a/pidgin/gtksavedstatuses.c Sun Nov 16 19:17:27 2008 +0000 +++ b/pidgin/gtksavedstatuses.c Mon Nov 17 00:43:59 2008 +0000 @@ -921,7 +921,14 @@ for (i = PURPLE_STATUS_UNSET + 1; i < PURPLE_STATUS_NUM_PRIMITIVES; i++) { - if (i == PURPLE_STATUS_MOBILE || i == PURPLE_STATUS_TUNE) + /* Someone should fix this for 3.0.0. The independent boolean + * should probably be set on the status type, not the status. + * I guess that would prevent third party plugins from creating + * independent statuses? + */ + if (i == PURPLE_STATUS_MOBILE || + i == PURPLE_STATUS_MOOD || + i == PURPLE_STATUS_TUNE) /* * Special-case these. They're intended to be independent * status types, so don't show them in the list.