changeset 15463:0b6f337a46d5

Emblems in the blist
author Sean Egan <seanegan@gmail.com>
date Tue, 30 Jan 2007 06:53:23 +0000
parents e9c12873fae0
children bb3bf2f88406 fdba26a13731
files libpurple/protocols/bonjour/bonjour.c libpurple/protocols/gg/gg.c libpurple/protocols/irc/irc.c libpurple/protocols/jabber/jabber.c libpurple/protocols/msn/msn.c libpurple/protocols/novell/novell.c libpurple/protocols/oscar/libaim.c libpurple/protocols/oscar/libicq.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscarcommon.h libpurple/protocols/qq/qq.c libpurple/protocols/sametime/sametime.c libpurple/protocols/silc/silc.c libpurple/protocols/toc/toc.c libpurple/protocols/yahoo/yahoo.c libpurple/prpl.h pidgin/gtkblist.c pidgin/gtkblist.h
diffstat 18 files changed, 146 insertions(+), 351 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/bonjour/bonjour.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/bonjour/bonjour.c	Tue Jan 30 06:53:23 2007 +0000
@@ -289,19 +289,6 @@
 	bonjour_jabber_close_conversation(((BonjourData*)(connection->proto_data))->jabber_data, buddy);
 }
 
-static void
-bonjour_list_emblems(GaimBuddy *buddy,
-								 const char **se, const char **sw,
-								 const char **nw, const char **ne)
-{
-	GaimPresence *presence;
-
-	presence = gaim_buddy_get_presence(buddy);
-
-	if (gaim_presence_is_online(presence) && !gaim_presence_is_available(presence))
-		*se = "away";
-}
-
 static char *
 bonjour_status_text(GaimBuddy *buddy)
 {
@@ -359,7 +346,7 @@
 	/* {"png", 0, 0, 96, 96, 0, GAIM_ICON_SCALE_DISPLAY}, */ /* icon_spec */
 	NO_BUDDY_ICONS, /* not yet */                            /* icon_spec */
 	bonjour_list_icon,                                       /* list_icon */
-	bonjour_list_emblems,                                    /* list_emblems */
+	NULL, 		                      			 /* list_emblem */
 	bonjour_status_text,                                     /* status_text */
 	bonjour_tooltip_text,                                    /* tooltip_text */
 	bonjour_status_types,                                    /* status_types */
--- a/libpurple/protocols/gg/gg.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/gg/gg.c	Tue Jan 30 06:53:23 2007 +0000
@@ -1515,31 +1515,6 @@
 }
 /* }}} */
 
-/* static void ggp_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne) {{{ */
-static void ggp_list_emblems(GaimBuddy *b, const char **se, const char **sw,
-					   const char **nw, const char **ne)
-{
-	GaimPresence *presence = gaim_buddy_get_presence(b);
-
-	/* 
-	 * Note to myself:
-	 * 	The only valid status types are those defined
-	 * 	in prpl_info->status_types.
-	 *
-	 * Usable icons: away, blocked, dnd, extended_away,
-	 * freeforchat, ignored, invisible, na, offline.
-	 */
-
-	if (!GAIM_BUDDY_IS_ONLINE(b)) {
-		*se = "offline";
-	} else if (gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_AWAY)) {
-		*se = "away";
-	} else if (gaim_presence_is_status_active(presence, "blocked")) {
-		*se = "blocked";
-	}
-}
-/* }}} */
-
 /* static char *ggp_status_text(GaimBuddy *b) {{{ */
 static char *ggp_status_text(GaimBuddy *b)
 {
@@ -2081,7 +2056,7 @@
 	NULL,				/* protocol_options */
 	NO_BUDDY_ICONS,			/* icon_spec */
 	ggp_list_icon,			/* list_icon */
-	ggp_list_emblems,		/* list_emblems */
+	NULL,				/* list_emblem */
 	ggp_status_text,		/* status_text */
 	ggp_tooltip_text,		/* tooltip_text */
 	ggp_status_types,		/* status_types */
--- a/libpurple/protocols/irc/irc.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/irc/irc.c	Tue Jan 30 06:53:23 2007 +0000
@@ -42,7 +42,6 @@
 static void irc_buddy_append(char *name, struct irc_buddy *ib, GString *string);
 
 static const char *irc_blist_icon(GaimAccount *a, GaimBuddy *b);
-static void irc_blist_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne);
 static GList *irc_status_types(GaimAccount *account);
 static GList *irc_actions(GaimPlugin *plugin, gpointer context);
 /* static GList *irc_chat_info(GaimConnection *gc); */
@@ -222,15 +221,6 @@
 	return "irc";
 }
 
-static void irc_blist_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne)
-{
-	GaimPresence *presence = gaim_buddy_get_presence(b);
-
-	if (gaim_presence_is_online(presence) == FALSE) {
-		*se = "offline";
-	}
-}
-
 static GList *irc_status_types(GaimAccount *account)
 {
 	GaimStatusType *type;
@@ -813,7 +803,7 @@
 	NULL,					/* protocol_options */
 	NO_BUDDY_ICONS,		/* icon_spec */
 	irc_blist_icon,		/* list_icon */
-	irc_blist_emblems,	/* list_emblems */
+	NULL,			/* list_emblems */
 	NULL,					/* status_text */
 	NULL,					/* tooltip_text */
 	irc_status_types,	/* away_states */
--- a/libpurple/protocols/jabber/jabber.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Tue Jan 30 06:53:23 2007 +0000
@@ -1068,8 +1068,7 @@
 	return "jabber";
 }
 
-static void jabber_list_emblems(GaimBuddy *b, const char **se, const char **sw,
-		const char **nw, const char **ne)
+static const char* jabber_list_emblem(GaimBuddy *b)
 {
 	JabberStream *js;
 	JabberBuddy *jb = NULL;
@@ -1081,22 +1080,11 @@
 		jb = jabber_buddy_find(js, b->name, FALSE);
 
 	if(!GAIM_BUDDY_IS_ONLINE(b)) {
-		if(jb && jb->error_msg)
-			*nw = "error";
-
 		if(jb && (jb->subscription & JABBER_SUB_PENDING ||
 					!(jb->subscription & JABBER_SUB_TO)))
-			*se = "notauthorized";
-		else
-			*se = "offline";
-	} else {
-		GaimStatusType *status_type = gaim_status_get_type(gaim_presence_get_active_status(gaim_buddy_get_presence(b)));
-		GaimStatusPrimitive primitive = gaim_status_type_get_primitive(status_type);
-
-		if(primitive > GAIM_STATUS_AVAILABLE) {
-			*se = gaim_status_type_get_id(status_type);
-		}
+			return "not-authorized";
 	}
+	return NULL;
 }
 
 static char *jabber_status_text(GaimBuddy *b)
@@ -1853,7 +1841,7 @@
 	NULL,							/* protocol_options */
 	{"png,gif,jpeg", 32, 32, 96, 96, 8191, GAIM_ICON_SCALE_SEND | GAIM_ICON_SCALE_DISPLAY}, /* icon_spec */
 	jabber_list_icon,				/* list_icon */
-	jabber_list_emblems,			/* list_emblems */
+	jabber_list_emblem,			/* list_emblems */
 	jabber_status_text,				/* status_text */
 	jabber_tooltip_text,			/* tooltip_text */
 	jabber_status_types,			/* status_types */
--- a/libpurple/protocols/msn/msn.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/msn/msn.c	Tue Jan 30 06:53:23 2007 +0000
@@ -479,40 +479,14 @@
 	return "msn";
 }
 
-static void
-msn_list_emblems(GaimBuddy *b, const char **se, const char **sw,
-				 const char **nw, const char **ne)
+static const char* 
+msn_list_emblem(GaimBuddy *b)
 {
 	MsnUser *user;
-	GaimPresence *presence;
-	const char *emblems[4] = { NULL, NULL, NULL, NULL };
-	int i = 0;
-
 	user = b->proto_data;
-	presence = gaim_buddy_get_presence(b);
-
-	if (!gaim_presence_is_online(presence))
-		emblems[i++] = "offline";
-	else if (gaim_presence_is_status_active(presence, "busy") ||
-			 gaim_presence_is_status_active(presence, "phone"))
-		emblems[i++] = "occupied";
-	else if (!gaim_presence_is_available(presence))
-		emblems[i++] = "away";
-
-	if (user == NULL)
-	{
-		emblems[0] = "offline";
-	}
-	else
-	{
-		if (user->mobile)
-			emblems[i++] = "wireless";
-	}
-
-	*se = emblems[0];
-	*sw = emblems[1];
-	*nw = emblems[2];
-	*ne = emblems[3];
+		if (user && user->mobile)
+			return "mobile";
+	return NULL;
 }
 
 static char *
@@ -1956,7 +1930,7 @@
 	NULL,					/* protocol_options */
 	{"png", 0, 0, 96, 96, 0, GAIM_ICON_SCALE_SEND},	/* icon_spec */
 	msn_list_icon,			/* list_icon */
-	msn_list_emblems,		/* list_emblems */
+	msn_list_emblem,		/* list_emblems */
 	msn_status_text,		/* status_text */
 	msn_tooltip_text,		/* tooltip_text */
 	msn_status_types,		/* away_states */
--- a/libpurple/protocols/novell/novell.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/novell/novell.c	Tue Jan 30 06:53:23 2007 +0000
@@ -2783,40 +2783,6 @@
 	}
 }
 
-static void
-novell_list_emblems(GaimBuddy * buddy, const char **se, const char **sw, const char **nw, const char **ne)
-{
-	NMUserRecord *user_record = NULL;
-	GaimConnection *gc;
-	NMUser *user;
-	int status = 0;
-
-	gc = gaim_account_get_connection(buddy->account);
-
-	if (gc == NULL || (user = gc->proto_data) == NULL)
-		return;
-
-	user_record = nm_find_user_record(user, buddy->name);
-
-	if (user_record)
-		status = nm_user_record_get_status(user_record);
-
-	switch (status) {
-		case NM_STATUS_AVAILABLE:
-			*se = "";
-			break;
-		case NM_STATUS_AWAY:
-			*se = "away";
-			break;
-		case NM_STATUS_BUSY:
-			*se = "occupied";
-			break;
-		case NM_STATUS_UNKNOWN:
-			*se = "error";
-			break;
-	}
-}
-
 static const char *
 novell_list_icon(GaimAccount * account, GaimBuddy * buddy)
 {
@@ -3472,7 +3438,7 @@
 	NULL,						/* protocol_options */
 	NO_BUDDY_ICONS,				/* icon_spec */
 	novell_list_icon,			/* list_icon */
-	novell_list_emblems,		/* list_emblems */
+	NULL,				/* list_emblems */
 	novell_status_text,			/* status_text */
 	novell_tooltip_text,		/* tooltip_text */
 	novell_status_types,		/* status_types */
--- a/libpurple/protocols/oscar/libaim.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/oscar/libaim.c	Tue Jan 30 06:53:23 2007 +0000
@@ -35,7 +35,7 @@
 	{"gif,jpeg,bmp,ico", 48, 48, 50, 50, 7168,
 		GAIM_ICON_SCALE_SEND | GAIM_ICON_SCALE_DISPLAY},	/* icon_spec */
 	oscar_list_icon_aim,		/* list_icon */
-	oscar_list_emblems,		/* list_emblems */
+	oscar_list_emblem,		/* list_emblems */
 	oscar_status_text,		/* status_text */
 	oscar_tooltip_text,		/* tooltip_text */
 	oscar_status_types,		/* status_types */
--- a/libpurple/protocols/oscar/libicq.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/oscar/libicq.c	Tue Jan 30 06:53:23 2007 +0000
@@ -35,7 +35,7 @@
 	{"gif,jpeg,bmp,ico", 48, 48, 50, 50, 7168,
 		GAIM_ICON_SCALE_SEND | GAIM_ICON_SCALE_DISPLAY},	/* icon_spec */
 	oscar_list_icon_icq,		/* list_icon */
-	oscar_list_emblems,		/* list_emblems */
+	oscar_list_emblem,		/* list_emblems */
 	oscar_status_text,		/* status_text */
 	oscar_tooltip_text,		/* tooltip_text */
 	oscar_status_types,		/* status_types */
--- a/libpurple/protocols/oscar/oscar.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Tue Jan 30 06:53:23 2007 +0000
@@ -5397,7 +5397,7 @@
 	return "aim";
 }
 
-void oscar_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne)
+const char* oscar_list_emblem(GaimBuddy *b)
 {
 	GaimConnection *gc = NULL;
 	OscarData *od = NULL;
@@ -5405,8 +5405,6 @@
 	GaimPresence *presence;
 	GaimStatus *status;
 	const char *status_id;
-	char *emblems[4] = {NULL,NULL,NULL,NULL};
-	int i = 0;
 	aim_userinfo_t *userinfo = NULL;
 
 	account = b->account;
@@ -5426,52 +5424,25 @@
 		if ((b->name) && (od) && (od->ssi.received_data) &&
 			(gname = aim_ssi_itemlist_findparentname(od->ssi.local, b->name)) &&
 			(aim_ssi_waitingforauth(od->ssi.local, gname, b->name))) {
-			emblems[i++] = "notauthorized";
-		} else {
-			emblems[i++] = "offline";
+			return "not-authorized";
 		}
 	}
-
-	if (b->name && aim_sn_is_icq(b->name)) {
-		if (!strcmp(status_id, OSCAR_STATUS_ID_INVISIBLE))
-				emblems[i++] = "invisible";
-		else if (!strcmp(status_id, OSCAR_STATUS_ID_FREE4CHAT))
-			emblems[i++] = "freeforchat";
-		else if (!strcmp(status_id, OSCAR_STATUS_ID_DND))
-			emblems[i++] = "dnd";
-		else if (!strcmp(status_id, OSCAR_STATUS_ID_NA))
-			emblems[i++] = "unavailable";
-		else if (!strcmp(status_id, OSCAR_STATUS_ID_OCCUPIED))
-			emblems[i++] = "occupied";
-		else if (!strcmp(status_id, OSCAR_STATUS_ID_AWAY))
-			emblems[i++] = "away";
-	} else if (!strcmp(status_id, OSCAR_STATUS_ID_AWAY)) {
-		emblems[i++] = "away";
-	}
-
+	
 	if (userinfo != NULL ) {
-	/*  if (userinfo->flags & AIM_FLAG_UNCONFIRMED)
-			emblems[i++] = "unconfirmed"; */
-		if ((i < 4) && userinfo->flags & AIM_FLAG_ADMINISTRATOR)
-			emblems[i++] = "admin";
-		if ((i < 4) && userinfo->flags & AIM_FLAG_AOL)
-			emblems[i++] = "aol";
-		if ((i < 4) && userinfo->flags & AIM_FLAG_WIRELESS)
-			emblems[i++] = "wireless";
-		if ((i < 4) && userinfo->flags & AIM_FLAG_ACTIVEBUDDY)
-			emblems[i++] = "activebuddy";
-
-		if ((i < 4) && (userinfo->capabilities & OSCAR_CAPABILITY_HIPTOP))
-			emblems[i++] = "hiptop";
-
-		if ((i < 4) && (userinfo->capabilities & OSCAR_CAPABILITY_SECUREIM))
-			emblems[i++] = "secure";
-	}
-
-	*se = emblems[0];
-	*sw = emblems[1];
-	*nw = emblems[2];
-	*ne = emblems[3];
+		if (userinfo->flags & AIM_FLAG_ADMINISTRATOR)
+			return "admin";
+		if (userinfo->flags & AIM_FLAG_WIRELESS)
+			return "mobile";
+		if (userinfo->capabilities & OSCAR_CAPABILITY_HIPTOP)
+			return "mobile";
+		if (userinfo->flags & AIM_FLAG_ACTIVEBUDDY)
+			return "bot";
+		if (userinfo->flags & AIM_FLAG_AOL)
+			return "aolclient";
+		if (userinfo->capabilities & OSCAR_CAPABILITY_SECUREIM)
+			return "secure";
+	}
+	return NULL;
 }
 
 void oscar_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full) {
--- a/libpurple/protocols/oscar/oscarcommon.h	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/oscar/oscarcommon.h	Tue Jan 30 06:53:23 2007 +0000
@@ -47,7 +47,7 @@
 #endif
 const char *oscar_list_icon_icq(GaimAccount *a, GaimBuddy *b);
 const char *oscar_list_icon_aim(GaimAccount *a, GaimBuddy *b);
-void oscar_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne);
+const char* oscar_list_emblem(GaimBuddy *b);
 char *oscar_status_text(GaimBuddy *b);
 void oscar_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full);
 GList *oscar_status_types(GaimAccount *account);
--- a/libpurple/protocols/qq/qq.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/qq/qq.c	Tue Jan 30 06:53:23 2007 +0000
@@ -250,38 +250,24 @@
 }
 
 /* we can show tiny icons on the four corners of buddy icon, */
-static void _qq_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne)
+static const char *_qq_list_emblem(GaimBuddy *b)
 {
 	/* each char** are refering to a filename in pixmaps/gaim/status/default/ */
 
 	qq_buddy *q_bud = b->proto_data;
-	const char *emblems[4] = { NULL, NULL, NULL, NULL };
-	int i = 1;
 
-	if (q_bud == NULL) {
-		emblems[0] = "offline";
-	} else {
-		if (q_bud->status == QQ_BUDDY_ONLINE_AWAY)
-			emblems[i++] = "away";
-		/*
+	if (q_bud) {
+		if (q_bud->comm_flag & QQ_COMM_FLAG_BIND_MOBILE)
+			return "mobile";
 		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";
+			return "qq_member";
 		/*
 		if (q_bud->comm_flag & QQ_COMM_FLAG_VIDEO)
-			emblems[i%4] = "video";
+			return "video";
 		*/
-
 	}
 
-	*se = emblems[0];
-	*sw = emblems[1];
-	*nw = emblems[2];
-	*ne = emblems[3];
-
-	return;
+	return NULL;
 }
 
 /* QQ away status (used to initiate QQ away packet) */
@@ -655,7 +641,7 @@
 	NULL,							/* protocol_options */
 	{"png", 96, 96, 96, 96, 0, GAIM_ICON_SCALE_SEND}, /* icon_spec */
 	_qq_list_icon,						/* list_icon */
-	_qq_list_emblems,					/* list_emblems */
+	_qq_list_emblem,					/* list_emblems */
 	_qq_status_text,					/* status_text	*/
 	_qq_tooltip_text,					/* tooltip_text */
 	_qq_away_states,					/* away_states	*/
--- a/libpurple/protocols/sametime/sametime.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Tue Jan 30 06:53:23 2007 +0000
@@ -3171,33 +3171,12 @@
 }
 
 
-static void mw_prpl_list_emblems(GaimBuddy *b,
-				 const char **se, const char **sw,
-				 const char **nw, const char **ne) {
-
-  /* speaking of custom icons, the external icon here is an ugly
-     little example of what happens when I use Gimp */
-
-  GaimPresence *presence;
-  GaimStatus *status;
-  const char *status_id;
-
-  presence = gaim_buddy_get_presence(b);
-  status = gaim_presence_get_active_status(presence);
-  status_id = gaim_status_get_id(status);
-
-  if(! GAIM_BUDDY_IS_ONLINE(b)) {
-    *se = "offline";
-  } else if(!strcmp(status_id, MW_STATE_AWAY)) {
-    *se = "away";
-  } else if(!strcmp(status_id, MW_STATE_BUSY)) {
-    *se = "dnd";
-  }  
-
-  if(buddy_is_external(b)) {
-    /* best assignment ever */
-    *(*se?sw:se) = "external";
-  }
+static const char* mw_prpl_list_emblem(GaimBuddy *b)
+{
+  if(buddy_is_external(b)) 
+    return "external";
+
+  return NULL;
 }
 
 
@@ -5098,7 +5077,7 @@
   .protocol_options          = NULL, /*< set in mw_plugin_init */
   .icon_spec                 = NO_BUDDY_ICONS,
   .list_icon                 = mw_prpl_list_icon,
-  .list_emblems              = mw_prpl_list_emblems,
+  .list_emblem               = mw_prpl_list_emblem,
   .status_text               = mw_prpl_status_text,
   .tooltip_text              = mw_prpl_tooltip_text,
   .status_types              = mw_prpl_status_types,
--- a/libpurple/protocols/silc/silc.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/silc/silc.c	Tue Jan 30 06:53:23 2007 +0000
@@ -32,12 +32,6 @@
 	return (const char *)"silc";
 }
 
-static void
-silcgaim_list_emblems(GaimBuddy *b, const char **se, const char **sw,
-		      const char **nw, const char **ne)
-{
-}
-
 static GList *
 silcgaim_away_states(GaimAccount *account)
 {
@@ -1739,7 +1733,7 @@
 	NO_BUDDY_ICONS,
 #endif
 	silcgaim_list_icon,			/* list_icon */
-	silcgaim_list_emblems,		/* list_emblems */
+	NULL,				/* list_emblems */
 	silcgaim_status_text,		/* status_text */
 	silcgaim_tooltip_text,		/* tooltip_text */
 	silcgaim_away_states,		/* away_states */
--- a/libpurple/protocols/toc/toc.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/toc/toc.c	Tue Jan 30 06:53:23 2007 +0000
@@ -1515,28 +1515,15 @@
 	return "aim";
 }
 
-static void toc_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne)
+static const char* toc_list_emblem(GaimBuddy *b)
 {
-	char *emblems[4] = {NULL,NULL,NULL,NULL};
-	int i = 0;
-
-	if (!GAIM_BUDDY_IS_ONLINE(b)) {
-		*se = "offline";
-		return;
-	} else {
-		if (b->uc & UC_UNAVAILABLE)
-			emblems[i++] = "away";
-		if (b->uc & UC_AOL)
-			emblems[i++] = "aol";
-		if (b->uc & UC_ADMIN)
-			emblems[i++] = "admin";
-		if (b->uc & UC_WIRELESS)
-			emblems[i++] = "wireless";
-	}
-	*se = emblems[0];
-	*sw = emblems[1];
-	*nw = emblems[2];
-	*ne = emblems[3];
+	if (b->uc & UC_AOL)
+		return "aol";
+	if (b->uc & UC_ADMIN)
+		return "admin";
+	if (b->uc & UC_WIRELESS)
+		return "mobile";
+	return NULL	
 }
 
 static GList *toc_blist_node_menu(GaimBlistNode *node)
@@ -2243,7 +2230,7 @@
 	NULL,					/* protocol_options */
 	NO_BUDDY_ICONS,			/* icon_spec */
 	toc_list_icon,			/* list_icon */
-	toc_list_emblems,		/* list_emblems */
+	toc_list_emblem,		/* list_emblems */
 	NULL,					/* status_text */
 	NULL,					/* tooltip_text */
 	toc_away_states,		/* away_states */
--- a/libpurple/protocols/yahoo/yahoo.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Tue Jan 30 06:53:23 2007 +0000
@@ -2801,10 +2801,8 @@
 	return "yahoo";
 }
 
-static void yahoo_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne)
+static const char *yahoo_list_emblem(GaimBuddy *b)
 {
-	int i = 0;
-	char *emblems[4] = {NULL,NULL,NULL,NULL};
 	GaimAccount *account;
 	GaimConnection *gc;
 	struct yahoo_data *yd;
@@ -2817,29 +2815,20 @@
 
 	f = yahoo_friend_find(gc, b->name);
 	if (!f) {
-		*se = "notauthorized";
-		return;
+		return "not-authorized";
 	}
 
 	presence = gaim_buddy_get_presence(b);
 
-	if (gaim_presence_is_online(presence) == FALSE) {
-		*se = "offline";
-		return;
-	} else {
-		if (f->away)
-			emblems[i++] = "away";
+	if (gaim_presence_is_online(presence)) {
 		if (f->sms)
-			emblems[i++] = "wireless";
+			return "mobile";
 		if (yahoo_friend_get_game(f))
-			emblems[i++] = "game";
+			return "game";
 		if (f->protocol == 2)
-			emblems[i] = "msn";
+			return "msn";
 	}
-	*se = emblems[0];
-	*sw = emblems[1];
-	*nw = emblems[2];
-	*ne = emblems[3];
+	return NULL;
 }
 
 static const char *yahoo_get_status_string(enum yahoo_status a)
@@ -3816,7 +3805,7 @@
 	NULL, /* protocol_options */
 	{"png,gif,jpeg", 96, 96, 96, 96, 0, GAIM_ICON_SCALE_SEND},
 	yahoo_list_icon,
-	yahoo_list_emblems,
+	yahoo_list_emblem,
 	yahoo_status_text,
 	yahoo_tooltip_text,
 	yahoo_status_types,
--- a/libpurple/prpl.h	Tue Jan 30 05:27:44 2007 +0000
+++ b/libpurple/prpl.h	Tue Jan 30 06:53:23 2007 +0000
@@ -184,8 +184,7 @@
 	 * Fills the four char**'s with string identifiers for "emblems"
 	 * that the UI will interpret and display as relevant
 	 */
-	void (*list_emblems)(GaimBuddy *buddy, const char **se, const char **sw,
-						  const char **nw, const char **ne);
+	const char *(*list_emblem)(GaimBuddy *buddy);
 
 	/**
 	 * Gets a short string representing this buddy's status.  This will
--- a/pidgin/gtkblist.c	Tue Jan 30 05:27:44 2007 +0000
+++ b/pidgin/gtkblist.c	Tue Jan 30 06:53:23 2007 +0000
@@ -2931,11 +2931,51 @@
 	return g_string_free(str, FALSE);
 }
 
-struct _emblem_data {
-	const char *filename;
-	int x;
-	int y;
-};
+GdkPixbuf *
+gaim_gtk_blist_get_emblem(GaimBlistNode *node)
+{
+	GaimBuddy *buddy = NULL;
+	struct _gaim_gtk_blist_node *gtknode = node->ui_data;
+	struct _gaim_gtk_blist_node *gtkbuddynode = NULL;
+	GaimPlugin *prpl;
+	GaimPluginProtocolInfo *prpl_info;
+	const char *name = NULL;
+	char *filename, *path;
+	GdkPixbuf *ret;
+	if(GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		if(!gtknode->contact_expanded) {
+			buddy = gaim_contact_get_priority_buddy((GaimContact*)node);
+			gtkbuddynode = ((GaimBlistNode*)buddy)->ui_data;
+		}
+	} else if(GAIM_BLIST_NODE_IS_BUDDY(node)) {
+		buddy = (GaimBuddy*)node;
+		gtkbuddynode = node->ui_data;
+	} else {
+		return NULL;
+	}
+
+	prpl = gaim_find_prpl(gaim_account_get_protocol_id(buddy->account));
+	if (!prpl)
+		return NULL;
+
+	prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl);
+	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);
+	ret = gdk_pixbuf_new_from_file(path, NULL);
+	
+	g_free(filename);
+	g_free(path);
+
+	return ret;
+}
+
 
 GdkPixbuf *
 gaim_gtk_blist_get_status_icon(GaimBlistNode *node, GaimStatusIconSize size)
@@ -2944,8 +2984,6 @@
 	const char *protoname = NULL;
 	struct _gaim_gtk_blist_node *gtknode = node->ui_data;
 	struct _gaim_gtk_blist_node *gtkbuddynode = NULL;
-	struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15},
-		{NULL, 0, 0}, {NULL, 15, 0}};
 	GaimBuddy *buddy = NULL;
 	GaimChat *chat = NULL;
 	GtkIconSize icon_size = gtk_icon_size_from_name((size == GAIM_STATUS_ICON_LARGE) ? PIDGIN_ICON_SIZE_TANGO_MEDIUM :
@@ -2984,12 +3022,6 @@
 		if(prpl_info && prpl_info->list_icon) {
 			protoname = prpl_info->list_icon(account, buddy);
 		}
-		if(prpl_info && prpl_info->list_emblems && buddy) {
-			if(gtknode && !gtknode->recent_signonoff)
-				prpl_info->list_emblems(buddy, &emblems[0].filename,
-						&emblems[1].filename, &emblems[2].filename,
-						&emblems[3].filename);
-		}
 	}
 	
 	if(buddy) {
@@ -3045,12 +3077,6 @@
 		if(prpl_info && prpl_info->list_icon) {
 			protoname = prpl_info->list_icon(account, buddy);
 		}
-		if(prpl_info && prpl_info->list_emblems) {
-			if(gtknode && !gtknode->recent_signonoff)
-				prpl_info->list_emblems(buddy, &emblems[0].filename,
-						&emblems[1].filename, &emblems[2].filename,
-						&emblems[3].filename);
-		}
 
 		if(conv != NULL) {
 			GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv);
@@ -3067,12 +3093,6 @@
 		}
 	}
 
-	if(size == GAIM_STATUS_ICON_SMALL) {
-		scalesize = 15;
-		/* So that only the se icon will composite */
-		emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL;
-	}
-
 	if(buddy && GAIM_BUDDY_IS_ONLINE(buddy) &&  gtkbuddynode && gtkbuddynode->recent_signonoff) {
 			filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL);
 	} else if(buddy && !GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) {
@@ -3098,45 +3118,6 @@
 			GDK_INTERP_BILINEAR);
 	g_object_unref(status);
 
-	for(i=0; i<4; i++) {
-		if(emblems[i].filename) {
-			GdkPixbuf *emblem;
-			char *image = g_strdup_printf("%s.png", emblems[i].filename);
-			filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL);
-			g_free(image);
-			emblem = gdk_pixbuf_new_from_file(filename, NULL);
-			g_free(filename);
-			if(emblem) {
-				if(i == 0 && size == GAIM_STATUS_ICON_SMALL) {
-					double scale_factor = 0.6;
-					if(gdk_pixbuf_get_width(emblem) > 20)
-						scale_factor = 9.0 / gdk_pixbuf_get_width(emblem);
-
-					gdk_pixbuf_composite(emblem,
-							scale, 5, 5,
-							10, 10,
-							5, 5,
-							scale_factor, scale_factor,
-							GDK_INTERP_BILINEAR,
-							255);
-				} else {
-					double scale_factor = 1.0;
-					if(gdk_pixbuf_get_width(emblem) > 20)
-						scale_factor = 15.0 / gdk_pixbuf_get_width(emblem);
-
-					gdk_pixbuf_composite(emblem,
-							scale, emblems[i].x, emblems[i].y,
-							15, 15,
-							emblems[i].x, emblems[i].y,
-							scale_factor, scale_factor,
-							GDK_INTERP_BILINEAR,
-							255);
-				}
-				g_object_unref(emblem);
-			}
-		}
-	}
-
 	if(buddy) {
 		presence = gaim_buddy_get_presence(buddy);
 		if (!GAIM_BUDDY_IS_ONLINE(buddy))
@@ -4212,7 +4193,9 @@
 						 GDK_TYPE_COLOR,  /* bgcolor */
 						 G_TYPE_BOOLEAN,  /* Group expander */
 						 G_TYPE_BOOLEAN,  /* Contact expander */
-						 G_TYPE_BOOLEAN); /* Contact expander visible */
+						 G_TYPE_BOOLEAN,  /* Contact expander visible */
+						 GDK_TYPE_PIXBUF, /* Emblem */
+						 G_TYPE_BOOLEAN); /* Emblem visible */
 
 	gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel));
 
@@ -4311,6 +4294,15 @@
 					    NULL);
 
 	rend = gtk_cell_renderer_pixbuf_new();
+	g_object_set(rend, "xalign", 1.0, "yalign", 0.5, "ypad", 0, NULL);
+	gtk_tree_view_column_pack_start(column, rend, FALSE);
+	gtk_tree_view_column_set_attributes(column, rend, "pixbuf", EMBLEM_COLUMN,
+#if GTK_CHECK_VERSION(2,6,0)
+							  "cell-background-gdk", BGCOLOR_COLUMN,
+#endif
+							  "visible", EMBLEM_VISIBLE_COLUMN, NULL);
+
+	rend = gtk_cell_renderer_pixbuf_new();
 	g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL);
 	gtk_tree_view_column_pack_start(column, rend, FALSE);
 	gtk_tree_view_column_set_attributes(column, rend, "pixbuf", BUDDY_ICON_COLUMN,
@@ -4702,6 +4694,7 @@
 				   CONTACT_EXPANDER_VISIBLE_COLUMN, FALSE,
 				   BUDDY_ICON_VISIBLE_COLUMN, FALSE,
 				   IDLE_VISIBLE_COLUMN, FALSE,
+				   EMBLEM_VISIBLE_COLUMN, FALSE,
 				   -1);
 		g_free(title);
 	} else {
@@ -4742,7 +4735,7 @@
 static void buddy_node(GaimBuddy *buddy, GtkTreeIter *iter, GaimBlistNode *node)
 {
 	GaimPresence *presence;
-	GdkPixbuf *status, *avatar;
+	GdkPixbuf *status, *avatar, *emblem;
 	char *mark;
 	char *idle = NULL;
 	gboolean expanded = ((struct _gaim_gtk_blist_node *)(node->parent->ui_data))->contact_expanded;
@@ -4758,7 +4751,7 @@
 		g_object_ref(G_OBJECT(gtkblist->empty_avatar));
 		avatar = gtkblist->empty_avatar;
 	}
-
+	emblem = gaim_gtk_blist_get_emblem((GaimBlistNode*) buddy);
 	mark = gaim_gtk_blist_get_name_markup(buddy, selected);
 
 	if (gaim_prefs_get_bool("/gaim/gtk/blist/show_idle_time") &&
@@ -4796,6 +4789,8 @@
 			   IDLE_VISIBLE_COLUMN, !biglist && idle,
 			   BUDDY_ICON_COLUMN, avatar,
 			   BUDDY_ICON_VISIBLE_COLUMN, biglist,
+			   EMBLEM_COLUMN, emblem,
+			   EMBLEM_VISIBLE_COLUMN, emblem,
 			   BGCOLOR_COLUMN, NULL,
 			   CONTACT_EXPANDER_COLUMN, NULL,
 			   CONTACT_EXPANDER_VISIBLE_COLUMN, expanded,
@@ -4922,6 +4917,7 @@
 		GtkTreeIter iter;
 		GdkPixbuf *status;
 		GdkPixbuf *avatar;
+		GdkPixbuf *emblem;
 		char *mark;
 
 		if(!insert_node(list, node, &iter))
@@ -4929,7 +4925,7 @@
 
 		status = gaim_gtk_blist_get_status_icon(node,
 				 GAIM_STATUS_ICON_SMALL);
-
+		emblem = gaim_gtk_blist_get_emblem(node);
 		avatar = gaim_gtk_blist_get_buddy_icon(node, TRUE, FALSE, TRUE);
 
 		mark = g_markup_escape_text(gaim_chat_get_name(chat), -1);
@@ -4939,6 +4935,8 @@
 				STATUS_ICON_VISIBLE_COLUMN, TRUE,
 				BUDDY_ICON_COLUMN, avatar ? avatar : gtkblist->empty_avatar,
 				BUDDY_ICON_VISIBLE_COLUMN,  gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons"),
+			        EMBLEM_COLUMN, emblem,
+				EMBLEM_VISIBLE_COLUMN, emblem != NULL,
 				NAME_COLUMN, mark,
 				-1);
 
--- a/pidgin/gtkblist.h	Tue Jan 30 05:27:44 2007 +0000
+++ b/pidgin/gtkblist.h	Tue Jan 30 06:53:23 2007 +0000
@@ -40,6 +40,8 @@
 	GROUP_EXPANDER_COLUMN,
 	CONTACT_EXPANDER_COLUMN,
 	CONTACT_EXPANDER_VISIBLE_COLUMN,
+	EMBLEM_COLUMN,
+	EMBLEM_VISIBLE_COLUMN,
 	BLIST_COLUMNS
 
 };
@@ -178,6 +180,16 @@
 void gaim_gtk_blist_update_refresh_timeout(void);
 
 /**
+ * Returns the blist emblem
+ *
+ * @param node   The node to return an emblem for
+ * 
+ * @return  A newly created GdkPixbuf, or NULL
+ */
+GdkPixbuf *
+gaim_gtk_blist_get_emblem(GaimBlistNode *node);
+
+/**
  * Useful for the buddy ticker
  */
 GdkPixbuf *gaim_gtk_blist_get_status_icon(GaimBlistNode *node,