# HG changeset patch # User Marcus Lundblad # Date 1265571116 0 # Node ID a538cb73f8979f138064c87ed0a6fc409dbc181b # Parent 791606778223e02a38c819b09c6398ec4b363076# Parent 5391094529c6dc0265426e13b70ca3dbc267756d propagate from branch 'im.pidgin.pidgin' (head b0098e2250f135d121960d8152e144e7e344125e) to branch 'im.pidgin.cpw.rekkanoryo.icqxstatus' (head dcd3ab65d5cfcd79b00a7b95ab5fe788da64c112) diff -r 791606778223 -r a538cb73f897 COPYRIGHT --- a/COPYRIGHT Fri Feb 05 14:40:39 2010 +0000 +++ b/COPYRIGHT Sun Feb 07 19:31:56 2010 +0000 @@ -228,6 +228,7 @@ Instant Messaging Freedom, Inc. Vitaliy Ischenko Intel Corporation +Andrew Ivanov Scott Jackson Hans Petter Jansson David Jedelsky @@ -237,7 +238,7 @@ Yuriy Kaminskiy Anders Kaseorg Praveen Karadakal -Jaromír Karmazín +Tomáš Kebert John Kelm Jochen Kemnade Yann Kerherve @@ -540,6 +541,7 @@ Jared Yanovich Timmy Yee Li Yuan +Yuriy Yevgrafov Nickolai Zeldovich Tom Zickel Marco Ziech diff -r 791606778223 -r a538cb73f897 ChangeLog.API --- a/ChangeLog.API Fri Feb 05 14:40:39 2010 +0000 +++ b/ChangeLog.API Sun Feb 07 19:31:56 2010 +0000 @@ -109,6 +109,7 @@ * xmlnode_from_file * xmlnode_get_parent * xmlnode_set_attrib_full + * PURPLE_STATUS_MOOD as a new PurpleStatusPrimitive Changed: * xmlnode_remove_attrib now removes all attributes with the diff -r 791606778223 -r a538cb73f897 finch/gntplugin.c --- a/finch/gntplugin.c Fri Feb 05 14:40:39 2010 +0000 +++ b/finch/gntplugin.c Sun Feb 07 19:31:56 2010 +0000 @@ -498,7 +498,7 @@ break; } stringlist = g_list_prepend(stringlist, value); - purple_request_field_list_add(field, label, value); + purple_request_field_list_add_icon(field, label, NULL, value); if (strcmp(value, current_value) == 0) purple_request_field_list_add_selected(field, label); list = list->next->next; diff -r 791606778223 -r a538cb73f897 finch/gntprefs.c --- a/finch/gntprefs.c Fri Feb 05 14:40:39 2010 +0000 +++ b/finch/gntprefs.c Sun Feb 07 19:31:56 2010 +0000 @@ -171,7 +171,7 @@ default: break; } - purple_request_field_list_add(field, data, iter->data); + purple_request_field_list_add_icon(field, data, NULL, iter->data); if (select) purple_request_field_list_add_selected(field, data); } diff -r 791606778223 -r a538cb73f897 finch/plugins/gnthistory.c --- a/finch/plugins/gnthistory.c Fri Feb 05 14:40:39 2010 +0000 +++ b/finch/plugins/gnthistory.c Sun Feb 07 19:31:56 2010 +0000 @@ -158,7 +158,7 @@ while (list) { const char *label = _(list->data); list = g_list_delete_link(list, list); - purple_request_field_list_add(field, label, list->data); + purple_request_field_list_add_icon(field, label, NULL, list->data); if (system && strcmp(system, list->data) == 0) purple_request_field_list_add_selected(field, label); list = g_list_delete_link(list, list); diff -r 791606778223 -r a538cb73f897 libpurple/plugins/perl/common/Request.xs --- a/libpurple/plugins/perl/common/Request.xs Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/plugins/perl/common/Request.xs Sun Feb 07 19:31:56 2010 +0000 @@ -380,6 +380,13 @@ void * data void +purple_request_field_list_add_icon(field, item, icon_path, data) + Purple::Request::Field field + const char *item + const char *icon_path + void * data + +void purple_request_field_list_add_selected(field, item) Purple::Request::Field field const char *item diff -r 791606778223 -r a538cb73f897 libpurple/protocols/gg/gg.c diff -r 791606778223 -r a538cb73f897 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/jabber/jabber.c Sun Feb 07 19:31:56 2010 +0000 @@ -2058,12 +2058,12 @@ if (full) { PurpleStatus *status; - status = purple_presence_get_active_status(presence); - mood = purple_status_get_attr_string(status, "mood"); - if(mood != NULL) { + status = purple_presence_get_status(presence, "mood"); + mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); + if(mood && *mood) { const char *moodtext; - moodtext = purple_status_get_attr_string(status, "moodtext"); - if(moodtext != NULL) { + moodtext = purple_status_get_attr_string(status, PURPLE_MOOD_COMMENT); + if(moodtext && *moodtext) { char *moodplustext = g_strdup_printf("%s (%s)", mood, moodtext); purple_notify_user_info_add_pair(user_info, _("Mood"), moodplustext); @@ -2130,7 +2130,7 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), buzz_enabled, 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); @@ -2146,7 +2146,7 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), buzz_enabled, 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); @@ -2162,7 +2162,7 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), buzz_enabled, 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); @@ -2178,7 +2178,7 @@ "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), "buzz", _("Allow Buzz"), buzz_enabled, 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); @@ -2191,11 +2191,11 @@ "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING), "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), 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, @@ -2203,7 +2203,7 @@ NULL, TRUE, 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, FALSE, TRUE, TRUE, @@ -2217,9 +2217,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); - - return types; + types = g_list_prepend(types, type); + + return g_list_reverse(types); } static void diff -r 791606778223 -r a538cb73f897 libpurple/protocols/jabber/usermood.c --- a/libpurple/protocols/jabber/usermood.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/jabber/usermood.c Sun Feb 07 19:31:56 2010 +0000 @@ -30,100 +30,102 @@ #include "request.h" #include "debug.h" -static const char * const moodstrings[] = { - "afraid", - "amazed", - "amorous", - "angry", - "annoyed", - "anxious", - "aroused", - "ashamed", - "bored", - "brave", - "calm", - "cautious", - "cold", - "confident", - "confused", - "contemplative", - "contented", - "cranky", - "crazy", - "creative", - "curious", - "dejected", - "depressed", - "disappointed", - "disgusted", - "dismayed", - "distracted", - "embarrassed", - "envious", - "excited", - "flirtatious", - "frustrated", - "grumpy", - "guilty", - "happy", - "hopeful", - "hot", - "humbled", - "humiliated", - "hungry", - "hurt", - "impressed", - "in_awe", - "in_love", - "indignant", - "interested", - "intoxicated", - "invincible", - "jealous", - "lonely", - "lucky", - "mean", - "moody", - "nervous", - "neutral", - "offended", - "outraged", - "playful", - "proud", - "relaxed", - "relieved", - "remorseful", - "restless", - "sad", - "sarcastic", - "serious", - "shocked", - "shy", - "sick", - "sleepy", - "spontaneous", - "stressed", - "strong", - "surprised", - "thankful", - "thirsty", - "tired", - "weak", - "worried" +static PurpleMood moods[] = { + {"afraid", N_("Afraid"), NULL}, + {"amazed", N_("Amazed"), NULL}, + {"amorous", N_("Amorous"), NULL}, + {"angry", N_("Angry"), NULL}, + {"annoyed", N_("Annoyed"), NULL}, + {"anxious", N_("Anxious"), NULL}, + {"aroused", N_("Aroused"), NULL}, + {"ashamed", N_("Ashamed"), NULL}, + {"bored", N_("Bored"), NULL}, + {"brave", N_("Brave"), NULL}, + {"calm", N_("Calm"), NULL}, + {"cautious", N_("Cautious"), NULL}, + {"cold", N_("Cold"), NULL}, + {"confident", N_("Confident"), NULL}, + {"confused", N_("Confused"), NULL}, + {"contemplative", N_("Contemplative"), NULL}, + {"contented", N_("Contented"), NULL}, + {"cranky", N_("Cranky"), NULL}, + {"crazy", N_("Crazy"), NULL}, + {"creative", N_("Creative"), NULL}, + {"curious", N_("Curious"), NULL}, + {"dejected", N_("Dejected"), NULL}, + {"depressed", N_("Depressed"), NULL}, + {"disappointed", N_("Disappointed"), NULL}, + {"disgusted", N_("Disgusted"), NULL}, + {"dismayed", N_("Dismayed"), NULL}, + {"distracted", N_("Distracted"), NULL}, + {"embarrassed", N_("Embarrassed"), NULL}, + {"envious", N_("Envious"), NULL}, + {"excited", N_("Excited"), NULL}, + {"flirtatious", N_("Flirtatious"), NULL}, + {"frustrated", N_("Frustrated"), NULL}, + {"grateful", N_("Grateful"), NULL}, + {"grieving", N_("Grieving"), NULL}, + {"grumpy", N_("Grumpy"), NULL}, + {"guilty", N_("Guilty"), NULL}, + {"happy", N_("Happy"), NULL}, + {"hopeful", N_("Hopeful"), NULL}, + {"hot", N_("Hot"), NULL}, + {"humbled", N_("Humbled"), NULL}, + {"humiliated", N_("Humiliated"), NULL}, + {"hungry", N_("Hungry"), NULL}, + {"hurt", N_("Hurt"), NULL}, + {"impressed", N_("Impressed"), NULL}, + {"in_awe", N_("In_awe"), NULL}, + {"in_love", N_("In_love"), NULL}, + {"indignant", N_("Indignant"), NULL}, + {"interested", N_("Interested"), NULL}, + {"intoxicated", N_("Intoxicated"), NULL}, + {"invincible", N_("Invincible"), NULL}, + {"jealous", N_("Jealous"), NULL}, + {"lonely", N_("Lonely"), NULL}, + {"lost", N_("Lost"), NULL}, + {"lucky", N_("Lucky"), NULL}, + {"mean", N_("Mean"), NULL}, + {"moody", N_("Moody"), NULL}, + {"nervous", N_("Nervous"), NULL}, + {"neutral", N_("Neutral"), NULL}, + {"offended", N_("Offended"), NULL}, + {"outraged", N_("Outraged"), NULL}, + {"playful", N_("Playful"), NULL}, + {"proud", N_("Proud"), NULL}, + {"relaxed", N_("Relaxed"), NULL}, + {"relieved", N_("Relieved"), NULL}, + {"remorseful", N_("Remorseful"), NULL}, + {"restless", N_("Restless"), NULL}, + {"sad", N_("Sad"), NULL}, + {"sarcastic", N_("Sarcastic"), NULL}, + {"satisfied", N_("Satisfied"), NULL}, + {"serious", N_("Serious"), NULL}, + {"shocked", N_("Shocked"), NULL}, + {"shy", N_("Shy"), NULL}, + {"sick", N_("Sick"), NULL}, + {"sleepy", N_("Sleepy"), NULL}, + {"spontaneous", N_("Spontaneous"), NULL}, + {"stressed", N_("Stressed"), NULL}, + {"strong", N_("Strong"), NULL}, + {"surprised", N_("Surprised"), NULL}, + {"thankful", N_("Thankful"), NULL}, + {"thirsty", N_("Thirsty"), NULL}, + {"tired", N_("Tired"), NULL}, + {"undefined", N_("Undefined"), NULL}, + {"weak", N_("Weak"), NULL}, + {"worried", N_("Worried"), NULL}, + /* Mark the last record. */ + {NULL, NULL, NULL} }; -static void -jabber_mood_cb(JabberStream *js, const char *from, xmlnode *items) -{ - xmlnode *item; - JabberBuddy *buddy = jabber_buddy_find(js, from, FALSE); +static void jabber_mood_cb(JabberStream *js, const char *from, xmlnode *items) { + /* it doesn't make sense to have more than one item here, so let's just pick the first one */ + xmlnode *item = xmlnode_get_child(items, "item"); const char *newmood = NULL; char *moodtext = NULL; - xmlnode *child, *mood; - - /* it doesn't make sense to have more than one item here, so let's just pick the first one */ - item = xmlnode_get_child(items, "item"); - + JabberBuddy *buddy = jabber_buddy_find(js, from, FALSE); + xmlnode *moodinfo, *mood; /* ignore the mood of people not on our buddy list */ if (!buddy || !item) return; @@ -131,39 +133,34 @@ mood = xmlnode_get_child_with_namespace(item, "mood", "http://jabber.org/protocol/mood"); if (!mood) return; - for (child = mood->child; child; child = child->next) { - if (child->type != XMLNODE_TYPE_TAG) - continue; - - if (g_str_equal("text", child->name) && moodtext == NULL) - moodtext = xmlnode_get_data(child); - else { - int i; - for (i = 0; i < G_N_ELEMENTS(moodstrings); ++i) { - /* verify that the mood is known (valid) */ - if (g_str_equal(child->name, moodstrings[i])) { - newmood = moodstrings[i]; - break; + for (moodinfo = mood->child; moodinfo; moodinfo = moodinfo->next) { + if (moodinfo->type == XMLNODE_TYPE_TAG) { + if (!strcmp(moodinfo->name, "text")) { + if (!moodtext) /* only pick the first one */ + moodtext = xmlnode_get_data(moodinfo); + } else { + int i; + for (i = 0; moods[i].mood; ++i) { + /* verify that the mood is known (valid) */ + if (!strcmp(moodinfo->name, moods[i].mood)) { + newmood = moods[i].mood; + break; + } } } + if (newmood != NULL && moodtext != NULL) + break; } if (newmood != NULL && moodtext != NULL) break; } if (newmood != NULL) { - PurpleAccount *account; - const char *status_id; - JabberBuddyResource *resource = jabber_buddy_find_resource(buddy, NULL); - if (!resource) { /* huh? */ - g_free(moodtext); - return; - } - status_id = jabber_buddy_state_get_status_id(resource->state); - - account = purple_connection_get_account(js->gc); - purple_prpl_got_user_status(account, from, status_id, "mood", - _(newmood), "moodtext", - moodtext ? moodtext : "", NULL); + purple_prpl_got_user_status(js->gc->account, from, "mood", + PURPLE_MOOD_NAME, mood, + PURPLE_MOOD_COMMENT, moodtext, + NULL); + } else { + purple_prpl_got_user_status_deactive(js->gc->account, from, "mood"); } g_free(moodtext); } @@ -175,6 +172,7 @@ static void do_mood_set_from_fields(PurpleConnection *gc, PurpleRequestFields *fields) { JabberStream *js; + const int max_mood_idx = sizeof(moods) / sizeof(moods[0]) - 1; int selected_mood = purple_request_fields_get_choice(fields, "mood"); if (!PURPLE_CONNECTION_IS_VALID(gc)) { @@ -184,12 +182,12 @@ js = gc->proto_data; - if (selected_mood < 0 || selected_mood >= G_N_ELEMENTS(moodstrings)) { + if (selected_mood < 0 || selected_mood >= max_mood_idx) { purple_debug_error("jabber", "Invalid mood index (%d) selected.\n", selected_mood); return; } - jabber_mood_set(js, moodstrings[selected_mood], purple_request_fields_get_string(fields, "text")); + jabber_mood_set(js, moods[selected_mood].mood, purple_request_fields_get_string(fields, "text")); } static void do_mood_set_mood(PurplePluginAction *action) { @@ -207,8 +205,8 @@ field = purple_request_field_choice_new("mood", _("Mood"), 0); - for(i = 0; i < G_N_ELEMENTS(moodstrings); ++i) - purple_request_field_choice_add(field, _(moodstrings[i])); + for(i = 0; moods[i].mood; ++i) + purple_request_field_choice_add(field, _(moods[i].description)); purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); diff -r 791606778223 -r a538cb73f897 libpurple/protocols/jabber/xdata.c --- a/libpurple/protocols/jabber/xdata.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/jabber/xdata.c Sun Feb 07 19:31:56 2010 +0000 @@ -305,7 +305,7 @@ data->values = g_slist_prepend(data->values, value); - purple_request_field_list_add(field, lbl, value); + purple_request_field_list_add_icon(field, lbl, NULL, value); if(g_list_find_custom(selected, value, (GCompareFunc)strcmp)) purple_request_field_list_add_selected(field, lbl); } diff -r 791606778223 -r a538cb73f897 libpurple/protocols/oscar/family_buddy.c --- a/libpurple/protocols/oscar/family_buddy.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/oscar/family_buddy.c Sun Feb 07 19:31:56 2010 +0000 @@ -221,6 +221,18 @@ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, &userinfo); + if (snac->subtype == SNAC_SUBTYPE_BUDDY_ONCOMING && + 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; diff -r 791606778223 -r a538cb73f897 libpurple/protocols/oscar/family_icbm.c --- a/libpurple/protocols/oscar/family_icbm.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Sun Feb 07 19:31:56 2010 +0000 @@ -2624,6 +2624,15 @@ char *bn; guchar *cookie; guint8 bnlen; + char *xml = NULL; + int hdrlen; + int curpos; + int num1,num2; + char *desc, *title, *temp; + PurpleAccount *account; + PurpleBuddy *buddy; + PurplePresence *presence; + PurpleStatus *status; cookie = byte_stream_getraw(bs, 8); channel = byte_stream_get16(bs); @@ -2633,14 +2642,54 @@ if (channel == 0x0002) { - if (reason == 0x0003) /* channel-specific */ - /* parse status note text */ - parse_status_note_text(od, cookie, bn, bs); - - byte_stream_get16(bs); /* Unknown */ - byte_stream_get16(bs); /* Unknown */ - if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, channel, bn, reason, cookie); + hdrlen = byte_stream_getle16(bs); + if ( ((hdrlen == 27 ) && (bs->len > (27 + 51)))) { + byte_stream_advance(bs, 51); + num1 = byte_stream_getle16(bs); + num2 = byte_stream_getle16(bs); + purple_debug_misc("oscar", "X-Status: Num1 %i, num2 %i\n",num1, num2); + + if(((num1 == 0x4f00)&&(num2 == 0x3b00))) { + byte_stream_advance(bs, 86); + curpos = byte_stream_curpos(bs); + xml = byte_stream_getstr(bs, bs->len - curpos); + purple_debug_misc("oscar", "X-Status: Received XML reply\n"); + if(xml) { + /* purple_debug_misc("oscar", "X-Status: XML reply: %s\n", (const char*) xml); */ + if ((desc=strstr(xml,"<desc>")) != NULL) { + temp=strstr(xml,"</desc>"); + temp[0]=0; + desc=desc+12; + } + if ((title=strstr(xml,"<title>")) != NULL) { + temp=strstr(xml,"</title>"); + temp[0]=0; + title=title+13; + } else { + title=""; + } + strcpy(xml,title); + if (desc) { + strcat(xml, " - "); + strcat(xml, desc); + } + purple_debug_misc("oscar", "X-Status reply: %s\n", (const char*)xml); + account = purple_connection_get_account(od->gc); + buddy = purple_find_buddy(account, sn); + presence = purple_buddy_get_presence(buddy); + status = purple_presence_get_active_status(presence); + purple_prpl_got_user_status(account, sn, + purple_status_get_id(status), "message", xml, NULL); + } else { + purple_debug_misc("oscar", "X-Status: Can't get XML reply string\n"); + } + } else { + purple_debug_misc("oscar", "X-Status: 0x0004, 0x000b not an xstatus reply\n" ); + /* if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) + ret = userfunc(od, conn, frame, channel, sn, reason); */ + } + + } } else if (channel == 0x0004) { /* ICQ message */ switch (reason) { @@ -2699,6 +2748,7 @@ g_free(cookie); g_free(bn); + g_free(xml); return ret; } @@ -2807,6 +2857,181 @@ } /* + * Subtype 0x0006 - Send eXtra Status request + */ +int icq_im_xstatus_request(OscarData *od, const char *sn) +{ + FlapConnection *conn; + aim_snacid_t snacid; + guchar cookie[8]; + GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; + ByteStream bs, header, plugindata; + PurpleAccount *account; + const char *fmt; + char *statxml; + int xmllen; + + static const guint8 pluginid[] = + { + 0x09, 0x46, 0x13, 0x49, 0x4C, 0x7F, 0x11, 0xD1, + 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 + }; + + static const guint8 c_plugindata[] = + { + 0x1B, 0x00, 0x0A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xD1, 0x0E, 0x00, 0xF9, 0xD1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x4F, 0x00, 0x3B, 0x60, 0xB3, 0xEF, 0xD8, 0x2A, 0x6C, 0x45, 0xA4, 0xE0, 0x9C, + 0x5A, 0x5E, 0x67, 0xE8, 0x65, 0x08, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x53, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x20, 0x50, 0x6C, 0x75, 0x67, 0x2D, 0x69, 0x6E, 0x3A, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x74, + 0x65, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x72, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00 + }; + + if (!od || !(conn = flap_connection_findbygroup(od, 0x0004))) + return -EINVAL; + + if (!sn) + return -EINVAL; + + fmt = "<Q><PluginID>srvMng</PluginID></Q><srv><id>cAwaySrv</id><req><id>AwayStat</id><trans>2</trans><senderId>%s</senderId></req></srv>\r\n"; + + account = purple_connection_get_account(od->gc); + xmllen = strlen(fmt) - 2 + strlen(account->username); + + statxml = (char*) g_malloc(xmllen); + snprintf(statxml, xmllen, fmt, account->username); + + aim_icbm_makecookie(cookie); + + byte_stream_new(&bs, 10 + 8 + 2 + 1 + strlen(sn) + 2 + + 2 + 2 + 8 + 16 + 2 + 2 + 2 + 2 + 2 + + 2 + 2 + sizeof(c_plugindata) + xmllen + + 2 + 2); + + snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); + aim_im_puticbm(&bs, cookie, 0x0002, sn); + + byte_stream_new(&header, (7*2) + 16 + 8 + 2 + sizeof(c_plugindata) + xmllen); /* TLV 0x0005 Stream + Size */ + byte_stream_new(&plugindata, (sizeof(c_plugindata) + xmllen)); + + byte_stream_put16(&header, 0x0000); /* Message Type: Request */ + byte_stream_putraw(&header, cookie, sizeof(cookie)); /* Message ID */ + byte_stream_putraw(&header, pluginid, sizeof(pluginid)); /* Plugin ID */ + + aim_tlvlist_add_16(&inner_tlvlist, 0x000a, 0x0001); + aim_tlvlist_add_noval(&inner_tlvlist, 0x000f); + + /* Add Plugin Specific Data */ + byte_stream_putraw(&plugindata, c_plugindata, sizeof(c_plugindata)); /* Content of TLV 0x2711 */ + byte_stream_putstr(&plugindata, statxml); + + aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, (sizeof(c_plugindata) + xmllen), plugindata.data); + + aim_tlvlist_write(&header, &inner_tlvlist); + + + aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&header), header.data); + aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); /* Empty TLV 0x0003 */ + + aim_tlvlist_write(&bs, &outer_tlvlist); + + purple_debug_misc("oscar", "X-Status Request\n"); + flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs, TRUE); + + aim_tlvlist_free(inner_tlvlist); + aim_tlvlist_free(outer_tlvlist); + byte_stream_destroy(&header); + byte_stream_destroy(&plugindata); + byte_stream_destroy(&bs); + g_free(statxml); + + return 0; +} + +int icq_relay_xstatus(OscarData *od, const char *sn, const guchar *cookie) +{ + FlapConnection *conn; + ByteStream bs; + aim_snacid_t snacid; + PurpleAccount *account; + PurpleStatus *status; + const char *fmt; + const char *formatted_msg; + char *msg; + char *statxml; + const char *title; + int len; + + static const guint8 plugindata[] = { + 0x1B, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xD1, 0x0E, 0x00, 0xF9, 0xD1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4F, + 0x00, 0x3B, 0x60, 0xB3, 0xEF, 0xD8, 0x2A, 0x6C, 0x45, 0xA4, 0xE0, + 0x9C, 0x5A, 0x5E, 0x67, 0xE8, 0x65, 0x08, 0x00, 0x2A, 0x00, 0x00, + 0x00, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x50, 0x6C, 0x75, + 0x67, 0x2D, 0x69, 0x6E, 0x3A, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x74, + 0x65, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x72, 0x72, 0x69, 0x76, 0x65, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xF3, 0x01, 0x00, 0x00, 0xEF, 0x01, 0x00, 0x00 + }; + + fmt = "<ret event='OnRemoteNotification'><srv><id>cAwaySrv</id><val srv_id='cAwaySrv'><Root><CASXtraSetAwayMessage></CASXtraSetAwayMessage>&l t;uin>%s</uin><index>1</index><title>%s</title><desc>%s</desc></Root></val></srv><srv><id>cRandomizerSrv</id><val srv_id='cRandomizerSrv'>undefined</val></srv></ret>\r\n"; + + + if (!od || !(conn = flap_connection_findbygroup(od, 0x0002))) + return -EINVAL; + + if (!sn) + return -EINVAL; + + account = purple_connection_get_account(od->gc); + if(!account) return -EINVAL; + +/* if (!strcmp(account->username, sn)) + icq_im_xstatus_request(od, sn); */ + + status = purple_presence_get_active_status(account->presence); + if (!status) return -EINVAL; + title = purple_status_get_name(status); + if (!title) return -EINVAL; + formatted_msg = purple_status_get_attr_string(status, "message"); + if (!formatted_msg) return -EINVAL; + msg = purple_markup_strip_html(formatted_msg); + if (!msg) return -EINVAL; + len = strlen(fmt)-6+strlen(account->username)+strlen(title)+strlen(msg); + statxml = (char*) g_malloc(len); + + snprintf(statxml, len, fmt, + account->username, title, msg); + + purple_debug_misc("oscar", "X-Status AutoReply: %s, %s\n", formatted_msg, msg); + + byte_stream_new(&bs, 10 + 8 + 2 + 1 + strlen(sn) + 2 + sizeof(plugindata) + strlen(statxml)); /* 16 extra */ + + snacid = aim_cachesnac(od, 0x0004, 0x000b, 0x0000, NULL, 0); + aim_im_puticbm(&bs, cookie, 0x0002, sn); + byte_stream_put16(&bs, 0x0003); + byte_stream_putraw(&bs, plugindata, sizeof(plugindata)); + byte_stream_putraw(&bs, (const guint8*)statxml, strlen(statxml)); + + flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x000b, 0x0000, snacid, &bs, TRUE); + + g_free(statxml); + g_free(msg); + byte_stream_destroy(&bs); + + return 0; +} + +/* * Subtype 0x0014 - Receive a mini typing notification (mtn) packet. * * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer, diff -r 791606778223 -r a538cb73f897 libpurple/protocols/oscar/family_locate.c --- a/libpurple/protocols/oscar/family_locate.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/oscar/family_locate.c Sun Feb 07 19:31:56 2010 +0000 @@ -166,6 +166,16 @@ {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1, 0x22, 0x82, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, + /* New format of caps (xtraz icons) */ + {OSCAR_CAPABILITY_NEWCAPS, + {0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, + 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, + + /* Support xtraz statuses */ + {OSCAR_CAPABILITY_XTRAZ, + {0x1a, 0x09, 0x3c, 0x6c, 0xd7, 0xFD, 0x4e, 0xc5, + 0x9d, 0x51, 0xa6, 0x47, 0x4e, 0x34, 0xf5, 0xa0}}, + {OSCAR_CAPABILITY_SENDBUDDYLIST, {0x09, 0x46, 0x13, 0x4b, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, @@ -240,6 +250,202 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }; +/* Keep this array synchronized with icq_purple_moods. */ +static const struct { + const char *mood; + guint8 data[16]; +} icq_custom_icons[] = { + + {"thinking", + {0x3f, 0xb0, 0xbd, 0x36, 0xaf, 0x3b, 0x4a, 0x60, + 0x9e, 0xef, 0xcf, 0x19, 0x0f, 0x6a, 0x5a, 0x7f}}, + + {"busy", + {0x48, 0x8e, 0x14, 0x89, 0x8a, 0xca, 0x4a, 0x08, + 0x82, 0xaa, 0x77, 0xce, 0x7a, 0x16, 0x52, 0x08}}, + + {"shopping", + {0x63, 0x62, 0x73, 0x37, 0xa0, 0x3f, 0x49, 0xff, + 0x80, 0xe5, 0xf7, 0x09, 0xcd, 0xe0, 0xa4, 0xee}}, + + /* This was in the original patch, but isn't what the official client + * (ICQ 6) sets when you choose its typewriter icon. */ + {"typing", + {0x63, 0x4f, 0x6b, 0xd8 ,0xad, 0xd2, 0x4a, 0xa1, + 0xaa, 0xb9, 0x11, 0x5b, 0xc2, 0x6d, 0x05, 0xa1}}, + + {"question", + {0x63, 0x14, 0x36, 0xff, 0x3f, 0x8a, 0x40, 0xd0, + 0xa5, 0xcb, 0x7b, 0x66, 0xe0, 0x51, 0xb3, 0x64}}, + + {"angry", + {0x01, 0xd8, 0xd7, 0xee, 0xac, 0x3b, 0x49, 0x2a, + 0xa5, 0x8d, 0xd3, 0xd8, 0x77, 0xe6, 0x6b, 0x92}}, + + {"plate", + {0xf8, 0xe8, 0xd7, 0xb2, 0x82, 0xc4, 0x41, 0x42, + 0x90, 0xf8, 0x10, 0xc6, 0xce, 0x0a, 0x89, 0xa6}}, + + {"cinema", + {0x10, 0x7a, 0x9a, 0x18, 0x12, 0x32, 0x4d, 0xa4, + 0xb6, 0xcd, 0x08, 0x79, 0xdb, 0x78, 0x0f, 0x09}}, + + {"sick", + {0x1f, 0x7a, 0x40, 0x71, 0xbf, 0x3b, 0x4e, 0x60, + 0xbc, 0x32, 0x4c, 0x57, 0x87, 0xb0, 0x4c, 0xf1}}, + + {"typing", + {0x2c, 0xe0, 0xe4, 0xe5, 0x7c, 0x64, 0x43, 0x70, + 0x9c, 0x3a, 0x7a, 0x1c, 0xe8, 0x78, 0xa7, 0xdc}}, + + {"suit", + {0xb7, 0x08, 0x67, 0xf5, 0x38, 0x25, 0x43, 0x27, + 0xa1, 0xff, 0xcf, 0x4c, 0xc1, 0x93, 0x97, 0x97}}, + + {"bathing", + {0x5a, 0x58, 0x1e, 0xa1, 0xe5, 0x80, 0x43, 0x0c, + 0xa0, 0x6f, 0x61, 0x22, 0x98, 0xb7, 0xe4, 0xc7}}, + + {"tv", + {0x80, 0x53, 0x7d, 0xe2, 0xa4, 0x67, 0x4a, 0x76, + 0xb3, 0x54, 0x6d, 0xfd, 0x07, 0x5f, 0x5e, 0xc6}}, + + {"excited", + {0x6f, 0x49, 0x30, 0x98, 0x4f, 0x7c, 0x4a, 0xff, + 0xa2, 0x76, 0x34, 0xa0, 0x3b, 0xce, 0xae, 0xa7}}, + + {"sleeping", + {0x78, 0x5e, 0x8c, 0x48, 0x40, 0xd3, 0x4c, 0x65, + 0x88, 0x6f, 0x04, 0xcf, 0x3f, 0x3f, 0x43, 0xdf}}, + + {"hiptop", + {0x10, 0x11, 0x17, 0xc9, 0xa3, 0xb0, 0x40, 0xf9, + 0x81, 0xac, 0x49, 0xe1, 0x59, 0xfb, 0xd5, 0xd4}}, + + {"in_love", + {0xdd, 0xcf, 0x0e, 0xa9, 0x71, 0x95, 0x40, 0x48, + 0xa9, 0xc6, 0x41, 0x32, 0x06, 0xd6, 0xf2, 0x80}}, + + {"sleepy", + {0x83, 0xc9, 0xb7, 0x8e, 0x77, 0xe7, 0x43, 0x78, + 0xb2, 0xc5, 0xfb, 0x6c, 0xfc, 0xc3, 0x5b, 0xec}}, + + {"meeting", + {0xf1, 0x8a, 0xb5, 0x2e, 0xdc, 0x57, 0x49, 0x1d, + 0x99, 0xdc, 0x64, 0x44, 0x50, 0x24, 0x57, 0xaf}}, + + {"phone", + {0x12, 0x92, 0xe5, 0x50, 0x1b, 0x64, 0x4f, 0x66, + 0xb2, 0x06, 0xb2, 0x9a, 0xf3, 0x78, 0xe4, 0x8d}}, + + {"surfing", + {0xa6, 0xed, 0x55, 0x7e, 0x6b, 0xf7, 0x44, 0xd4, + 0xa5, 0xd4, 0xd2, 0xe7, 0xd9, 0x5c, 0xe8, 0x1f}}, + + {"mobile", + {0x16, 0x0c, 0x60, 0xbb, 0xdd, 0x44, 0x43, 0xf3, + 0x91, 0x40, 0x05, 0x0f, 0x00, 0xe6, 0xc0, 0x09}}, + + {"search", + {0xd4, 0xe2, 0xb0, 0xba, 0x33, 0x4e, 0x4f, 0xa5, + 0x98, 0xd0, 0x11, 0x7d, 0xbf, 0x4d, 0x3c, 0xc8}}, + + {"party", + {0xe6, 0x01, 0xe4, 0x1c, 0x33, 0x73, 0x4b, 0xd1, + 0xbc, 0x06, 0x81, 0x1d, 0x6c, 0x32, 0x3d, 0x81}}, + + {"coffee", + {0x1b, 0x78, 0xae, 0x31, 0xfa, 0x0b, 0x4d, 0x38, + 0x93, 0xd1, 0x99, 0x7e, 0xee, 0xaf, 0xb2, 0x18}}, + + {"console", + {0xd4, 0xa6, 0x11, 0xd0, 0x8f, 0x01, 0x4e, 0xc0, + 0x92, 0x23, 0xc5, 0xb6, 0xbe, 0xc6, 0xcc, 0xf0}}, + + {"internet", + {0x12, 0xd0, 0x7e, 0x3e, 0xf8, 0x85, 0x48, 0x9e, + 0x8e, 0x97, 0xa7, 0x2a, 0x65, 0x51, 0xe5, 0x8d}}, + + {"cigarette", + {0x64, 0x43, 0xc6, 0xaf, 0x22, 0x60, 0x45, 0x17, + 0xb5, 0x8c, 0xd7, 0xdf, 0x8e, 0x29, 0x03, 0x52}}, + + {"writing", + {0x00, 0x72, 0xd9, 0x08, 0x4a, 0xd1, 0x43, 0xdd, + 0x91, 0x99, 0x6f, 0x02, 0x69, 0x66, 0x02, 0x6f}}, + + {"beer", + {0x8c, 0x50, 0xdb, 0xae, 0x81, 0xed, 0x47, 0x86, + 0xac, 0xca, 0x16, 0xcc, 0x32, 0x13, 0xc7, 0xb7}}, + + {"music", + {0x61, 0xbe, 0xe0, 0xdd, 0x8b, 0xdd, 0x47, 0x5d, + 0x8d, 0xee, 0x5f, 0x4b, 0xaa, 0xcf, 0x19, 0xa7}}, + + {"studying", + {0x60, 0x9d, 0x52, 0xf8, 0xa2, 0x9a, 0x49, 0xa6, + 0xb2, 0xa0, 0x25, 0x24, 0xc5, 0xe9, 0xd2, 0x60}}, + + {"working", + {0xba, 0x74, 0xdb, 0x3e, 0x9e, 0x24, 0x43, 0x4b, + 0x87, 0xb6, 0x2f, 0x6b, 0x8d, 0xfe, 0xe5, 0x0f}}, + + {"restroom", + {0x16, 0xf5, 0xb7, 0x6f, 0xa9, 0xd2, 0x40, 0x35, + 0x8c, 0xc5, 0xc0, 0x84, 0x70, 0x3c, 0x98, 0xfa}}, + + {NULL, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} +}; + +/* Keep this array synchronized with icq_custom_icons. */ +static PurpleMood icq_purple_moods[] = { + {"thinking", N_("Thinking"), NULL}, + {"busy", N_("Busy"), NULL}, + {"shopping", N_("Shopping"), NULL}, + /* This was in the original patch, but isn't what the official client + * (ICQ 6) sets when you choose its typewriter icon. */ + {"typing", NULL, NULL}, + {"question", N_("Questioning"), NULL}, + {"angry", N_("Angry"), NULL}, + {"plate", N_("Eating"), NULL}, + {"cinema", N_("Watching a movie"), NULL}, + {"sick", N_("Sick"), NULL}, + {"typing", N_("Typing"), NULL}, + {"suit", N_("At the office"), NULL}, + {"bathing", N_("Taking a bath"), NULL}, + {"tv", N_("Watching TV"), NULL}, + {"excited", N_("Having fun"), NULL}, + {"sleeping", N_("Sleeping"), NULL}, + {"hiptop", N_("Using a PDA"), NULL}, + {"in_love", N_("In love"), NULL}, + /* Sleepy / Tired */ + {"sleepy", N_("Sleepy"), NULL}, + {"meeting", N_("Meeting friends"), NULL}, + {"phone", N_("On the phone"), NULL}, + {"surfing", N_("Surfing"), NULL}, + /* "I am mobile." / "John is mobile." */ + {"mobile", N_("Mobile"), NULL}, + {"search", N_("Searching the web"), NULL}, + {"party", N_("At a party"), NULL}, + {"coffee", N_("Having Coffee"), NULL}, + /* Playing video games */ + {"console", N_("Gaming"), NULL}, + {"internet", N_("Browsing the web"), NULL}, + {"cigarette", N_("Smoking"), NULL}, + {"writing", N_("Writing"), NULL}, + /* Drinking [Alcohol] */ + {"beer", N_("Drinking"), NULL}, + {"music", N_("Listening to music"), NULL}, + {"studying", N_("Studying"), NULL}, + {"working", N_("Working"), NULL}, + {"restroom", N_("In the restroom"), NULL}, + /* Mark the last record. */ + {NULL, NULL, NULL}, +}; + + /* * Add the userinfo to our linked list. If we already have userinfo * for this buddy, then just overwrite parts of the old data. @@ -274,6 +480,7 @@ cur->sessionlen = userinfo->sessionlen; if (userinfo->capabilities != 0) cur->capabilities = userinfo->capabilities; + cur->present |= userinfo->present; if (userinfo->iconcsumlen > 0) { @@ -398,13 +605,38 @@ cap[8], cap[9], cap[10], cap[11], cap[12], cap[13], cap[14], cap[15]); - g_free(cap); } return flags; } +static const char * +aim_receive_custom_icon(OscarData *od, ByteStream *bs, int len) +{ + int offset; + const char *result = NULL; + + for (offset = 0; byte_stream_empty(bs) && (offset < len); offset += 0x10) { + /* check wheather this capability is a custom user icon */ + guint8 *cap; + int i; + + cap = byte_stream_getraw(bs, 0x10); + + for (i = 0; icq_custom_icons[i].mood; i++) { + if (memcmp(&icq_custom_icons[i].data, cap, 0x10) == 0) { + purple_debug_misc("oscar", "Custom status icon: %s\n", icq_purple_moods[i].description); + result = icq_custom_icons[i].mood; + break; /* should only match once... */ + } + } + g_free(cap); + } + + return result; +} + guint32 aim_locate_getcaps_short(OscarData *od, ByteStream *bs, int len) { @@ -495,6 +727,38 @@ g_free(info->away_encoding); } +static const struct { + char *icqmood; + const char *mood; +} icqmoods[] = { + {"icqmood0", "shopping"}, + {"icqmood1", "bathing"}, + {"icqmood2", "sleepy"}, + {"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", "sleeping"}, + {"icqmood19", "surfing"}, + {"icqmood20", "internet"}, + {"icqmood21", "working"}, + {"icqmood22", "typing"}, + {"icqmood23", "angry"}, + {NULL, 0} + +}; + /* * AIM is fairly regular about providing user info. This is a generic * routine to extract it in its standard form. @@ -535,11 +799,12 @@ for (curtlv = 0; curtlv < tlvcnt; curtlv++) { guint16 type, length; int endpos; + int curpos; type = byte_stream_get16(bs); length = byte_stream_get16(bs); - - endpos = byte_stream_curpos(bs) + MIN(length, byte_stream_empty(bs)); + curpos = byte_stream_curpos(bs); + endpos = curpos + MIN(length, byte_stream_empty(bs)); if (type == 0x0001) { /* @@ -651,11 +916,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); + + 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) { /* @@ -791,6 +1068,37 @@ outinfo->itmsurl_encoding = NULL; } } break; + + case 0x000e: { /* ICQ mood */ + PurpleAccount *account = purple_connection_get_account(od->gc); + char *icqmood; + gint32 i; + const char *mood = NULL; + + icqmood = byte_stream_getstr(bs, length2); + + /* 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 (!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_prpl_got_user_status_deactive(account, outinfo->sn, "mood"); + } break; } /* Save ourselves. */ @@ -857,6 +1165,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() */ @@ -892,8 +1204,9 @@ } #endif - if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES) - aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities); + 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); @@ -904,6 +1217,7 @@ return 0; } +#endif /* * Subtype 0x0001 @@ -1089,6 +1403,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; @@ -1096,7 +1414,7 @@ if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE))) return -EINVAL; - aim_tlvlist_add_caps(&tlvlist, 0x0005, caps); + aim_tlvlist_add_caps(&tlvlist, 0x0005, caps, mood); byte_stream_new(&bs, aim_tlvlist_size(tlvlist)); @@ -1179,9 +1497,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->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); @@ -1399,3 +1729,57 @@ return 0; } + +#if 0 //rlaager +const char* aim_get_custom_icon_mood(gint32 no) +{ + if (no >= G_N_ELEMENTS(aim_custom_icons) || no < 1) + return NULL; + return aim_custom_icons[no].mood.mood; +} +#endif + +const char* +icq_get_custom_icon_description(const char *mood) +{ + int i; + + if (!(mood && *mood)) + return NULL; + + for (i = 0; icq_custom_icons[i].mood; i++) { + /* We check that description is not NULL to exclude + * duplicates, like the typing duplicate. */ + if (icq_purple_moods[i].description && + !strcmp(mood, icq_custom_icons[i].mood)) { + return icq_purple_moods[i].description; + } + } + + return NULL; +} + +guint8* +icq_get_custom_icon_data(const char *mood) +{ + int i; + + if (!(mood && *mood)) + return NULL; + + for (i = 0; icq_custom_icons[i].mood; i++) { + /* We check that description is not NULL to exclude + * duplicates, like the typing duplicate. */ + if (icq_purple_moods[i].description && + !strcmp(mood, icq_custom_icons[i].mood)) { + return (guint8 *)icq_custom_icons[i].data; + } + } + return NULL; +} + +PurpleMood* +icq_get_purple_moods(PurpleAccount *account) +{ + return icq_purple_moods; +} diff -r 791606778223 -r a538cb73f897 libpurple/protocols/oscar/libicq.c --- a/libpurple/protocols/oscar/libicq.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/oscar/libicq.c Sun Feb 07 19:31:56 2010 +0000 @@ -109,6 +109,7 @@ icq_get_account_text_table, /* get_account_text_table */ NULL, /* initiate_media */ NULL /* can_do_media */ + oscar_get_purple_moods, /* get_moods */ }; static PurplePluginInfo info = diff -r 791606778223 -r a538cb73f897 libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.c Sun Feb 07 19:31:56 2010 +0000 @@ -61,6 +61,11 @@ #define OSCAR_STATUS_ID_FREE4CHAT "free4chat" #define OSCAR_STATUS_ID_CUSTOM "custom" #define OSCAR_STATUS_ID_MOBILE "mobile" +#define OSCAR_STATUS_ID_EVIL "evil" +#define OSCAR_STATUS_ID_DEPRESSION "depression" +#define OSCAR_STATUS_ID_ATHOME "athome" +#define OSCAR_STATUS_ID_ATWORK "atwork" +#define OSCAR_STATUS_ID_LUNCH "lunch" #define AIMHASHDATA "http://pidgin.im/aim_data.php3" @@ -68,7 +73,7 @@ static OscarCapability purple_caps = (OSCAR_CAPABILITY_CHAT | OSCAR_CAPABILITY_BUDDYICON | OSCAR_CAPABILITY_DIRECTIM | OSCAR_CAPABILITY_SENDFILE | OSCAR_CAPABILITY_UNICODE | OSCAR_CAPABILITY_INTEROPERATE | - OSCAR_CAPABILITY_SHORTCAPS | OSCAR_CAPABILITY_TYPING); + OSCAR_CAPABILITY_SHORTCAPS | OSCAR_CAPABILITY_TYPING | OSCAR_CAPABILITY_ICQSERVERRELAY | OSCAR_CAPABILITY_NEWCAPS | OSCAR_CAPABILITY_XTRAZ); static guint8 features_aim[] = {0x01, 0x01, 0x01, 0x02}; static guint8 features_icq[] = {0x01, 0x06}; @@ -180,6 +185,7 @@ static int purple_parse_misses (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_clientauto (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_userinfo (OscarData *, FlapConnection *, FlapFrame *, ...); +static int purple_got_infoblock (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_motd (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_chatnav_info (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_conv_chat_join (OscarData *, FlapConnection *, FlapFrame *, ...); @@ -190,6 +196,7 @@ static int purple_icon_parseicon (OscarData *, FlapConnection *, FlapFrame *, ...); static int oscar_icon_req (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_msgack (OscarData *, FlapConnection *, FlapFrame *, ...); +static int purple_parse_ratechange (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_evilnotify (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_searcherror(OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_searchreply(OscarData *, FlapConnection *, FlapFrame *, ...); @@ -225,6 +232,7 @@ void oscar_set_info(PurpleConnection *gc, const char *info); static void oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *rawinfo, gboolean setstatus, PurpleStatus *status); static void oscar_set_extendedstatus(PurpleConnection *gc); +static void oscar_format_username(PurpleConnection *gc, const char *nick); static gboolean purple_ssi_rerequestdata(gpointer data); static void oscar_free_name_data(struct name_data *data) { @@ -703,6 +711,10 @@ case OSCAR_CAPABILITY_GAMES2: tmp = _("Games"); break; + case OSCAR_CAPABILITY_XTRAZ: + case OSCAR_CAPABILITY_NEWCAPS: + tmp = _("ICQ Xtraz"); + break; case OSCAR_CAPABILITY_ADDINS: tmp = _("Add-Ins"); break; @@ -784,6 +796,16 @@ return g_strdup(_("Web Aware")); else if (state & AIM_ICQ_STATE_INVISIBLE) return g_strdup(_("Invisible")); + else if (state & AIM_ICQ_STATE_EVIL) + return g_strdup(_("Evil")); + else if (state & AIM_ICQ_STATE_DEPRESSION) + return g_strdup(_("Depression")); + else if (state & AIM_ICQ_STATE_ATHOME) + return g_strdup_(_("At home")); + else if (state & AIM_ICQ_STATE_ATWORK) + return g_strdup(_("At work")); + else if (state & AIM_ICQ_STATE_LUNCH) + return g_strdup(_("At lunch")); else return g_strdup(_("Online")); } @@ -961,6 +983,16 @@ } } + if (presence) { + const char *mood; + const char *description; + status = purple_presence_get_status(presence, "mood"); + mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); + description = icq_get_custom_icon_description(mood); + if (description && *description) + purple_notify_user_info_add_pair(user_info, _("Mood"), _(description)); + } + purple_notify_user_info_add_pair(user_info, _("Status"), message); g_free(message); } @@ -2240,6 +2272,16 @@ status_id = OSCAR_STATUS_ID_AWAY; else if (type & AIM_ICQ_STATE_INVISIBLE) status_id = OSCAR_STATUS_ID_INVISIBLE; + else if (type & AIM_ICQ_STATE_EVIL) + status_id = OSCAR_STATUS_ID_EVIL; + else if (type & AIM_ICQ_STATE_DEPRESSION) + status_id = OSCAR_STATUS_ID_DEPRESSION; + else if (type & AIM_ICQ_STATE_ATHOME) + status_id = OSCAR_STATUS_ID_ATHOME; + else if (type & AIM_ICQ_STATE_ATWORK) + status_id = OSCAR_STATUS_ID_ATWORK; + else if (type & AIM_ICQ_STATE_LUNCH) + status_id = OSCAR_STATUS_ID_LUNCH; else status_id = OSCAR_STATUS_ID_AVAILABLE; } else { @@ -2552,7 +2594,9 @@ { PurpleConnection *gc; PurpleAccount *account; + PurpleMessageFlags flags = 0; char *message = NULL; + char *rtfmsg = NULL; g_return_val_if_fail(od != NULL, 0); g_return_val_if_fail(od->gc != NULL, 0); @@ -2582,6 +2626,20 @@ } } + if (args->info.rtfmsg.rtfmsg != NULL) + { + if (args->encoding != NULL) + { + char *encoding = NULL; + encoding = oscar_encoding_extract(args->encoding); + rtfmsg = oscar_encoding_to_utf8(account, encoding, args->info.rtfmsg.rtfmsg, + strlen(args->info.rtfmsg.rtfmsg)); + g_free(encoding); + } else { + if (g_utf8_validate(args->info.rtfmsg.rtfmsg, strlen(args->info.rtfmsg.rtfmsg), NULL)) + rtfmsg = g_strdup(args->info.rtfmsg.rtfmsg); + } + } if (args->type & OSCAR_CAPABILITY_CHAT) { char *encoding, *utf8name, *tmp; @@ -2667,10 +2725,28 @@ else if (args->type & OSCAR_CAPABILITY_ICQSERVERRELAY) { - purple_debug_error("oscar", "Got an ICQ Server Relay message of " + purple_debug_info("oscar", "Got an ICQ Server Relay message of " "type %d\n", args->info.rtfmsg.msgtype); - } - + purple_debug_info("oscar", "Sending X-Status Reply\n"); + + if(args->info.rtfmsg.msgtype == 26) + icq_relay_xstatus(od, userinfo->sn, args->cookie); + + if(args->info.rtfmsg.msgtype == 1) + { + if(rtfmsg) + { + serv_got_im(gc, userinfo->sn, rtfmsg, flags, + time(NULL)); + } + else + { + serv_got_im(gc, userinfo->sn, + args->info.rtfmsg.rtfmsg, flags, + time(NULL)); + } + } + } else { purple_debug_error("oscar", "Unknown request class %hu\n", @@ -3250,6 +3326,29 @@ } break; + case 0x0006: { /* Reply from an ICQ status message request */ + char *statusmsg, **splitmsg; + PurpleNotifyUserInfo *user_info; + + /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ + statusmsg = oscar_icqstatus(state); + splitmsg = g_strsplit(msg, "\r\n", 0); + + user_info = purple_notify_user_info_new(); + + purple_notify_user_info_add_pair(user_info, _("UIN"), who); + purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg); + purple_notify_user_info_add_section_break(user_info); + purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("
", splitmsg)); + + g_free(statusmsg); + g_strfreev(splitmsg); + + purple_notify_userinfo(gc, who, user_info, NULL, NULL); + purple_notify_user_info_destroy(user_info); + + } break; + default: { purple_debug_warning("oscar", "Received an unknown client auto-response from %s. " @@ -3497,6 +3596,55 @@ return 1; } +static int purple_got_infoblock(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) +{ + PurpleConnection *gc = od->gc; + PurpleAccount *account = purple_connection_get_account(gc); + PurpleBuddy *b; + PurplePresence *presence; + PurpleStatus *status; + gchar *message = NULL; + + va_list ap; + aim_userinfo_t *userinfo; + + va_start(ap, fr); + userinfo = va_arg(ap, aim_userinfo_t *); + va_end(ap); + + b = purple_find_buddy(account, userinfo->bn); + if (b == NULL) + return 1; + + if (!oscar_util_valid_name_icq(userinfo->bn)) + { + if (strcmp(purple_buddy_get_name(b), userinfo->bn) != 0) + serv_got_alias(gc, purple_buddy_get_name(b), userinfo->bn); + else + serv_got_alias(gc, purple_buddy_get_name(b), NULL); + } + + presence = purple_buddy_get_presence(b); + status = purple_presence_get_active_status(presence); + + if (purple_status_is_online(status) && !purple_status_is_available(status) && + userinfo->flags & AIM_FLAG_AWAY && userinfo->away_len > 0 && + userinfo->away != NULL && userinfo->away_encoding != NULL) + { + gchar *charset = oscar_encoding_extract(userinfo->away_encoding); + message = oscar_encoding_to_utf8(account, charset, + userinfo->away, + userinfo->away_len); + g_free(charset); + purple_prpl_got_user_status(account, userinfo->bn, + purple_status_get_id(status), + "message", message, NULL); + g_free(message); + } + + return 1; +} + static int purple_parse_motd(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { char *msg; @@ -4848,6 +4996,16 @@ data |= AIM_ICQ_STATE_CHAT; else if (!strcmp(status_id, OSCAR_STATUS_ID_INVISIBLE)) data |= AIM_ICQ_STATE_INVISIBLE; + else if (!strcmp(status_id, OSCAR_STATUS_ID_EVIL)) + data |= AIM_ICQ_STATE_EVIL; + else if (!strcmp(status_id, OSCAR_STATUS_ID_DEPRESSION)) + data |= AIM_ICQ_STATE_DEPRESSION; + else if (!strcmp(status_id, OSCAR_STATUS_ID_ATWORK)) + data |= AIM_ICQ_STATE_ATWORK; + else if (!strcmp(status_id, OSCAR_STATUS_ID_ATHOME)) + data |= AIM_ICQ_STATE_ATHOME; + else if (!strcmp(status_id, OSCAR_STATUS_ID_LUNCH)) + data |= AIM_ICQ_STATE_LUNCH; else if (!strcmp(status_id, OSCAR_STATUS_ID_CUSTOM)) data |= AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY; @@ -5006,8 +5164,12 @@ if (!purple_account_is_connected(account)) return; - pc = purple_account_get_connection(account); - od = purple_connection_get_protocol_data(pc); + /* 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) { + PurpleConnection *gc = purple_account_get_connection(account); + aim_locate_setcaps((OscarData *)gc->proto_data, purple_caps); + return; + } /* Set the AIM-style away message for both AIM and ICQ accounts */ oscar_set_info_and_status(account, FALSE, NULL, TRUE, status); @@ -5961,6 +6123,11 @@ return 0; } +PurpleMood* oscar_get_purple_moods(PurpleAccount *account) +{ + return icq_get_purple_moods(account); +} + const char *oscar_list_icon_icq(PurpleAccount *a, PurpleBuddy *b) { const char *name = b ? purple_buddy_get_name(b) : NULL; @@ -6037,6 +6204,13 @@ return "secure"; if (userinfo->icqinfo.status & AIM_ICQ_STATE_BIRTHDAY) return "birthday"; + + /* 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"; } return NULL; } @@ -6259,9 +6433,53 @@ purple_value_new(PURPLE_TYPE_STRING), NULL); status_types = g_list_prepend(status_types, type); - type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, OSCAR_STATUS_ID_FREE4CHAT, - _("Free For Chat"), TRUE, is_icq, FALSE); + _("Free For Chat"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + + status_types = g_list_prepend(status_types, type); + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_EVIL, + _("Evil"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_DEPRESSION, + _("Depression"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_ATHOME, + _("At home"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_ATWORK, + _("At work"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_LUNCH, + _("Lunch"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, @@ -6271,9 +6489,12 @@ purple_value_new(PURPLE_TYPE_STRING), NULL); status_types = g_list_prepend(status_types, type); - type = purple_status_type_new_full(PURPLE_STATUS_INVISIBLE, + type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE, OSCAR_STATUS_ID_INVISIBLE, - NULL, TRUE, TRUE, FALSE); + NULL, TRUE, TRUE, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); type = purple_status_type_new_full(PURPLE_STATUS_MOBILE, OSCAR_STATUS_ID_MOBILE, NULL, FALSE, FALSE, TRUE); @@ -6306,9 +6527,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) { @@ -6480,19 +6706,21 @@ } } -static void -oscar_get_aim_info_cb(PurpleBlistNode *node, gpointer ignore) +static void oscar_get_icqxstatusmsg (PurpleBlistNode *node, gpointer ignore) { PurpleBuddy *buddy; PurpleConnection *gc; - + PurpleAccount *account; + + g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *)node; - gc = purple_account_get_connection(purple_buddy_get_account(buddy)); - - aim_locate_getinfoshort(purple_connection_get_protocol_data(gc), - purple_buddy_get_name(buddy), 0x00000003); + gc = purple_account_get_connection(buddy->account); + account = purple_connection_get_account(gc); + purple_debug_info("oscar", "Manual X-Status Get From %s to %s:\n", purple_buddy_get_name(buddy), account->username); + + icq_im_xstatus_request(gc->proto_data, purple_buddy_get_name(buddy)); } static GList * @@ -6529,15 +6757,13 @@ menu = g_list_prepend(menu, act); } -#if 0 if (od->icq) { - act = purple_menu_action_new(_("Get Status Msg"), - PURPLE_CALLBACK(oscar_get_icqstatusmsg), + act = purple_menu_action_new(_("Get X-Status Msg"), + PURPLE_CALLBACK(oscar_get_icqxstatusmsg), NULL, NULL); menu = g_list_prepend(menu, act); } -#endif if (userinfo && oscar_util_name_compare(purple_account_get_username(account), bname) && diff -r 791606778223 -r a538cb73f897 libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.h Sun Feb 07 19:31:56 2010 +0000 @@ -375,8 +375,14 @@ OSCAR_CAPABILITY_CAMERA = 0x04000000, OSCAR_CAPABILITY_ICHAT_SCREENSHARE = 0x08000000, OSCAR_CAPABILITY_TYPING = 0x10000000, - OSCAR_CAPABILITY_GENERICUNKNOWN = 0x20000000, - OSCAR_CAPABILITY_LAST = 0x40000000 + OSCAR_CAPABILITY_NEWCAPS = 0x20000000, + OSCAR_CAPABILITY_XTRAZ = 0x40000000, + OSCAR_CAPABILITY_GENERICUNKNOWN = 0x80000000, +#warning Fix OSCAR_CAPABILITY_LAST situation +#if 0 + // TODO: We're out of bits. Rework things that depend on this or remove some capability. (Or, ensure this is a 64-bit type.) + OSCAR_CAPABILITY_LAST = 0x100000000 +#endif } OscarCapability; /* @@ -535,6 +541,7 @@ struct { struct aim_userinfo_s *userinfo; + struct userinfo_node *requested; } locate; struct { @@ -572,6 +579,12 @@ #define AIM_ICQ_STATE_BUSY 0x00000010 #define AIM_ICQ_STATE_CHAT 0x00000020 #define AIM_ICQ_STATE_INVISIBLE 0x00000100 +#define AIM_ICQ_STATE_EVIL 0x00003000 +#define AIM_ICQ_STATE_DEPRESSION 0x00004000 +#define AIM_ICQ_STATE_ATHOME 0x00005000 +#define AIM_ICQ_STATE_ATWORK 0x00006000 +#define AIM_ICQ_STATE_LUNCH 0x00002001 +#define AIM_ICQ_STATE_EVIL 0x00003000 #define AIM_ICQ_STATE_WEBAWARE 0x00010000 #define AIM_ICQ_STATE_HIDEIP 0x00020000 #define AIM_ICQ_STATE_BIRTHDAY 0x00080000 @@ -1012,7 +1025,8 @@ /* 0x0008 */ int aim_im_warn(OscarData *od, FlapConnection *conn, const char *destbn, guint32 flags); /* 0x000b */ int aim_im_denytransfer(OscarData *od, const char *bn, const guchar *cookie, guint16 code); /* 0x0010 */ int aim_im_reqofflinemsgs(OscarData *od); -/* 0x0014 */ int aim_im_sendmtn(OscarData *od, guint16 channel, const char *bn, guint16 event); +/* 0x0014 */ int aim_im_sendmtn(OscarData *od, guint16 type1, const char *bn, guint16 type2); +/* 0x000b */ int icq_relay_xstatus (OscarData *od, const char *sn, const guchar* cookie); void aim_icbm_makecookie(guchar* cookie); gchar *oscar_encoding_extract(const char *encoding); gchar *oscar_encoding_to_utf8(PurpleAccount *account, const char *encoding, const char *text, int textlen); @@ -1144,8 +1158,11 @@ void aim_info_free(aim_userinfo_t *); int aim_info_extract(OscarData *od, ByteStream *bs, aim_userinfo_t *); int aim_putuserinfo(ByteStream *bs, aim_userinfo_t *info); - - +#endif +PurpleMood* icq_get_purple_moods(PurpleAccount *account); +const char* icq_get_custom_icon_description(const char *mood); +guint8* icq_get_custom_icon_data(const char *mood); +int icq_im_xstatus_request(OscarData *od, const char *sn); /* 0x0003 - family_buddy.c */ /* 0x0002 */ void aim_buddylist_reqrights(OscarData *, FlapConnection *); diff -r 791606778223 -r a538cb73f897 libpurple/protocols/oscar/oscarcommon.h --- a/libpurple/protocols/oscar/oscarcommon.h Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/oscar/oscarcommon.h Sun Feb 07 19:31:56 2010 +0000 @@ -30,6 +30,7 @@ #include "prpl.h" #include "version.h" #include "notify.h" +#include "status.h" #define OSCAR_DEFAULT_LOGIN_SERVER "login.messaging.aol.com" #define OSCAR_DEFAULT_LOGIN_PORT 5190 @@ -51,6 +52,7 @@ #ifdef _WIN32 const char *oscar_get_locale_charset(void); #endif +PurpleMood* oscar_get_purple_moods(PurpleAccount *account); const char *oscar_list_icon_icq(PurpleAccount *a, PurpleBuddy *b); const char *oscar_list_icon_aim(PurpleAccount *a, PurpleBuddy *b); const char* oscar_list_emblem(PurpleBuddy *b); diff -r 791606778223 -r a538cb73f897 libpurple/protocols/oscar/tlv.c --- a/libpurple/protocols/oscar/tlv.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/oscar/tlv.c Sun Feb 07 19:31:56 2010 +0000 @@ -407,10 +407,11 @@ * @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) +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; + guint8 *data; if (caps == 0) return 0; /* nothing there anyway */ @@ -418,6 +419,11 @@ byte_stream_init(&bs, buf, sizeof(buf)); byte_stream_putcaps(&bs, caps); + + /* adding of custom icon GUID */ + data = icq_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); } diff -r 791606778223 -r a538cb73f897 libpurple/protocols/sametime/sametime.c --- a/libpurple/protocols/sametime/sametime.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/sametime/sametime.c Sun Feb 07 19:31:56 2010 +0000 @@ -3527,10 +3527,10 @@ purple_request_field_list_set_multi_select(f, FALSE); for(; confs; confs = confs->next) { struct mwConference *c = confs->data; - purple_request_field_list_add(f, mwConference_getTitle(c), c); + purple_request_field_list_add_icon(f, mwConference_getTitle(c), NULL, c); } - purple_request_field_list_add(f, _("Create New Conference..."), - GINT_TO_POINTER(0x01)); + purple_request_field_list_add_icon(f, _("Create New Conference..."), + NULL, GINT_TO_POINTER(0x01)); purple_request_field_group_add_field(g, f); f = purple_request_field_string_new(CHAT_KEY_INVITE, "Message", NULL, FALSE); @@ -5458,7 +5458,7 @@ res->id = g_strdup(match->id); res->name = g_strdup(match->name); - purple_request_field_list_add(f, res->name, res); + purple_request_field_list_add_icon(f, res->name, NULL, res); } purple_request_field_group_add_field(g, f); diff -r 791606778223 -r a538cb73f897 libpurple/protocols/silc/buddy.c --- a/libpurple/protocols/silc/buddy.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/silc/buddy.c Sun Feb 07 19:31:56 2010 +0000 @@ -1183,7 +1183,7 @@ client_entry->username, *client_entry->hostname ? client_entry->hostname : "", fingerprint ? tmp2 : ""); - purple_request_field_list_add(f, tmp, client_entry); + purple_request_field_list_add_icon(f, tmp, NULL, client_entry); silc_free(fingerprint); } diff -r 791606778223 -r a538cb73f897 libpurple/protocols/silc/chat.c --- a/libpurple/protocols/silc/chat.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/silc/chat.c Sun Feb 07 19:31:56 2010 +0000 @@ -475,7 +475,7 @@ g_snprintf(tmp2, sizeof(tmp2), "%s\n %s\n %s", ident->realname ? ident->realname : ident->username ? ident->username : "", fingerprint, babbleprint); - purple_request_field_list_add(f, tmp2, public_key); + purple_request_field_list_add_icon(f, tmp2, NULL, public_key); silc_free(fingerprint); silc_free(babbleprint); diff -r 791606778223 -r a538cb73f897 libpurple/protocols/silc10/buddy.c --- a/libpurple/protocols/silc10/buddy.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/silc10/buddy.c Sun Feb 07 19:31:56 2010 +0000 @@ -1176,7 +1176,7 @@ clients[i]->username, clients[i]->hostname ? clients[i]->hostname : "", fingerprint ? tmp2 : ""); - purple_request_field_list_add(f, tmp, clients[i]); + purple_request_field_list_add_icon(f, tmp, NULL, clients[i]); silc_free(fingerprint); } diff -r 791606778223 -r a538cb73f897 libpurple/protocols/silc10/chat.c --- a/libpurple/protocols/silc10/chat.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/protocols/silc10/chat.c Sun Feb 07 19:31:56 2010 +0000 @@ -449,7 +449,7 @@ g_snprintf(tmp2, sizeof(tmp2), "%s\n %s\n %s", ident->realname ? ident->realname : ident->username ? ident->username : "", fingerprint, babbleprint); - purple_request_field_list_add(f, tmp2, pubkey); + purple_request_field_list_add_icon(f, tmp2, NULL, pubkey); silc_free(fingerprint); silc_free(babbleprint); diff -r 791606778223 -r a538cb73f897 libpurple/prpl.h --- a/libpurple/prpl.h Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/prpl.h Sun Feb 07 19:31:56 2010 +0000 @@ -569,6 +569,12 @@ */ PurpleMediaCaps (*get_media_caps)(PurpleAccount *account, const char *who); + + /** + * Returns an array of "PurpleMood"s, with the last one having + * "mood" set to @c NULL. + */ + PurpleMood *(*get_moods)(PurpleAccount *account); }; #define PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, member) \ diff -r 791606778223 -r a538cb73f897 libpurple/request.c --- a/libpurple/request.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/request.c Sun Feb 07 19:31:56 2010 +0000 @@ -850,13 +850,40 @@ purple_request_field_list_add(PurpleRequestField *field, const char *item, void *data) { + purple_request_field_list_add_icon(field, item, NULL, data); +} + +void +purple_request_field_list_add_icon(PurpleRequestField *field, const char *item, const char* icon_path, + void *data) +{ g_return_if_fail(field != NULL); g_return_if_fail(item != NULL); g_return_if_fail(data != NULL); g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST); + if (icon_path) + { + if (field->u.list.icons == NULL) + { + GList *l; + for (l = field->u.list.items ; l != NULL ; l = l->next) + { + /* Order doesn't matter, because we're just + * filing in blank items. So, we use + * g_list_prepend() because it's faster. */ + field->u.list.icons = g_list_prepend(field->u.list.icons, NULL); + } + } + field->u.list.icons = g_list_append(field->u.list.icons, g_strdup(icon_path)); + } + else if (field->u.list.icons) + { + /* Keep this even with the items list. */ + field->u.list.icons = g_list_append(field->u.list.icons, NULL); + } + field->u.list.items = g_list_append(field->u.list.items, g_strdup(item)); - g_hash_table_insert(field->u.list.item_data, g_strdup(item), data); } @@ -962,6 +989,15 @@ return field->u.list.items; } +GList * +purple_request_field_list_get_icons(const PurpleRequestField *field) +{ + g_return_val_if_fail(field != NULL, NULL); + g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL); + + return field->u.list.icons; +} + PurpleRequestField * purple_request_field_label_new(const char *id, const char *text) { diff -r 791606778223 -r a538cb73f897 libpurple/request.h --- a/libpurple/request.h Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/request.h Sun Feb 07 19:31:56 2010 +0000 @@ -150,6 +150,7 @@ struct { GList *items; + GList *icons; GHashTable *item_data; GList *selected; GHashTable *selected_table; @@ -947,15 +948,30 @@ void *purple_request_field_list_get_data(const PurpleRequestField *field, const char *text); +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_REQUEST_C_) /** * Adds an item to a list field. * * @param field The list field. * @param item The list item. * @param data The associated data. + * + * @deprecated Use purple_request_field_list_add_icon() instead. */ void purple_request_field_list_add(PurpleRequestField *field, const char *item, void *data); +#endif + +/** + * Adds an item to a list field. + * + * @param field The list field. + * @param item The list item. + * @param icon_path The path to icon file, or @c NULL for no icon. + * @param data The associated data. + */ +void purple_request_field_list_add_icon(PurpleRequestField *field, + const char *item, const char* icon_path, void* data); /** * Adds a selected item to the list field. @@ -1015,6 +1031,18 @@ */ GList *purple_request_field_list_get_items(const PurpleRequestField *field); +/** + * Returns a list of icons in a list field. + * + * The icons will correspond with the items, in order. + * + * @param field The field. + * + * @constreturn The list of icons or @c NULL (i.e. the empty GList) if no + * items have icons. + */ +GList *purple_request_field_list_get_icons(const PurpleRequestField *field); + /*@}*/ /**************************************************************************/ diff -r 791606778223 -r a538cb73f897 libpurple/status.c --- a/libpurple/status.c Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/status.c Sun Feb 07 19:31:56 2010 +0000 @@ -137,6 +137,7 @@ -200, /* extended away */ -400, /* mobile */ 0, /* tune */ + 0, /* mood */ -10, /* idle, special case. */ -5, /* idle time, special case. */ 10 /* Offline messageable */ @@ -157,15 +158,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 * diff -r 791606778223 -r a538cb73f897 libpurple/status.h --- a/libpurple/status.h Fri Feb 05 14:40:39 2010 +0000 +++ b/libpurple/status.h Sun Feb 07 19:31:56 2010 +0000 @@ -87,6 +87,12 @@ typedef struct _PurplePresence PurplePresence; typedef struct _PurpleStatus PurpleStatus; +typedef struct _PurpleMood { + const char *mood; + const char *description; + gpointer *padding; +} PurpleMood; + /** * A context for a presence. * @@ -106,8 +112,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 { @@ -120,6 +125,7 @@ PURPLE_STATUS_EXTENDED_AWAY, PURPLE_STATUS_MOBILE, PURPLE_STATUS_TUNE, + PURPLE_STATUS_MOOD, PURPLE_STATUS_NUM_PRIMITIVES } PurpleStatusPrimitive; @@ -139,6 +145,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 diff -r 791606778223 -r a538cb73f897 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/gtkblist.c Sun Feb 07 19:31:56 2010 +0000 @@ -3705,7 +3705,8 @@ /* Offline? */ - /* FIXME: Why is this status special-cased by the core? -- rlaager */ + /* FIXME: Why is this status special-cased by the core? --rlaager + * FIXME: Alternatively, why not have the core do all of them? --rlaager */ if (!PURPLE_BUDDY_IS_ONLINE(b)) { purple_notify_user_info_add_pair(user_info, _("Status"), _("Offline")); } @@ -3800,6 +3801,24 @@ return pb; } +static char *get_mood_icon_path(const char *mood) +{ + char *path; + + if (!strcmp(mood, "busy")) { + path = g_build_filename(DATADIR, "pixmaps", "pidgin", + "status", "16", "busy.png", NULL); + } else if (!strcmp(mood, "hiptop")) { + path = g_build_filename(DATADIR, "pixmaps", "pidgin", + "emblems", "16", "hiptop.png", NULL); + } else { + char *filename = g_strdup_printf("%s.png", mood); + path = g_build_filename(DATADIR, "pixmaps", "pidgin", + "emotes", "small", filename, NULL); + g_free(filename); + } + return path; +} GdkPixbuf * pidgin_blist_get_emblem(PurpleBlistNode *node) @@ -3811,7 +3830,7 @@ PurplePluginProtocolInfo *prpl_info; const char *name = NULL; char *filename, *path; - PurplePresence *p; + PurplePresence *presence = NULL; PurpleStatus *tune; if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { @@ -3822,16 +3841,19 @@ } 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)) { - path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", - "16", "mobile.png", NULL); + presence = purple_buddy_get_presence(buddy); + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOBILE)) { + /* This emblem comes from the small emoticon set now, + * to reduce duplication. */ + path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", + "small", "mobile.png", NULL); return _pidgin_blist_get_cached_emblem(path); } if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded) { - if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) - return pidgin_create_prpl_icon(((PurpleBuddy*)node)->account, PIDGIN_PRPL_ICON_SMALL); + if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) + return NULL; + return pidgin_create_prpl_icon(((PurpleBuddy*)node)->account, PIDGIN_PRPL_ICON_SMALL); } } else { return NULL; @@ -3844,9 +3866,14 @@ return _pidgin_blist_get_cached_emblem(path); } - p = purple_buddy_get_presence(buddy); - if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) { - path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "mobile.png", NULL); + /* 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)) { + /* This emblem comes from the small emoticon set now, to reduce duplication. */ + path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", "small", "mobile.png", NULL); return _pidgin_blist_get_cached_emblem(path); } @@ -3865,7 +3892,8 @@ return _pidgin_blist_get_cached_emblem(path); } /* Regular old "tune" is the only one in all protocols. */ - path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "music.png", NULL); + /* This emblem comes from the small emoticon set now, to reduce duplication. */ + path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", "small", "music.png", NULL); return _pidgin_blist_get_cached_emblem(path); } @@ -3877,13 +3905,24 @@ if (prpl_info && prpl_info->list_emblem) name = prpl_info->list_emblem(buddy); - if (name == NULL) - return NULL; - - filename = g_strdup_printf("%s.png", name); - - path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL); - g_free(filename); + if (name == NULL) { + 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; + + path = get_mood_icon_path(name); + } else { + filename = g_strdup_printf("%s.png", name); + path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL); + g_free(filename); + } /* _pidgin_blist_get_cached_emblem() assumes ownership of path */ return _pidgin_blist_get_cached_emblem(path); @@ -7989,6 +8028,7 @@ PurpleAccount *account = NULL; GdkPixbuf *pixbuf = NULL; PurplePlugin *plugin = NULL; + PurplePluginProtocolInfo *prpl_info account = accounts->data; @@ -8028,12 +8068,38 @@ gc = purple_account_get_connection(account); plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL; - if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) { - build_plugin_actions(submenu, plugin, gc); - } else { - menuitem = gtk_menu_item_new_with_label(_("No actions available")); - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); - gtk_widget_set_sensitive(menuitem, FALSE); + + if (plugin && + (prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin)) && + PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods)) + { + GList *types; + for (types = purple_account_get_status_types(account); + types != NULL ; types = types->next) + { + PurpleStatusType *type = types->data; + + if (strcmp(purple_status_type_get_id(type), "mood") != 0) + continue; + + menuitem = gtk_menu_item_new_with_mnemonic(_("Set _Mood...")); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(set_mood_cb), account); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + + /* Be safe. It shouldn't match more than once anyway */ + break; + } + } + else + { + if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) { + build_plugin_actions(submenu, plugin, gc); + } else { + menuitem = gtk_menu_item_new_with_label(_("No actions available")); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_set_sensitive(menuitem, FALSE); + } } pidgin_separator(submenu); diff -r 791606778223 -r a538cb73f897 pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/gtkrequest.c Sun Feb 07 19:31:56 2010 +0000 @@ -1066,6 +1066,9 @@ GtkTreeViewColumn *column; GtkTreeIter iter; GList *l; + GList *icons = NULL; + + icons = purple_request_field_list_get_icons(field); /* Create the scrolled window */ sw = gtk_scrolled_window_new(NULL, NULL); @@ -1077,7 +1080,10 @@ gtk_widget_show(sw); /* Create the list store */ - store = gtk_list_store_new(2, G_TYPE_POINTER, G_TYPE_STRING); + if (icons) + store = gtk_list_store_new(3, G_TYPE_POINTER, G_TYPE_STRING, GDK_TYPE_PIXBUF); + else + store = gtk_list_store_new(2, G_TYPE_POINTER, G_TYPE_STRING); /* Create the tree view */ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); @@ -1096,13 +1102,38 @@ gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_add_attribute(column, renderer, "text", 1); + if (icons) + { + renderer = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, renderer, TRUE); + gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", 2); + + gtk_widget_set_size_request(treeview, 200, 400); + } + for (l = purple_request_field_list_get_items(field); l != NULL; l = l->next) { const char *text = (const char *)l->data; gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, + if (icons) + { + const char *icon_path = (const char *)icons->data; + GdkPixbuf* pixbuf = NULL; + + if (icon_path) + pixbuf = gdk_pixbuf_new_from_file(icon_path, NULL); + + gtk_list_store_set(store, &iter, + 0, purple_request_field_list_get_data(field, text), + 1, text, + 2, pixbuf, + -1); + icons = icons->next; + } + else + gtk_list_store_set(store, &iter, 0, purple_request_field_list_get_data(field, text), 1, text, -1); diff -r 791606778223 -r a538cb73f897 pidgin/gtksavedstatuses.c --- a/pidgin/gtksavedstatuses.c Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/gtksavedstatuses.c Sun Feb 07 19:31:56 2010 +0000 @@ -907,7 +907,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. diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/Makefile.am --- a/pidgin/pixmaps/Makefile.am Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/pixmaps/Makefile.am Sun Feb 07 19:31:56 2010 +0000 @@ -101,8 +101,6 @@ emblems/16/half-operator.png \ emblems/16/hiptop.png \ emblems/16/male.png \ - emblems/16/mobile.png \ - emblems/16/music.png \ emblems/16/not-authorized.png \ emblems/16/operator.png \ emblems/16/qq-member.png \ @@ -207,6 +205,7 @@ emotes/default/24/scalable/yin-yang.svg EMOTES_SMALL_16_SCALABLE = \ + emotes/small/16/scalable/mobile.svg emotes/small/16/scalable/pidgin-emotes.svg PROTOCOLS_16_SCALABLE = \ diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emblems/16/mobile.png Binary file pidgin/pixmaps/emblems/16/mobile.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emblems/16/music.png Binary file pidgin/pixmaps/emblems/16/music.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emblems/scalable/mobile.svg --- a/pidgin/pixmaps/emblems/scalable/mobile.svg Fri Feb 05 14:40:39 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emblems/scalable/music.svg --- a/pidgin/pixmaps/emblems/scalable/music.svg Fri Feb 05 14:40:39 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/Makefile.am --- a/pidgin/pixmaps/emotes/default/24/Makefile.am Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/pixmaps/emotes/default/24/Makefile.am Sun Feb 07 19:31:56 2010 +0000 @@ -2,6 +2,7 @@ act-up.png \ airplane.png \ alien.png \ + amorous.png \ angel.png \ angry.png \ arrogant.png \ @@ -56,8 +57,9 @@ dont-know.png \ drink.png \ drool.png \ - eat.png \ + hungry.png \ embarrassed.png \ + excited.png \ excruciating.png \ eyeroll.png \ female-fighter.png \ @@ -81,7 +83,7 @@ hug-left.png \ hug-right.png \ hypnotized.png \ - in-love.png \ + in_love.png \ island.png \ jump.png \ kissed.png \ @@ -94,7 +96,6 @@ liquor.png \ loser.png \ love-over.png \ - love.png \ lying.png \ mad-tongue.png \ mail.png \ @@ -114,7 +115,7 @@ msn.png \ musical-note.png \ music.png \ - nailbiting.png \ + nervous.png \ neutral.png \ on-the-phone.png \ party.png \ @@ -144,7 +145,7 @@ secret.png \ shame.png \ sheep.png \ - shock.png \ + shocked.png \ shout.png \ shut-mouth.png \ sick.png \ @@ -153,9 +154,9 @@ sinister.png \ skeleton.png \ skywalker.png \ + sleeping.png \ sleepy.png \ - smile-big.png \ - smile.png \ + happy.png \ smirk.png \ snail.png \ snicker.png \ @@ -167,7 +168,7 @@ stop.png \ struggle.png \ sun.png \ - sweat.png \ + hot.png \ talktohand.png \ teeth.png \ terror.png \ @@ -175,7 +176,7 @@ thunder.png \ time-out.png \ tongue.png \ - tremble.png \ + afraid.png \ turtle.png \ tv.png \ umbrella.png \ @@ -188,7 +189,6 @@ wilt.png \ wink.png \ worship.png \ - yawn.png \ yin-yang.png diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/afraid.png Binary file pidgin/pixmaps/emotes/default/24/afraid.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/amorous.png Binary file pidgin/pixmaps/emotes/default/24/amorous.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/default.theme.in --- a/pidgin/pixmaps/emotes/default/24/default.theme.in Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/pixmaps/emotes/default/24/default.theme.in Sun Feb 07 19:31:56 2010 +0000 @@ -6,16 +6,16 @@ # Default smileys [default] -smile.png :) :-) -smile-big.png :-D :-d :D :d +happy.png :) :-) +excited.png :-D :-d :D :d sad.png :-( :( wink.png ;-) ;) -tongue.png :P :-P :-p :p -shock.png =-O =-o +tongue.png :P :p :-P :-p +shocked.png =-O =-o kiss.png :-* glasses-cool.png 8-) embarrassed.png :-[ -crying.png :'( +crying.png :'( :'-( thinking.png :-/ :-\\ angel.png O:-) o:-) shut-mouth.png :-X @@ -23,20 +23,70 @@ foot-in-mouth.png :-! shout.png >:o >:O ! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) :(|) 8-|) -! cyclops.png O-) o-) +! monkey.png :-(|) :(|) 8-|) +! cyclops.png O-) o-) + + +[XMPP] +# Following XEP-0038 + GTalk + our default set, in default set order +# The GTalk strings come from ticket #3307. +happy.png :) :-) =) +excited.png :-D :-d :D :d =D =d +sad.png :-( :( +wink.png ;-) ;) ;^) +tongue.png :P :p :-P :-p +shocked.png =-O =-o :-O :-o +kiss.png :kiss: :-* +glasses-cool.png 8-) B-) +embarrassed.png :-[ +crying.png :'-( :'( +thinking.png :-/ :-\\ +angel.png O:-) o:-) +shut-mouth.png :-X +moneymouth.png :-$ +foot-in-mouth.png :-! +shout.png >:o >:O + +# Following XEP-0038 + GTalk +angry.png >:-( >:( X-( x-( +good.png :yes: +bad.png :no: +stop.png :wait: +rose.png @->-- :rose: +phone.png :telephone: +mail.png :email: +lamp.png :jabber: +cake.png :cake: +in_love.png :heart: :love: <3 +love-over.png :brokenheart: +musical-note.png :music: +beer.png :beer: +coffee.png :coffee: +coins.png :money: +moon.png :moon: +sun.png :sun: +star.png :star: + +# Others +neutral.png :| :-| +victory.png \\m/ + +# Hidden icons from the default set. +! skywalker.png C:-) c:-) C:) c:) +! monkey.png :-(|) :(|) 8-|) +! cyclops.png O-) o-) # Following AIM 6.1 [AIM] -smile.png :-) :) +happy.png :-) :) wink.png ;-) ;) sad.png :-( :( -tongue.png :-P :P :-p :p -shock.png =-O +tongue.png :P :p :-P :-p +shocked.png =-O kiss.png :-* shout.png >:o -smile-big.png :-D :D +excited.png :-D :D moneymouth.png :-$ foot-in-mouth.png :-! embarrassed.png :-[ @@ -46,26 +96,27 @@ shut-mouth.png :-X glasses-cool.png 8-) ! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) :(|) +! monkey.png :-(|) :(|) 8-|) +! cyclops.png O-) o-) # Following Windows Live Messenger 8.1 [MSN] -smile.png :) :-) -smile-big.png :D :d :-D :-d +happy.png :) :-) +excited.png :D :d :-D :-d wink.png ;) ;-) -shock.png :-O :-o :O :o -tongue.png :P :p :-P :-p +shocked.png :-O :-o :O :o +tongue.png :-P :P :-p :p glasses-cool.png (H) (h) angry.png :@ :-@ embarrassed.png :$ :-$ -confused.png :S :s :-S :-s +confused.png :S :s :-S :-s sad.png :( :-( crying.png :'( neutral.png :| :-| devil.png (6) angel.png (A) (a) -love.png (L) (l) +in_love.png (L) (l) love-over.png (U) (u) msn.png (M) (m) cat.png (@) @@ -125,10 +176,11 @@ thunder.png (li) party.png <:o) eyeroll.png 8-) -yawn.png |-) +sleepy.png |-) bunny.png ('.') ! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) :(|) +! monkey.png :-(|) :(|) 8-|) +! cyclops.png O-) o-) # Hidden MSN emotes cigarette.png (ci) (CI) @@ -139,7 +191,7 @@ # Following QQ 2006 [QQ] -shock.png /:O /jy /surprised +shocked.png /:O /jy /surprised curl-lip.png /:~ /pz /curl_lip desire.png /:* /se /desire dazed.png /:| /dazed @@ -147,13 +199,13 @@ crying.png /:< /ll /cry bashful.png /:$ /hx /bashful shut-mouth.png /:X /bz /shut_mouth -sleepy.png /:Z /shui /sleep +sleeping.png /:Z /shui /sleep weep.png /:'( /dk /weep embarrassed.png /:-| /gg /embarassed pissed-off.png /:@ /fn /pissed_off act-up.png /:P /tp /act_up -smile-big.png /:D /cy /toothy_smile -smile.png /:) /wx /small_smile +excited.png /:D /cy /toothy_smile +happy.png /:) /wx /small_smile sad.png /:( /ng /sad glasses-cool.png /:+ /kuk /cool doctor.png /:# /feid /SARS @@ -164,9 +216,9 @@ disdain.png /;d /by /disdain arrogant.png /;o /am /arrogant starving.png /:g /jie /starving -yawn.png /|-) /kun /sleepy +sleepy.png /|-) /kun /sleepy terror.png /:! /jk /terror -sweat.png /:L /sweat +hot.png /:L /sweat smirk.png /:> /hanx /smirk soldier.png /:; /db /soldier struggle.png /;f /fendou /struggle @@ -180,8 +232,8 @@ hammer.png /xx /qiao /hammer bye.png /bye /zj /bye go-away.png /go /shan /go -tremble.png /shake /fad /shake -in-love.png /love /aiq /love +afraid.png /shake /fad /shake +amorous.png /love /aiq /love jump.png /jump /tiao /jump search.png /find /zhao /search lashes.png /& /mm /beautiful_eyebrows @@ -200,12 +252,12 @@ musical-note.png /music /yy /music poop.png /shit /bb /shit coffee.png /coffee /kf /coffee -eat.png /eat /fan /eat +hungry.png /eat /fan /eat pill.png /pill /yw /pill rose.png /rose /mg /rose wilt.png /fade /dx /wilt kiss.png /kiss /wen /kiss -love.png /heart /xin /heart +in_love.png /heart /xin /heart love-over.png /break /xs /broken_heart meeting.png /meeting /hy /meeting present.png /gift /lw /gift @@ -233,20 +285,21 @@ girl.png /<00> /nv /woman boy.png /<11> /nan /man ! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) :(|) +! monkey.png :-(|) :(|) 8-|) +! cyclops.png O-) o-) # Following ICQ 6.0 [ICQ] -smile.png :-) :) +happy.png :-) :) neutral.png :-$ sad.png :-( :( -shock.png =-O +shocked.png =-O wink.png ;-) ;) tongue.png :-P :P :-p :p music.png [:-} laugh.png *JOKINGLY* -sleepy.png *TIRED* +sleeping.png *TIRED* crying.png :'( :'-( sick.png :-! kissed.png *KISSED* @@ -265,26 +318,27 @@ good.png *THUMBS\ UP* shout.png >:o >:O :-@ beer.png *DRINK* -smile-big.png :-D :D +excited.png :-D :D glasses-cool.png 8-) -in-love.png *IN\ LOVE* +amorous.png *IN\ LOVE* ! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) :(|) +! monkey.png :-(|) :(|) 8-|) +! cyclops.png O-) o-) # Following Yahoo! Messenger 8.1 [Yahoo] -smile.png :) :-) +happy.png :) :-) question.png :-/ :-\\ -shock.png :-O :O :-o :o +shocked.png :-O :O :-o :o devil.png >:) angel.png O:-) o:-) 0:-) sick.png :-& -yawn.png (:| +sleepy.png (:| hypnotized.png @-) on-the-phone.png :)] sad.png :( :-( -in-love.png :x :-x :X :-X +amorous.png :x :-x :X :-X angry.png X-( x-( X( x( crying.png :(( glasses-nerdy.png :-B :-b @@ -301,11 +355,11 @@ thinking.png :-? waiting.png :-w :-W at-wits-end.png ~x( ~X( -smile-big.png :D :-D :d :-d +excited.png :D :-D :d :-d tongue.png :-P :P :-p :p glasses-cool.png B-) b-) neutral.png :| :-| -sleepy.png I-) i-) |-) +sleeping.png I-) i-) |-) clown.png :o) :O) doh.png #-o #-O weep.png :-< @@ -321,107 +375,16 @@ time-out.png :-t :-T hug-left.png >:D< >:d< love-over.png =(( -sweat.png #:-S #:-s +hot.png #:-S #:-s rotfl.png =)) :-j :-J loser.png L-) l-) party.png <:-P <:-p -nailbiting.png :-SS :-Ss :-sS :-ss +nervous.png :-SS :-Ss :-sS :-ss cowboy.png <):) desire.png 8-> ! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) :(|) - -# Hidden Yahoo emotes -alien.png =:) >-) -beat-up.png b-( B-( -chicken.png ~:> -coffee.png ~o) ~O) -cow.png 3:-O 3:-o -dance.png \\:D/ \\:d/ -rose.png @};- -dont-know.png :-L :-l -skeleton.png 8-X 8-x -lamp.png *-:) -monkey.png :(|) -coins.png $-) -peace.png :)>- -pig.png :@) -pray.png [-o< [-O< -pumpkin.png (~~) -shame.png [-X [-x -flag.png **== -clover.png %%- -musical-note.png :-" -giggle.png ;)) -worship.png ^:)^ -star.png (*) -waving.png >:/ -talktohand.png :-@ - -# Only available after activating the Yahoo! Fighter IMVironment -male-fighter1.png o-> O-> -male-fighter2.png o=> O=> -female-fighter.png o-+ O-+ -yin-yang.png (%) - -# Following Yahoo! Messenger 8.1 -[Yahoo JAPAN] -smile.png :) :-) -question.png :-/ :-\\ -shock.png :-O :O :-o :o -devil.png >:) -angel.png O:-) o:-) 0:-) -sick.png :-& -yawn.png (:| -hypnotized.png @-) -on-the-phone.png :)] -sad.png :( :-( -in-love.png :x :-x :X :-X -angry.png X-( x-( X( x( -crying.png :(( -glasses-nerdy.png :-B :-b -quiet.png :-$ -drool.png =P~ =p~ -lying.png :^O :^o -call-me.png :-c -wink.png ;) ;-) -embarrassed.png :"> -mean.png :-> :> -laugh.png :)) :-)) -bye.png =; -arrogant.png [-( -thinking.png :-? -waiting.png :-w :-W -at-wits-end.png ~x( ~X( -smile-big.png :D :-D :d :-d -tongue.png :-P :P :-p :p -glasses-cool.png B-) b-) -neutral.png :| :-| -sleepy.png I-) i-) |-) -clown.png :o) :O) -doh.png #-o #-O -weep.png :-< -go-away.png :-h -lashes.png ;;) -kiss.png :-* :* -confused.png :-S :-s -sarcastic.png /:) -eyeroll.png 8-| -silly.png 8-} -clap.png =D> =d> -mad-tongue.png >:P >:p -time-out.png :-t :-T -hug-left.png >:D< >:d< -love-over.png =(( -sweat.png #:-S #:-s -rotfl.png =)) :-j :-J -loser.png L-) l-) -party.png <:-P <:-p -nailbiting.png :-SS :-Ss :-sS :-ss -cowboy.png <):) -desire.png 8-> -! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) :(|) +! monkey.png :-(|) :(|) 8-|) +! cyclops.png O-) o-) # Hidden Yahoo emotes alien.png =:) >-) @@ -459,14 +422,14 @@ # Following MySpaceIM Beta 1.0.697.0 [MySpaceIM] -smile-big.png :D :-D +excited.png :D :-D devil.png }:) confused.png :Z glasses-nerdy.png B) bulgy-eyes.png %) freaked-out.png :E smile.png :) :-) -in-love.png :X +amorous.png :X laugh.png :)) mohawk.png -: mad-tongue.png X( @@ -474,7 +437,7 @@ glasses-nerdy.png Q) doh.png :G pirate.png P) -shock.png :O +shocked.png :O sidefrown.png :{ sinister.png :B smirk.png :, @@ -484,23 +447,7 @@ wink.png ;-) ;) sad.png :[ kiss.png :x +! skywalker.png C:-) c:-) C:) c:) +! monkey.png :-(|) :(|) 8-|) +! cyclops.png O-) o-) -[XMPP] -# XMPP emoticons -smile.png :) :-) =) -smile-big.png :D :-D =D -wink.png ;) ;-) ;^) -shock.png :-o -tongue.png :P :-P :-p :p -glasses-cool.png B-) -angry.png X-( -sad.png :( :-( =( -crying.png :'( -neutral.png :-| -thinking.png :-/ -love.png <3 -monkey.png :(|) -victory.png \\m/ -! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) :(|) 8-|) -! cyclops.png O-) o-) diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/eat.png Binary file pidgin/pixmaps/emotes/default/24/eat.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/excited.png Binary file pidgin/pixmaps/emotes/default/24/excited.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/happy.png Binary file pidgin/pixmaps/emotes/default/24/happy.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/hot.png Binary file pidgin/pixmaps/emotes/default/24/hot.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/hungry.png Binary file pidgin/pixmaps/emotes/default/24/hungry.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/in-love.png Binary file pidgin/pixmaps/emotes/default/24/in-love.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/in_love.png Binary file pidgin/pixmaps/emotes/default/24/in_love.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/love.png Binary file pidgin/pixmaps/emotes/default/24/love.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/nailbiting.png Binary file pidgin/pixmaps/emotes/default/24/nailbiting.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/nervous.png Binary file pidgin/pixmaps/emotes/default/24/nervous.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/shock.png Binary file pidgin/pixmaps/emotes/default/24/shock.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/shocked.png Binary file pidgin/pixmaps/emotes/default/24/shocked.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/sleeping.png Binary file pidgin/pixmaps/emotes/default/24/sleeping.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/sleepy.png Binary file pidgin/pixmaps/emotes/default/24/sleepy.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/smile-big.png Binary file pidgin/pixmaps/emotes/default/24/smile-big.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/smile.png Binary file pidgin/pixmaps/emotes/default/24/smile.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/sweat.png Binary file pidgin/pixmaps/emotes/default/24/sweat.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/tremble.png Binary file pidgin/pixmaps/emotes/default/24/tremble.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/default/24/yawn.png Binary file pidgin/pixmaps/emotes/default/24/yawn.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/Makefile.am --- a/pidgin/pixmaps/emotes/small/16/Makefile.am Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/pixmaps/emotes/small/16/Makefile.am Sun Feb 07 19:31:56 2010 +0000 @@ -1,4 +1,21 @@ +# These are mood images that are NOT also used in the smiley theme. +MOODS = \ + bathing.png \ + cinema.png \ + internet.png \ + music.png \ + restroom.png \ + search.png \ + shopping.png \ + studying.png \ + suit.png \ + surfing.png \ + typing.png \ + working.png \ + writing.png + SMILEYS = \ + amorous.png \ angel.png \ angry.png \ beer.png \ @@ -12,12 +29,15 @@ crying.png \ devil.png \ dont-know.png \ + excited.png \ grin.png \ + happy.png \ hug-left.png \ hug-right.png \ + in_love.png \ kiss.png \ - love.png \ meeting.png \ + mobile.png \ musical-note.png \ nerdy.png \ neutral.png \ @@ -27,18 +47,16 @@ question.png \ sad.png \ shame.png \ - shock.png \ + shocked.png \ sick.png \ silent.png \ + sleeping.png \ sleepy.png \ - smile-big.png \ - smile.png \ thinking.png \ tongue.png \ tv.png \ uhm-yeah.png \ - wink.png \ - yawn.png + wink.png pidginsmileypix_in_files = small.theme.in @@ -46,6 +64,7 @@ if INSTALL_PIXMAPS pidginsmileypixdir = $(datadir)/pixmaps/pidgin/emotes/small pidginsmileypix_DATA = \ + $(MOODS) \ $(SMILEYS) \ theme @@ -56,4 +75,4 @@ $< > $@ endif -EXTRA_DIST = $(SMILEYS) $(pidginsmileypix_in_files) theme +EXTRA_DIST = $(MOODS) $(SMILEYS) $(pidginsmileypix_in_files) theme diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/TODO --- a/pidgin/pixmaps/emotes/small/16/TODO Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/pixmaps/emotes/small/16/TODO Sun Feb 07 19:31:56 2010 +0000 @@ -1,7 +1,18 @@ The following icons where just scaled down from the 24x24 and may need work: + afraid.png + amorous.png + disappointed.png + embarrassed.png + happy.png + hot.png + hungry.png + mean.png meeting.png + nervous.png question.png + sarcastic.png search.png + shocked.png sleepy.png smile-big.png tv.png @@ -13,7 +24,7 @@ cigarette.png coffee.png console.png - love.png + in_love.png musical-note.png party.png phone.png diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/afraid.png Binary file pidgin/pixmaps/emotes/small/16/afraid.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/amorous.png Binary file pidgin/pixmaps/emotes/small/16/amorous.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/bathing.png Binary file pidgin/pixmaps/emotes/small/16/bathing.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/cinema.png Binary file pidgin/pixmaps/emotes/small/16/cinema.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/disappointed.png Binary file pidgin/pixmaps/emotes/small/16/disappointed.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/embarrassed.png Binary file pidgin/pixmaps/emotes/small/16/embarrassed.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/excited.png Binary file pidgin/pixmaps/emotes/small/16/excited.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/happy.png Binary file pidgin/pixmaps/emotes/small/16/happy.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/hot.png Binary file pidgin/pixmaps/emotes/small/16/hot.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/hungry.png Binary file pidgin/pixmaps/emotes/small/16/hungry.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/in_love.png Binary file pidgin/pixmaps/emotes/small/16/in_love.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/internet.png Binary file pidgin/pixmaps/emotes/small/16/internet.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/love.png Binary file pidgin/pixmaps/emotes/small/16/love.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/mean.png Binary file pidgin/pixmaps/emotes/small/16/mean.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/mobile.png Binary file pidgin/pixmaps/emotes/small/16/mobile.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/music.png Binary file pidgin/pixmaps/emotes/small/16/music.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/nervous.png Binary file pidgin/pixmaps/emotes/small/16/nervous.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/restroom.png Binary file pidgin/pixmaps/emotes/small/16/restroom.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/sarcastic.png Binary file pidgin/pixmaps/emotes/small/16/sarcastic.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/scalable/mobile.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pixmaps/emotes/small/16/scalable/mobile.svg Sun Feb 07 19:31:56 2010 +0000 @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/scalable/music.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pixmaps/emotes/small/16/scalable/music.svg Sun Feb 07 19:31:56 2010 +0000 @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/shock.png Binary file pidgin/pixmaps/emotes/small/16/shock.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/shocked.png Binary file pidgin/pixmaps/emotes/small/16/shocked.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/shopping.png Binary file pidgin/pixmaps/emotes/small/16/shopping.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/sleeping.png Binary file pidgin/pixmaps/emotes/small/16/sleeping.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/sleepy.png Binary file pidgin/pixmaps/emotes/small/16/sleepy.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/small.theme.in --- a/pidgin/pixmaps/emotes/small/16/small.theme.in Fri Feb 05 14:40:39 2010 +0000 +++ b/pidgin/pixmaps/emotes/small/16/small.theme.in Sun Feb 07 19:31:56 2010 +0000 @@ -6,27 +6,58 @@ # Default smileys [default] -smile.png :) :-) -smile-big.png :-D :-d :D :d +happy.png :) :-) +excited.png :-D :-d :D :d sad.png :-( :( wink.png ;-) ;) -tongue.png :P :-P :-p :p -shock.png =-O =-o +tongue.png :P :p :-P :-p +shocked.png =-O =-o kiss.png :-* -crying.png :'( +embarrassed.png :-[ +crying.png :'( :'-( thinking.png :-/ :-\\ angel.png O:-) o:-) +[XMPP] +# Following XEP-0038 + GTalk + our default set, in default set order +# The GTalk strings come from ticket #3307. +happy.png :) :-) =) +excited.png :-D :-d :D :d =D =d +sad.png :-( :( +wink.png ;-) ;) ;^) +tongue.png :P :p :-P :-p +shocked.png =-O =-o :-O :-o +kiss.png :kiss: :-* +embarrassed.png :-[ +crying.png :'-( :'( +thinking.png :-/ :-\\ +angel.png O:-) o:-) + +# Following XEP-0038 + GTalk +angry.png >:-( >:( X-( x-( +phone.png :telephone: +in_love.png :heart: :love: <3 +musical-note.png :music: +beer.png :beer: +coffee.png :coffee: + +# Others +neutral.png :| :-| + +# Hidden icons from the default set. + + # Following AIM 6.1 [AIM] -smile.png :-) :) +happy.png :-) :) wink.png ;-) ;) sad.png :-( :( -tongue.png :-P :P :-p :p -shock.png =-O +tongue.png :P :p :-P :-p +shocked.png =-O kiss.png :-* -smile-big.png :-D :D +excited.png :-D :D +embarrassed.png :-[ angel.png O:-) thinking.png :-\\ :-/ crying.png :'( @@ -34,19 +65,20 @@ # Following Windows Live Messenger 8.1 [MSN] -smile.png :) :-) -smile-big.png :D :d :-D :-d +happy.png :) :-) +excited.png :D :d :-D :-d wink.png ;) ;-) -shock.png :-O :-o :O :o -tongue.png :P :p :-P :-p +shocked.png :-O :-o :O :o +tongue.png :-P :P :-p :p angry.png :@ :-@ -confused.png :S :s :-S :-s +embarrassed.png :$ :-$ +confused.png :S :s :-S :-s sad.png :( :-( crying.png :'( neutral.png :| :-| devil.png (6) angel.png (A) (a) -love.png (L) (l) +in_love.png (L) (l) musical-note.png (8) kiss.png (K) (k) camera.png (P) (p) @@ -55,12 +87,14 @@ hug-left.png ({) hug-right.png (}) beer.png (B) (b) +sarcastic.png ^o) sick.png +o( plate.png (pl) +mobile.png (mp) dont-know.png :^) thinking.png *-) party.png <:o) -yawn.png |-) +sleepy.png |-) # Hidden MSN emotes cigarette.png (ci) (CI) @@ -69,22 +103,27 @@ # Following QQ 2006 [QQ] -shock.png /:O /jy /surprised +shocked.png /:O /jy /surprised party.png /8-) /dy /revel crying.png /:< /ll /cry -sleepy.png /:Z /shui /sleep -smile-big.png /:D /cy /toothy_smile -smile.png /:) /wx /small_smile +sleeping.png /:Z /shui /sleep +embarrassed.png /:-| /gg /embarassed +excited.png /:D /cy /toothy_smile +happy.png /:) /wx /small_smile sad.png /:( /ng /sad sick.png /:T /tu /vomit -yawn.png /|-) /kun /sleepy +sleepy.png /|-) /kun /sleepy +hot.png /:L /sweat question.png /? /yiw /question +afraid.png /shake /fad /shake +amorous.png /love /aiq /love search.png /find /zhao /search hug-left.png /hug /yb /hug musical-note.png /music /yy /music coffee.png /coffee /kf /coffee +hungry.png /eat /fan /eat kiss.png /kiss /wen /kiss -love.png /heart /xin /heart +in_love.png /heart /xin /heart meeting.png /meeting /hy /meeting phone.png /phone /dh /phone tv.png /TV /ds /TV @@ -93,45 +132,54 @@ # Following ICQ 6.0 [ICQ] -smile.png :-) :) +happy.png :-) :) neutral.png :-$ sad.png :-( :( -shock.png =-O +shocked.png =-O wink.png ;-) ;) tongue.png :-P :P :-p :p -sleepy.png *TIRED* +music.png [:-} +sleeping.png *TIRED* crying.png :'( :'-( sick.png :-! kiss.png :-{} :-* +embarrassed.png :-[ devil.png ]:-> angel.png O:-) thinking.png :-\\ :-/ beer.png *DRINK* -smile-big.png :-D :D +excited.png :-D :D +amorous.png *IN\ LOVE* # Following Yahoo! Messenger 8.1 [Yahoo] -smile.png :) :-) +happy.png :) :-) question.png :-/ :-\\ -shock.png :-O :O :-o :o +shocked.png :-O :O :-o :o devil.png >:) angel.png O:-) o:-) 0:-) sick.png :-& -yawn.png (:| +sleepy.png (:| sad.png :( :-( +amorous.png :x :-x :X :-X angry.png X-( x-( X( x( crying.png :(( wink.png ;) ;-) +embarrassed.png :"> +mean.png :-> :> thinking.png :-? -smile-big.png :D :-D :d :-d +excited.png :D :-D :d :-d tongue.png :-P :P :-p :p neutral.png :| :-| -sleepy.png I-) i-) |-) +sleeping.png I-) i-) |-) kiss.png :-* :* confused.png :-S :-s +sarcastic.png /:) hug-left.png >:D< >:d< +hot.png #:-S #:-s party.png <:-P <:-p +nervous.png :-SS :-Ss :-sS :-ss # Hidden Yahoo emotes coffee.png ~o) ~O) @@ -171,30 +219,14 @@ # Following MySpaceIM Beta 1.0.697.0 [MySpaceIM] -smile-big.png :D :-D +excited.png :D :-D devil.png }:) confused.png :Z -smile.png :) :-) -shock.png :O +amorous.png :X +shocked.png :O neutral.png :| tongue.png :P :p wink.png ;-) ;) sad.png :[ kiss.png :x -[XMPP] -# XMPP emoticons -smile.png :) :-) =) -smile-big.png :D :-D =D -wink.png ;) ;-) ;^) -shock.png :-o -tongue.png :P :-P :-p :p -glasses-cool.png B-) -angry.png X-( -sad.png :( :-( =( -crying.png :'( -neutral.png :-| -thinking.png :-/ -love.png <3 -monkey.png :(|) -victory.png \\m/ diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/smile-big.png Binary file pidgin/pixmaps/emotes/small/16/smile-big.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/smile.png Binary file pidgin/pixmaps/emotes/small/16/smile.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/studying.png Binary file pidgin/pixmaps/emotes/small/16/studying.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/suit.png Binary file pidgin/pixmaps/emotes/small/16/suit.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/surfing.png Binary file pidgin/pixmaps/emotes/small/16/surfing.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/typing.png Binary file pidgin/pixmaps/emotes/small/16/typing.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/working.png Binary file pidgin/pixmaps/emotes/small/16/working.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/writing.png Binary file pidgin/pixmaps/emotes/small/16/writing.png has changed diff -r 791606778223 -r a538cb73f897 pidgin/pixmaps/emotes/small/16/yawn.png Binary file pidgin/pixmaps/emotes/small/16/yawn.png has changed diff -r 791606778223 -r a538cb73f897 po/POTFILES.in --- a/po/POTFILES.in Fri Feb 05 14:40:39 2010 +0000 +++ b/po/POTFILES.in Sun Feb 07 19:31:56 2010 +0000 @@ -146,6 +146,7 @@ libpurple/protocols/novell/novell.c libpurple/protocols/oscar/clientlogin.c libpurple/protocols/oscar/family_chatnav.c +libpurple/protocols/oscar/family_locate.c libpurple/protocols/oscar/flap_connection.c libpurple/protocols/oscar/libaim.c libpurple/protocols/oscar/libicq.c