# HG changeset patch # User Tim Ringenbach # Date 1087262236 0 # Node ID fe0291162312facd22b5247a0227dace5201d9cf # Parent 66ff39319900cf142064568ac7f1beb29b64654b [gaim-migrate @ 10087] Yahoo "picture" buddy icon support. It still kind of sucks, and you can't set your own yet. But expect it to improve. committer: Tailor Script diff -r 66ff39319900 -r fe0291162312 ChangeLog --- a/ChangeLog Mon Jun 14 16:44:32 2004 +0000 +++ b/ChangeLog Tue Jun 15 01:17:16 2004 +0000 @@ -21,6 +21,7 @@ buddy is currently in. For example, if the buddy is idle, set "Return from idle" by default. The last action(s) used are the defaults for the next pounce. + * Yahoo buddy icon support, can't set your own yet though. Bug Fixes: * Better handling of character sets in RTF for Novell (Mike Stoddard of diff -r 66ff39319900 -r fe0291162312 src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Mon Jun 14 16:44:32 2004 +0000 +++ b/src/protocols/yahoo/yahoo.c Tue Jun 15 01:17:16 2004 +0000 @@ -47,7 +47,7 @@ /* #define YAHOO_DEBUG */ static void yahoo_add_buddy(GaimConnection *gc, const char *who, GaimGroup *); - +static void yahoo_send_buddy_icon_request(GaimConnection *gc, const char *who); struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) { @@ -688,6 +688,7 @@ char *from; int time; int utf8; + int buddy_icon; char *msg; }; @@ -712,6 +713,9 @@ if (pair->key == 15) if (im) im->time = strtol(pair->value, NULL, 10); + if (pair->key == 206) + if (im) + im->buddy_icon = strtol(pair->value, NULL, 10); if (pair->key == 14) { if (im) im->msg = pair->value; @@ -726,6 +730,7 @@ for (l = list; l; l = l->next) { char *m, *m2; im = l->data; + YahooFriend *f; if (!im->from || !im->msg) { g_free(im); @@ -749,6 +754,14 @@ g_free(m); serv_got_im(gc, im->from, m2, 0, im->time); g_free(m2); + + if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { + if (yahoo_friend_get_buddy_icon_need_request(f)) { + yahoo_send_buddy_icon_request(gc, im->from); + yahoo_friend_set_buddy_icon_need_request(f, FALSE); + } + } + g_free(im); } g_slist_free(list); @@ -1844,6 +1857,78 @@ } } +struct yahoo_fetch_picture_data { + GaimConnection *gc; + char *who; + int checksum; +}; + +void yahoo_fetch_picture_cb(void *user_data, const char *pic_data, size_t len) +{ + struct yahoo_fetch_picture_data *d = user_data; + + if (GAIM_CONNECTION_IS_VALID(d->gc) && len) { + gaim_buddy_icons_set_for_user(gaim_connection_get_account(d->gc), d->who, pic_data, len); + } + + g_free(d->who); + g_free(d); +} + +static void yahoo_process_picture(GaimConnection *gc, struct yahoo_packet *pkt) +{ + GSList *l = pkt->hash; + char *who = NULL, *us = NULL; + gboolean got_icon_info = FALSE; + char *url = NULL; + int checksum = 0; /* ?? */ + + while (l) { + struct yahoo_pair *pair = l->data; + + switch (pair->key) { + case 1: + case 4: + who = pair->value; + break; + case 5: + us = pair->value; + break; + case 13: { + int tmp; + tmp = strtol(pair->value, NULL, 10); + if (tmp == 1) { + /* send them info about our buddy icon */ + } else if (tmp == 2) { + got_icon_info = TRUE; + } + break; + } + case 20: + url = pair->value; + break; + case 192: + checksum = strtol(pair->value, NULL, 10); /* just a guess for now */ + break; + } + + l = l->next; + } + + if (got_icon_info && url) { + /* TODO: make this work p2p, try p2p before the url, check the checksum + * (if that's what it is) before fetching the icon. + */ + struct yahoo_fetch_picture_data *data = g_new0(struct yahoo_fetch_picture_data, 1); + data->gc = gc; + data->who = g_strdup(who); + data->checksum = checksum; + gaim_url_fetch(url, FALSE, "Mozilla/4.0 (compatible; MSIE 5.0)", FALSE, + yahoo_fetch_picture_cb, data); + } + +} + static void yahoo_packet_process(GaimConnection *gc, struct yahoo_packet *pkt) { switch (pkt->service) { @@ -1935,6 +2020,9 @@ case YAHOO_SERVICE_PEEPTOPEER: yahoo_process_p2p(gc, pkt); break; + case YAHOO_SERVICE_PICTURE: + yahoo_process_picture(gc, pkt); + break; default: gaim_debug(GAIM_DEBUG_ERROR, "yahoo", "Unhandled service 0x%02x\n", pkt->service); @@ -3078,6 +3166,19 @@ g_free(gpo); } +static void yahoo_send_buddy_icon_request(GaimConnection *gc, const char *who) +{ + struct yahoo_data *yd = gc->proto_data; + struct yahoo_packet *pkt; + + pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash(pkt, 4, gaim_connection_get_display_name(gc)); /* me */ + yahoo_packet_hash(pkt, 5, who); /* the other guy */ + yahoo_packet_hash(pkt, 13, "1"); /* 1 = request, 2 = reply */ + yahoo_send_packet(yd, pkt); + yahoo_packet_free(pkt); +} + #if 0 static gboolean yahoo_has_send_file(GaimConnection *gc, const char *who) { diff -r 66ff39319900 -r fe0291162312 src/protocols/yahoo/yahoo_friend.c --- a/src/protocols/yahoo/yahoo_friend.c Mon Jun 14 16:44:32 2004 +0000 +++ b/src/protocols/yahoo/yahoo_friend.c Tue Jun 15 01:17:16 2004 +0000 @@ -112,6 +112,16 @@ return f->msg; } +void yahoo_friend_set_buddy_icon_need_request(YahooFriend *f, gboolean needs) +{ + f->bicon_sent_request = !needs; +} + +gboolean yahoo_friend_get_buddy_icon_need_request(YahooFriend *f) +{ + return !f->bicon_sent_request; +} + void yahoo_friend_free(gpointer p) { YahooFriend *f = p; diff -r 66ff39319900 -r fe0291162312 src/protocols/yahoo/yahoo_friend.h --- a/src/protocols/yahoo/yahoo_friend.h Mon Jun 14 16:44:32 2004 +0000 +++ b/src/protocols/yahoo/yahoo_friend.h Tue Jun 15 01:17:16 2004 +0000 @@ -39,7 +39,7 @@ gboolean sms; char *ip; guint bicon_checksum; - gboolean bicon_have; + gboolean bicon_sent_request; } YahooFriend; @@ -55,6 +55,9 @@ void yahoo_friend_set_status_message(YahooFriend *f, char *msg); const char *yahoo_friend_get_status_message(YahooFriend *f); +void yahoo_friend_set_buddy_icon_need_request(YahooFriend *f, gboolean needs); +gboolean yahoo_friend_get_buddy_icon_need_request(YahooFriend *f); + void yahoo_friend_free(gpointer p); #endif /* _YAHOO_FRIEND_H_ */ diff -r 66ff39319900 -r fe0291162312 src/util.h --- a/src/util.h Mon Jun 14 16:44:32 2004 +0000 +++ b/src/util.h Tue Jun 15 01:17:16 2004 +0000 @@ -610,10 +610,10 @@ * @param url The URL. * @param full TRUE if this is the full URL, or FALSE if it's a * partial URL. + * @param user_agent The user agent field to use, or NULL. + * @param http11 TRUE if HTTP/1.1 should be used to download the file. * @param cb The callback function. * @param data The user data to pass to the callback function. - * @param user_agent The user agent field to use, or NULL. - * @param http11 TRUE if HTTP/1.1 should be used to download the file. */ void gaim_url_fetch(const char *url, gboolean full, const char *user_agent, gboolean http11,