changeset 14265:584cbd1628d0

[gaim-migrate @ 16947] Added support for QQ faces. Thanks to csyfek@gmail.com for the images and protocol update. committer: Tailor Script <tailor@pidgin.im>
author Mark Huetsch <markhuetsch>
date Mon, 21 Aug 2006 07:17:40 +0000
parents d171bdecf17b
children 63ef6342db05
files gtk/pixmaps/status/default/Makefile.am gtk/pixmaps/status/default/qq_1.png gtk/pixmaps/status/default/qq_10.png gtk/pixmaps/status/default/qq_100.png gtk/pixmaps/status/default/qq_11.png gtk/pixmaps/status/default/qq_12.png gtk/pixmaps/status/default/qq_13.png gtk/pixmaps/status/default/qq_14.png gtk/pixmaps/status/default/qq_15.png gtk/pixmaps/status/default/qq_16.png gtk/pixmaps/status/default/qq_17.png gtk/pixmaps/status/default/qq_18.png gtk/pixmaps/status/default/qq_19.png gtk/pixmaps/status/default/qq_2.png gtk/pixmaps/status/default/qq_20.png gtk/pixmaps/status/default/qq_21.png gtk/pixmaps/status/default/qq_22.png gtk/pixmaps/status/default/qq_23.png gtk/pixmaps/status/default/qq_24.png gtk/pixmaps/status/default/qq_25.png gtk/pixmaps/status/default/qq_26.png gtk/pixmaps/status/default/qq_27.png gtk/pixmaps/status/default/qq_28.png gtk/pixmaps/status/default/qq_29.png gtk/pixmaps/status/default/qq_3.png gtk/pixmaps/status/default/qq_30.png gtk/pixmaps/status/default/qq_31.png gtk/pixmaps/status/default/qq_32.png gtk/pixmaps/status/default/qq_33.png gtk/pixmaps/status/default/qq_34.png gtk/pixmaps/status/default/qq_35.png gtk/pixmaps/status/default/qq_36.png gtk/pixmaps/status/default/qq_37.png gtk/pixmaps/status/default/qq_38.png gtk/pixmaps/status/default/qq_39.png gtk/pixmaps/status/default/qq_4.png gtk/pixmaps/status/default/qq_40.png gtk/pixmaps/status/default/qq_41.png gtk/pixmaps/status/default/qq_42.png gtk/pixmaps/status/default/qq_43.png gtk/pixmaps/status/default/qq_44.png gtk/pixmaps/status/default/qq_45.png gtk/pixmaps/status/default/qq_46.png gtk/pixmaps/status/default/qq_47.png gtk/pixmaps/status/default/qq_48.png gtk/pixmaps/status/default/qq_49.png gtk/pixmaps/status/default/qq_5.png gtk/pixmaps/status/default/qq_50.png gtk/pixmaps/status/default/qq_51.png gtk/pixmaps/status/default/qq_52.png gtk/pixmaps/status/default/qq_53.png gtk/pixmaps/status/default/qq_54.png gtk/pixmaps/status/default/qq_55.png gtk/pixmaps/status/default/qq_56.png gtk/pixmaps/status/default/qq_57.png gtk/pixmaps/status/default/qq_58.png gtk/pixmaps/status/default/qq_59.png gtk/pixmaps/status/default/qq_6.png gtk/pixmaps/status/default/qq_60.png gtk/pixmaps/status/default/qq_61.png gtk/pixmaps/status/default/qq_62.png gtk/pixmaps/status/default/qq_63.png gtk/pixmaps/status/default/qq_64.png gtk/pixmaps/status/default/qq_65.png gtk/pixmaps/status/default/qq_66.png gtk/pixmaps/status/default/qq_67.png gtk/pixmaps/status/default/qq_68.png gtk/pixmaps/status/default/qq_69.png gtk/pixmaps/status/default/qq_7.png gtk/pixmaps/status/default/qq_70.png gtk/pixmaps/status/default/qq_71.png gtk/pixmaps/status/default/qq_72.png gtk/pixmaps/status/default/qq_73.png gtk/pixmaps/status/default/qq_74.png gtk/pixmaps/status/default/qq_75.png gtk/pixmaps/status/default/qq_76.png gtk/pixmaps/status/default/qq_77.png gtk/pixmaps/status/default/qq_78.png gtk/pixmaps/status/default/qq_79.png gtk/pixmaps/status/default/qq_8.png gtk/pixmaps/status/default/qq_80.png gtk/pixmaps/status/default/qq_81.png gtk/pixmaps/status/default/qq_82.png gtk/pixmaps/status/default/qq_83.png gtk/pixmaps/status/default/qq_84.png gtk/pixmaps/status/default/qq_85.png gtk/pixmaps/status/default/qq_86.png gtk/pixmaps/status/default/qq_87.png gtk/pixmaps/status/default/qq_88.png gtk/pixmaps/status/default/qq_89.png gtk/pixmaps/status/default/qq_9.png gtk/pixmaps/status/default/qq_90.png gtk/pixmaps/status/default/qq_91.png gtk/pixmaps/status/default/qq_92.png gtk/pixmaps/status/default/qq_93.png gtk/pixmaps/status/default/qq_94.png gtk/pixmaps/status/default/qq_95.png gtk/pixmaps/status/default/qq_96.png gtk/pixmaps/status/default/qq_97.png gtk/pixmaps/status/default/qq_98.png gtk/pixmaps/status/default/qq_99.png libgaim/protocols/qq/buddy_info.c libgaim/protocols/qq/buddy_list.c libgaim/protocols/qq/buddy_status.c libgaim/protocols/qq/buddy_status.h libgaim/protocols/qq/group_info.c libgaim/protocols/qq/im.c libgaim/protocols/qq/login_logout.c libgaim/protocols/qq/qq.c libgaim/protocols/qq/qq.h libgaim/protocols/qq/utils.c libgaim/protocols/qq/utils.h
diffstat 112 files changed, 231 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/gtk/pixmaps/status/default/Makefile.am	Mon Aug 21 06:06:54 2006 +0000
+++ b/gtk/pixmaps/status/default/Makefile.am	Mon Aug 21 07:17:40 2006 +0000
@@ -42,6 +42,108 @@
 	yahoo.png \
 	zephyr.png
 
+QQ_FACES = \
+	qq_1.png \
+	qq_2.png \
+	qq_3.png \
+	qq_4.png \
+	qq_5.png \
+	qq_6.png \
+	qq_7.png \
+	qq_8.png \
+	qq_9.png \
+	qq_10.png \
+	qq_11.png \
+	qq_12.png \
+	qq_13.png \
+	qq_14.png \
+	qq_15.png \
+	qq_16.png \
+	qq_17.png \
+	qq_18.png \
+	qq_19.png \
+	qq_20.png \
+	qq_21.png \
+	qq_22.png \
+	qq_23.png \
+	qq_24.png \
+	qq_25.png \
+	qq_26.png \
+	qq_27.png \
+	qq_28.png \
+	qq_29.png \
+	qq_30.png \
+	qq_31.png \
+	qq_32.png \
+	qq_33.png \
+	qq_34.png \
+	qq_35.png \
+	qq_36.png \
+	qq_37.png \
+	qq_38.png \
+	qq_39.png \
+	qq_40.png \
+	qq_41.png \
+	qq_42.png \
+	qq_43.png \
+	qq_44.png \
+	qq_45.png \
+	qq_46.png \
+	qq_47.png \
+	qq_48.png \
+	qq_49.png \
+	qq_50.png \
+	qq_51.png \
+	qq_52.png \
+	qq_53.png \
+	qq_54.png \
+	qq_55.png \
+	qq_56.png \
+	qq_57.png \
+	qq_58.png \
+	qq_59.png \
+	qq_60.png \
+	qq_61.png \
+	qq_62.png \
+	qq_63.png \
+	qq_64.png \
+	qq_65.png \
+	qq_66.png \
+	qq_67.png \
+	qq_68.png \
+	qq_69.png \
+	qq_70.png \
+	qq_71.png \
+	qq_72.png \
+	qq_73.png \
+	qq_74.png \
+	qq_75.png \
+	qq_76.png \
+	qq_77.png \
+	qq_78.png \
+	qq_79.png \
+	qq_80.png \
+	qq_81.png \
+	qq_82.png \
+	qq_83.png \
+	qq_84.png \
+	qq_85.png \
+	qq_86.png \
+	qq_87.png \
+	qq_88.png \
+	qq_89.png \
+	qq_90.png \
+	qq_91.png \
+	qq_92.png \
+	qq_93.png \
+	qq_94.png \
+	qq_95.png \
+	qq_96.png \
+	qq_97.png \
+	qq_98.png \
+	qq_99.png \
+	qq_100.png
+
 gaimstatuspixdir = $(datadir)/pixmaps/gaim/status/default
 
-gaimstatuspix_DATA = $(EXTRA_DIST)
+gaimstatuspix_DATA = $(EXTRA_DIST) $(QQ_FACES)
Binary file gtk/pixmaps/status/default/qq_1.png has changed
Binary file gtk/pixmaps/status/default/qq_10.png has changed
Binary file gtk/pixmaps/status/default/qq_100.png has changed
Binary file gtk/pixmaps/status/default/qq_11.png has changed
Binary file gtk/pixmaps/status/default/qq_12.png has changed
Binary file gtk/pixmaps/status/default/qq_13.png has changed
Binary file gtk/pixmaps/status/default/qq_14.png has changed
Binary file gtk/pixmaps/status/default/qq_15.png has changed
Binary file gtk/pixmaps/status/default/qq_16.png has changed
Binary file gtk/pixmaps/status/default/qq_17.png has changed
Binary file gtk/pixmaps/status/default/qq_18.png has changed
Binary file gtk/pixmaps/status/default/qq_19.png has changed
Binary file gtk/pixmaps/status/default/qq_2.png has changed
Binary file gtk/pixmaps/status/default/qq_20.png has changed
Binary file gtk/pixmaps/status/default/qq_21.png has changed
Binary file gtk/pixmaps/status/default/qq_22.png has changed
Binary file gtk/pixmaps/status/default/qq_23.png has changed
Binary file gtk/pixmaps/status/default/qq_24.png has changed
Binary file gtk/pixmaps/status/default/qq_25.png has changed
Binary file gtk/pixmaps/status/default/qq_26.png has changed
Binary file gtk/pixmaps/status/default/qq_27.png has changed
Binary file gtk/pixmaps/status/default/qq_28.png has changed
Binary file gtk/pixmaps/status/default/qq_29.png has changed
Binary file gtk/pixmaps/status/default/qq_3.png has changed
Binary file gtk/pixmaps/status/default/qq_30.png has changed
Binary file gtk/pixmaps/status/default/qq_31.png has changed
Binary file gtk/pixmaps/status/default/qq_32.png has changed
Binary file gtk/pixmaps/status/default/qq_33.png has changed
Binary file gtk/pixmaps/status/default/qq_34.png has changed
Binary file gtk/pixmaps/status/default/qq_35.png has changed
Binary file gtk/pixmaps/status/default/qq_36.png has changed
Binary file gtk/pixmaps/status/default/qq_37.png has changed
Binary file gtk/pixmaps/status/default/qq_38.png has changed
Binary file gtk/pixmaps/status/default/qq_39.png has changed
Binary file gtk/pixmaps/status/default/qq_4.png has changed
Binary file gtk/pixmaps/status/default/qq_40.png has changed
Binary file gtk/pixmaps/status/default/qq_41.png has changed
Binary file gtk/pixmaps/status/default/qq_42.png has changed
Binary file gtk/pixmaps/status/default/qq_43.png has changed
Binary file gtk/pixmaps/status/default/qq_44.png has changed
Binary file gtk/pixmaps/status/default/qq_45.png has changed
Binary file gtk/pixmaps/status/default/qq_46.png has changed
Binary file gtk/pixmaps/status/default/qq_47.png has changed
Binary file gtk/pixmaps/status/default/qq_48.png has changed
Binary file gtk/pixmaps/status/default/qq_49.png has changed
Binary file gtk/pixmaps/status/default/qq_5.png has changed
Binary file gtk/pixmaps/status/default/qq_50.png has changed
Binary file gtk/pixmaps/status/default/qq_51.png has changed
Binary file gtk/pixmaps/status/default/qq_52.png has changed
Binary file gtk/pixmaps/status/default/qq_53.png has changed
Binary file gtk/pixmaps/status/default/qq_54.png has changed
Binary file gtk/pixmaps/status/default/qq_55.png has changed
Binary file gtk/pixmaps/status/default/qq_56.png has changed
Binary file gtk/pixmaps/status/default/qq_57.png has changed
Binary file gtk/pixmaps/status/default/qq_58.png has changed
Binary file gtk/pixmaps/status/default/qq_59.png has changed
Binary file gtk/pixmaps/status/default/qq_6.png has changed
Binary file gtk/pixmaps/status/default/qq_60.png has changed
Binary file gtk/pixmaps/status/default/qq_61.png has changed
Binary file gtk/pixmaps/status/default/qq_62.png has changed
Binary file gtk/pixmaps/status/default/qq_63.png has changed
Binary file gtk/pixmaps/status/default/qq_64.png has changed
Binary file gtk/pixmaps/status/default/qq_65.png has changed
Binary file gtk/pixmaps/status/default/qq_66.png has changed
Binary file gtk/pixmaps/status/default/qq_67.png has changed
Binary file gtk/pixmaps/status/default/qq_68.png has changed
Binary file gtk/pixmaps/status/default/qq_69.png has changed
Binary file gtk/pixmaps/status/default/qq_7.png has changed
Binary file gtk/pixmaps/status/default/qq_70.png has changed
Binary file gtk/pixmaps/status/default/qq_71.png has changed
Binary file gtk/pixmaps/status/default/qq_72.png has changed
Binary file gtk/pixmaps/status/default/qq_73.png has changed
Binary file gtk/pixmaps/status/default/qq_74.png has changed
Binary file gtk/pixmaps/status/default/qq_75.png has changed
Binary file gtk/pixmaps/status/default/qq_76.png has changed
Binary file gtk/pixmaps/status/default/qq_77.png has changed
Binary file gtk/pixmaps/status/default/qq_78.png has changed
Binary file gtk/pixmaps/status/default/qq_79.png has changed
Binary file gtk/pixmaps/status/default/qq_8.png has changed
Binary file gtk/pixmaps/status/default/qq_80.png has changed
Binary file gtk/pixmaps/status/default/qq_81.png has changed
Binary file gtk/pixmaps/status/default/qq_82.png has changed
Binary file gtk/pixmaps/status/default/qq_83.png has changed
Binary file gtk/pixmaps/status/default/qq_84.png has changed
Binary file gtk/pixmaps/status/default/qq_85.png has changed
Binary file gtk/pixmaps/status/default/qq_86.png has changed
Binary file gtk/pixmaps/status/default/qq_87.png has changed
Binary file gtk/pixmaps/status/default/qq_88.png has changed
Binary file gtk/pixmaps/status/default/qq_89.png has changed
Binary file gtk/pixmaps/status/default/qq_9.png has changed
Binary file gtk/pixmaps/status/default/qq_90.png has changed
Binary file gtk/pixmaps/status/default/qq_91.png has changed
Binary file gtk/pixmaps/status/default/qq_92.png has changed
Binary file gtk/pixmaps/status/default/qq_93.png has changed
Binary file gtk/pixmaps/status/default/qq_94.png has changed
Binary file gtk/pixmaps/status/default/qq_95.png has changed
Binary file gtk/pixmaps/status/default/qq_96.png has changed
Binary file gtk/pixmaps/status/default/qq_97.png has changed
Binary file gtk/pixmaps/status/default/qq_98.png has changed
Binary file gtk/pixmaps/status/default/qq_99.png has changed
--- a/libgaim/protocols/qq/buddy_info.c	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/buddy_info.c	Mon Aug 21 07:17:40 2006 +0000
@@ -282,7 +282,7 @@
 /************************ packets and UI management **************************/
 
 /* send a packet to get detailed information of uid */
-void qq_send_packet_get_info(GaimConnection * gc, guint32 uid, gboolean show_window)
+void qq_send_packet_get_info(GaimConnection *gc, guint32 uid, gboolean show_window)
 {
 	qq_data *qd;
 	gchar *uid_str;
@@ -597,6 +597,14 @@
 			return;
 
 		info = (contact_info *) segments;
+		if (qd->modifying_face && strtol(info->face, NULL, 10) != qd->my_icon) {
+			gchar *icon = g_strdup_printf("%i", qd->my_icon);
+			qd->modifying_face = FALSE;
+			memcpy(info->face, icon, 2);
+			qq_send_packet_modify_info(gc, info);
+			g_free(icon);
+		}
+
 		qq_refresh_buddy_and_myself(info, gc);
 
 		query_list = qd->info_query;
--- a/libgaim/protocols/qq/buddy_list.c	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/buddy_list.c	Mon Aug 21 07:17:40 2006 +0000
@@ -255,7 +255,7 @@
 	qq_buddy *q_bud;
 	gint len, bytes, bytes_expected, i;
 	guint16 position, unknown;
-	guint8 *data, *cursor, bar, pascal_len;
+	guint8 *data, *cursor, pascal_len;
 	gchar *name;
 	GaimBuddy *b;
 
@@ -276,10 +276,8 @@
 			bytes = 0;
 			/* 000-003: uid */
 			bytes += read_packet_dw(data, &cursor, len, &q_bud->uid);
-			/* 004-004: 0xff if buddy is self, 0x00 otherwise */
-			bytes += read_packet_b(data, &cursor, len, &bar);
-			/* 005-005: icon index (1-255) */
-			bytes += read_packet_b(data, &cursor, len, &q_bud->icon);
+			/* 004-005: icon index (1-255) */
+			bytes += read_packet_w(data, &cursor, len, &q_bud->icon);
 			/* 006-006: age */
 			bytes += read_packet_b(data, &cursor, len, &q_bud->age);
 			/* 007-007: gender */
--- a/libgaim/protocols/qq/buddy_status.c	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/buddy_status.c	Mon Aug 21 07:17:40 2006 +0000
@@ -120,20 +120,22 @@
 	return FALSE;
 }
 
-/* the icon suffix is detemined by status
- * although QQ server may return the right icon, I set it here myself */
-gchar get_suffix_from_status(guint8 status)
+/* The QQ client seems to use a separate icon for each
+ * face/status combo, but we only use one and let Gaim
+ * handle the rest. We need to use this function to report 
+ * the correct icon file back to the server. */
+gint get_icon_offset_from_self_status(guint8 status)
 {
 	switch (status) {
-	case QQ_BUDDY_ONLINE_NORMAL:
-		return QQ_ICON_SUFFIX_NORMAL;
-	case QQ_BUDDY_ONLINE_AWAY:
-		return QQ_ICON_SUFFIX_AWAY;
-	case QQ_BUDDY_ONLINE_INVISIBLE:
-	case QQ_BUDDY_ONLINE_OFFLINE:
-		return QQ_ICON_SUFFIX_OFFLINE;
+	case QQ_SELF_STATUS_AVAILABLE:
+		return 0;
+	case QQ_SELF_STATUS_AWAY:
+	case QQ_SELF_STATUS_CUSTOM:
+		return 1;
+	case QQ_SELF_STATUS_INVISIBLE:
+		return 2;
 	default:
-		return QQ_ICON_SUFFIX_DEFAULT;
+		return 2;
 	}
 }
 
--- a/libgaim/protocols/qq/buddy_status.h	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/buddy_status.h	Mon Aug 21 07:17:40 2006 +0000
@@ -59,7 +59,7 @@
 gboolean is_online(guint8 status);
 
 gint qq_buddy_status_read(guint8 *data, guint8 **cursor, gint len, qq_buddy_status *s);
-gchar get_suffix_from_status(guint8 status);
+gint get_icon_offset_from_self_status(guint8 status);
 
 void qq_send_packet_change_status(GaimConnection *gc);
 
--- a/libgaim/protocols/qq/group_info.c	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/group_info.c	Mon Aug 21 07:17:40 2006 +0000
@@ -283,7 +283,6 @@
 {
 	guint32 internal_group_id, member_uid;
 	guint16 unknown;
-	guint8 bar;
 	gint pascal_len, i;
 	qq_group *group;
 	qq_buddy *member;
@@ -305,8 +304,7 @@
 		g_return_if_fail(member != NULL);
 
 		i++;
-		read_packet_b(data, cursor, len, &bar);
-		read_packet_b(data, cursor, len, &(member->icon));
+		read_packet_w(data, cursor, len, &(member->icon));
 		read_packet_b(data, cursor, len, &(member->age));
 		read_packet_b(data, cursor, len, &(member->gender));
 		pascal_len = convert_as_pascal_string(*cursor, &(member->nickname), QQ_CHARSET_DEFAULT);
--- a/libgaim/protocols/qq/im.c	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/im.c	Mon Aug 21 07:17:40 2006 +0000
@@ -87,8 +87,7 @@
 	/* now comes the part for text only */
 	guint16 msg_seq;
 	guint32 send_time;
-	guint8 unknown1;
-	guint8 sender_icon;
+	guint16 sender_icon;
 	guint8 unknown2[3];
 	guint8 is_there_font_attr;
 	guint8 unknown3[4];
@@ -268,8 +267,7 @@
 	/* push data into im_text */
 	read_packet_w(data, cursor, len, &(im_text->msg_seq));
 	read_packet_dw(data, cursor, len, &(im_text->send_time));
-	read_packet_b(data, cursor, len, &(im_text->unknown1));
-	read_packet_b(data, cursor, len, &(im_text->sender_icon));
+	read_packet_w(data, cursor, len, &(im_text->sender_icon));
 	read_packet_data(data, cursor, len, (guint8 *) & (im_text->unknown2), 3);
 	read_packet_b(data, cursor, len, &(im_text->is_there_font_attr));
 	/**
@@ -515,10 +513,8 @@
 	bytes += create_packet_w(raw_data, &cursor, qd->send_seq);
 	/* 038-041: send time */
 	bytes += create_packet_dw(raw_data, &cursor, (guint32) now);
-	/* 042-042: always 0x00 */
-	bytes += create_packet_b(raw_data, &cursor, 0x00);
-	/* 043-043: sender icon */
-	bytes += create_packet_b(raw_data, &cursor, qd->my_icon);
+	/* 042-043: sender icon */
+	bytes += create_packet_w(raw_data, &cursor, qd->my_icon);
 	/* 044-046: always 0x00 */
 	bytes += create_packet_w(raw_data, &cursor, 0x0000);
 	bytes += create_packet_b(raw_data, &cursor, 0x00);
--- a/libgaim/protocols/qq/login_logout.c	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/login_logout.c	Mon Aug 21 07:17:40 2006 +0000
@@ -229,6 +229,7 @@
 	qq_group_init(gc);
 
 	/* Now goes on updating my icon/nickname, not showing info_window */
+	qd->modifying_face = FALSE;
 	qq_send_packet_get_info(gc, qd->uid, FALSE);
 	/* change my status manually, even server may broadcast my online */
 	qd->status = (qd->login_mode == QQ_LOGIN_MODE_HIDDEN) ? QQ_SELF_STATUS_INVISIBLE : QQ_SELF_STATUS_AVAILABLE;
--- a/libgaim/protocols/qq/qq.c	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/qq.c	Mon Aug 21 07:17:40 2006 +0000
@@ -147,27 +147,17 @@
 /* returns the icon name for a buddy or protocol */
 static const gchar *_qq_list_icon(GaimAccount *a, GaimBuddy *b)
 {
-	/* XXX temp commented out until we figure out what to do with
-	 * status icons */
-	/*
 	gchar *filename;
 	qq_buddy *q_bud;
-	gchar icon_suffix;
-	*/
 
 	/* do not use g_return_val_if_fail, as it is not assertion */
 	if (b == NULL || b->proto_data == NULL)
 		return "qq";
 
-	/*
 	q_bud = (qq_buddy *) b->proto_data;
-
-	icon_suffix = get_suffix_from_status(q_bud->status);
-	filename = get_icon_name(q_bud->icon / 3 + 1, icon_suffix);
+	filename = get_icon_name(q_bud->icon / 3 + 1);
 
 	return filename;
-	*/
-	return "qq";
 }
 
 
@@ -282,17 +272,20 @@
 
 	qq_buddy *q_bud = b->proto_data;
         const char *emblems[4] = { NULL, NULL, NULL, NULL };
-        int i = 0;
+        int i = 1;
 
         if (q_bud == NULL) {
                 emblems[0] = "offline";
 	} else {
+		/* TODO the wireless icon is a bit too big to look good with QQ faces */
+		if (q_bud->status == QQ_BUDDY_ONLINE_AWAY || q_bud->status == QQ_SELF_STATUS_AWAY)
+			emblems[i++] = "away";
 		if (q_bud->comm_flag & QQ_COMM_FLAG_QQ_MEMBER)
 			emblems[i++] = "qq_member";
                 if (q_bud->comm_flag & QQ_COMM_FLAG_BIND_MOBILE)
                         emblems[i++] = "wireless";
 		if (q_bud->comm_flag & QQ_COMM_FLAG_VIDEO)
-			emblems[i++] = "video";
+			emblems[i%4] = "video";
 
         }
 
@@ -437,6 +430,85 @@
 	qq_prepare_modify_info(gc);
 }
 
+static void _qq_change_face_cb(GaimConnection *gc, GaimRequestFields *fields)
+{
+	qq_data *qd;
+	GaimRequestField *field;
+	gint suffix;
+	
+	g_return_if_fail(gc != NULL && gc->proto_data != NULL);
+	qd = (qq_data *) gc->proto_data;
+
+	field = gaim_request_fields_get_field(fields, "face_num");
+	suffix = get_icon_offset_from_self_status(qd->status);
+	qd->my_icon = gaim_request_field_choice_get_value(field) * 3 + suffix;
+	qd->modifying_face = TRUE;
+	qq_send_packet_get_info(gc, qd->uid, FALSE);
+}
+
+static void _qq_add_face_choice(GaimRequestFieldGroup *group, gint face_num)
+{
+	GaimRequestField *field;
+	struct stat img_stat;
+	FILE *file;
+	gchar *filename, *prefix, *img_data, *face;
+	gint size;
+
+	face = g_strdup_printf("qq_%i.png", face_num);
+	prefix = br_extract_prefix(DATADIR);
+	filename = g_build_filename(prefix, "share","pixmaps",
+			"gaim","status","default", face, NULL);
+	g_free(face);
+	face = g_strdup_printf("%i", face_num);
+	stat(filename, &img_stat);
+	file = g_fopen(filename, "rb");
+	if (file) {
+		img_data = g_malloc(img_stat.st_size);
+		size = fread(img_data, 1, img_stat.st_size, file);
+
+		field = gaim_request_field_image_new(face, face, img_data, size);
+		gaim_request_field_group_add_field(group, field);
+
+		g_free(img_data);
+		fclose(file);
+	}
+	g_free(face);
+	g_free(prefix);
+}
+
+static void _qq_menu_change_face(GaimPluginAction *action)
+{
+	GaimConnection *gc = (GaimConnection *) action->context;
+	qq_data *qd = (qq_data *) gc->proto_data;
+	GaimRequestFields *fields;
+	GaimRequestFieldGroup *group;
+	GaimRequestField *field;
+	gchar *label;
+	gint i;
+
+	fields = gaim_request_fields_new();
+	group = gaim_request_field_group_new(_("Selection"));
+	gaim_request_fields_add_group(fields, group);
+	field = gaim_request_field_choice_new("face_num",
+		       	_("Select a number"), qd->my_icon / 3);
+	for(i = 1; i <= QQ_FACES; i++) {
+		label = g_strdup_printf("%i", i);
+		gaim_request_field_choice_add(field, label);
+		g_free(label);
+	}
+	gaim_request_field_group_add_field(group, field);
+	group = gaim_request_field_group_new(_("Faces"));
+	gaim_request_fields_add_group(fields, group);
+	for(i = 1; i <= QQ_FACES; i++)
+		_qq_add_face_choice(group, i);
+
+	gaim_request_fields(gc, _("Change Your QQ Face"),
+			_("Change Face"), NULL, fields,
+			_("Update"), G_CALLBACK(_qq_change_face_cb),
+			_("Cancel"), NULL,
+			gc);
+}
+
 static void _qq_menu_change_password(GaimPluginAction *action)
 {
 	gaim_notify_uri(NULL, "https://password.qq.com");
@@ -795,6 +867,9 @@
 	act = gaim_plugin_action_new(_("Modify My Information"), _qq_menu_modify_my_info);
 	m = g_list_append(m, act);
 
+	act = gaim_plugin_action_new(_("Change My Face"), _qq_menu_change_face);
+	m = g_list_append(m, act);
+
 	act = gaim_plugin_action_new(_("Change Password"), _qq_menu_change_password);
 	m = g_list_append(m, act);
 
--- a/libgaim/protocols/qq/qq.h	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/qq.h	Mon Aug 21 07:17:40 2006 +0000
@@ -29,6 +29,7 @@
 #include "proxy.h"
 #include "roomlist.h"
 
+#define QQ_FACES	    100
 #define QQ_KEY_LENGTH       16
 #define QQ_DEBUG            1	/* whether we are doing DEBUG */
 
@@ -37,7 +38,7 @@
 
 struct _qq_buddy {
 	guint32 uid;
-	guint8 icon;		/* index: 01 - 85 */
+	guint16 icon;		/* index: 01 - 85 */
 	guint8 age;
 	guint8 gender;
 	gchar *nickname;
@@ -83,7 +84,7 @@
 	/* get from keep_alive packet */
 	gchar *my_ip;			/* my ip address detected by server */
 	guint16 my_port;		/* my port detected by server */
-	guint8 my_icon;			/* my icon index */
+	guint16 my_icon;			/* my icon index */
 	guint32 all_online;		/* the number of online QQ users */
 	time_t last_get_online;		/* last time send get_friends_online packet */
 
@@ -103,7 +104,9 @@
 	GList *add_buddy_request;
 	GQueue *before_login_packets;
 
+	/* TODO is there a better way of handling these? */
 	gboolean modifying_info;
+	gboolean modifying_face;
 };
 
 void qq_function_not_implemented(GaimConnection *gc);
--- a/libgaim/protocols/qq/utils.c	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/utils.c	Mon Aug 21 07:17:40 2006 +0000
@@ -159,9 +159,9 @@
 
 /* return the QQ icon file name
  * the return needs to be freed */
-gchar *get_icon_name(gint set, gint suffix)
+gchar *get_icon_name(gint set)
 {
-	return g_strdup_printf("qq_%d-%d", set, suffix);
+	return g_strdup_printf("qq_%d", set);
 }
 
 /* convert a QQ UID to a unique name of GAIM
--- a/libgaim/protocols/qq/utils.h	Mon Aug 21 06:06:54 2006 +0000
+++ b/libgaim/protocols/qq/utils.h	Mon Aug 21 07:17:40 2006 +0000
@@ -40,7 +40,7 @@
 
 guint32 gaim_name_to_uid(const gchar *name);
 
-gchar *get_icon_name(gint set, gint suffix);
+gchar *get_icon_name(gint set);
 
 void try_dump_as_gbk(const guint8 *const data, gint len);