changeset 29330:e3031e5785a3

merged with im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Wed, 03 Feb 2010 16:00:49 +0900
parents 06740353bfc7 (current diff) 4d50162d809e (diff)
children 4c4ddafbc089
files libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h pidgin/gtkblist.c pidgin/gtkutils.c
diffstat 11 files changed, 147 insertions(+), 142 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Fri Jan 29 13:00:26 2010 +0900
+++ b/COPYRIGHT	Wed Feb 03 16:00:49 2010 +0900
@@ -379,6 +379,7 @@
 R. Ramkumar
 Mart Raudsepp
 Etan Reisner
+Luoh Ren-Shan
 Kristian Rietveld
 Pekka Riikonen
 Tim Ringenbach
@@ -390,6 +391,7 @@
 Luciano Miguel Ferreira Rocha
 Andrew Rodland
 Miguel Rodríguez (migrax)
+Adi Roiban
 Martin Rosinski
 Bob Rossi
 Jason Roth
--- a/ChangeLog	Fri Jan 29 13:00:26 2010 +0900
+++ b/ChangeLog	Wed Feb 03 16:00:49 2010 +0900
@@ -31,6 +31,8 @@
 	  offline.
 	* Wrap XHTML messages in <p>, as described in XEP-0071, for compatibility
 	  with some clients.
+	* Don't do an SRV lookup for a STUN server associated with the account
+	  if one is already set globally in prefs.
 
 	Yahoo:
 	* Don't send <span> and </span> tags.  (Fartash Faghri)
@@ -40,6 +42,7 @@
 	  interior-focus style property is diabled. (Gabriel Schulhof)
 	* Correctly handle a multiline text field being required in a
 	  request form.  (Thanks to Florian Zeitz for finding this problem)
+	* Search friends by email-addresses in the buddy list. (Luoh Ren-Shan)
 
 version 2.6.5 (01/08/2010):
 	libpurple:
--- a/libpurple/dnssrv.c	Fri Jan 29 13:00:26 2010 +0900
+++ b/libpurple/dnssrv.c	Wed Feb 03 16:00:49 2010 +0900
@@ -366,7 +366,7 @@
 		cp += 6;
 
 		GETSHORT(dlen,cp);
-		if (query.type == T_SRV) {
+		if (type == T_SRV) {
 			GETSHORT(pref,cp);
 
 			GETSHORT(weight,cp);
@@ -386,7 +386,7 @@
 			srvres->weight = weight;
 
 			ret = g_list_prepend(ret, srvres);
-		} else if (query.type == T_TXT) {
+		} else if (type == T_TXT) {
 			txtres = g_new0(PurpleTxtResponse, 1);
 			txtres->content = g_strndup((gchar*)(++cp), dlen-1);
 			ret = g_list_append(ret, txtres);
--- a/libpurple/protocols/jabber/disco.c	Fri Jan 29 13:00:26 2010 +0900
+++ b/libpurple/protocols/jabber/disco.c	Wed Feb 03 16:00:49 2010 +0900
@@ -22,6 +22,7 @@
  */
 
 #include "internal.h"
+#include "network.h"
 #include "prefs.h"
 #include "debug.h"
 #include "request.h"
@@ -534,8 +535,12 @@
 			js->googletalk = TRUE;
 
 			/* autodiscover stun and relays */
-			jabber_google_send_jingle_info(js);
-		} else {
+			if (purple_network_get_stun_ip() == NULL ||
+		    	purple_strequal(purple_network_get_stun_ip(), "")) {
+				jabber_google_send_jingle_info(js);
+			}
+		} else if (purple_network_get_stun_ip() == NULL ||
+		    purple_strequal(purple_network_get_stun_ip(), "")) {
 			js->srv_query_data = 
 				purple_srv_resolve("stun", "udp", js->user->domain,
 					jabber_disco_stun_srv_resolve_cb, js);
--- a/libpurple/protocols/oscar/family_oservice.c	Fri Jan 29 13:00:26 2010 +0900
+++ b/libpurple/protocols/oscar/family_oservice.c	Wed Feb 03 16:00:49 2010 +0900
@@ -27,6 +27,24 @@
 
 #include "cipher.h"
 
+/*
+ * Each time we make a FLAP connection to an oscar server the server gives
+ * us a list of rate classes.  Each rate class has different properties for
+ * how frequently we can send SNACs in that rate class before we become
+ * throttled or disconnected.
+ *
+ * The server also gives us a list of every available SNAC and tells us which
+ * rate class it's in.  There are a lot of different SNACs, so this list can be
+ * fairly large.  One important characteristic of these rate classes is that
+ * currently (and since at least 2004) most SNACs are in the same rate class.
+ *
+ * One optimization we can do to save memory is to only keep track of SNACs
+ * that are in classes other than this default rate class.  So if we try to
+ * look up a SNAC and it's not in our hash table then we can assume that it's
+ * in the default rate class.
+ */
+#define OSCAR_DEFAULT_RATECLASS 1
+
 /* Subtype 0x0002 - Client Online */
 void
 aim_srv_clientready(OscarData *od, FlapConnection *conn)
@@ -323,7 +341,7 @@
 		struct timeval now;
 
 		gettimeofday(&now, NULL);
-		rateclass = g_new0(struct rateclass, 1);
+		rateclass = g_new(struct rateclass, 1);
 
 		rateclass->classid = byte_stream_get16(bs);
 		rateclass->windowsize = byte_stream_get32(bs);
@@ -333,34 +351,21 @@
 		rateclass->disconnect = byte_stream_get32(bs);
 		rateclass->current = byte_stream_get32(bs);
 		rateclass->max = byte_stream_get32(bs);
-
-		/*
-		 * The server will send an extra five bytes of parameters
-		 * depending on the version we advertised in 1/17.  If we
-		 * didn't send 1/17 (evil!), then this will crash and you
-		 * die, as it will default to the old version but we have
-		 * the new version hardcoded here.
-		 */
-		if (mod->version >= 3)
-		{
-			rateclass->delta = byte_stream_get32(bs);
+		if (mod->version >= 3) {
+			delta = byte_stream_get32(bs);
 			rateclass->dropping_snacs = byte_stream_get8(bs);
-
-			delta = rateclass->delta;
-
-			rateclass->last.tv_sec = now.tv_sec - delta / 1000;
-			delta %= 1000;
-			rateclass->last.tv_usec = now.tv_usec - delta * 1000;
-		}
-		else
-		{
-			rateclass->delta = rateclass->dropping_snacs = 0;
-			rateclass->last.tv_sec = now.tv_sec;
-			rateclass->last.tv_usec = now.tv_usec;
+		} else {
+			delta = 0;
+			rateclass->dropping_snacs = 0;
 		}
 
-		rateclass->members = g_hash_table_new(g_direct_hash, g_direct_equal);
+		rateclass->last.tv_sec = now.tv_sec - delta / 1000;
+		rateclass->last.tv_usec = now.tv_usec - (delta % 1000) * 1000;
+
 		conn->rateclasses = g_slist_prepend(conn->rateclasses, rateclass);
+
+		if (rateclass->classid == OSCAR_DEFAULT_RATECLASS)
+			conn->default_rateclass = rateclass;
 	}
 	conn->rateclasses = g_slist_reverse(conn->rateclasses);
 
@@ -376,6 +381,15 @@
 		classid = byte_stream_get16(bs);
 		count = byte_stream_get16(bs);
 
+		if (classid == OSCAR_DEFAULT_RATECLASS) {
+			/*
+			 * Don't bother adding these SNACs to the hash table.  See the
+			 * comment for OSCAR_DEFAULT_RATECLASS at the top of this file.
+			 */
+			byte_stream_advance(bs, 4 * count);
+			continue;
+		}
+
 		rateclass = rateclass_find(conn->rateclasses, classid);
 
 		for (j = 0; j < count; j++)
@@ -386,9 +400,9 @@
 			subtype = byte_stream_get16(bs);
 
 			if (rateclass != NULL)
-				g_hash_table_insert(rateclass->members,
+				g_hash_table_insert(conn->rateclass_members,
 						GUINT_TO_POINTER((group << 16) + subtype),
-						GUINT_TO_POINTER(TRUE));
+						rateclass);
 		}
 	}
 
@@ -462,12 +476,17 @@
 static int
 ratechange(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
 {
-	int ret = 0;
-	aim_rxcallback_t userfunc;
 	guint16 code, classid;
 	struct rateclass *rateclass;
 	guint32 delta;
 	struct timeval now;
+	static const char *codes[5] = {
+		"invalid",
+		"change",
+		"warning",
+		"limit",
+		"limit cleared",
+	};
 
 	gettimeofday(&now, NULL);
 	code = byte_stream_get16(bs);
@@ -485,32 +504,32 @@
 	rateclass->disconnect = byte_stream_get32(bs);
 	rateclass->current = byte_stream_get32(bs);
 	rateclass->max = byte_stream_get32(bs);
-
-	if (mod->version >= 3)
-	{
-		rateclass->delta = byte_stream_get32(bs);
+	if (mod->version >= 3) {
+		delta = byte_stream_get32(bs);
 		rateclass->dropping_snacs = byte_stream_get8(bs);
-
-		delta = rateclass->delta;
-
-		rateclass->last.tv_sec = now.tv_sec - delta / 1000;
-		delta %= 1000;
-		rateclass->last.tv_usec = now.tv_usec - delta * 1000;
-	}
-	else
-	{
-		rateclass->delta = rateclass->dropping_snacs = 0;
-		rateclass->last.tv_sec = now.tv_sec;
-		rateclass->last.tv_usec = now.tv_usec;
+	} else {
+		delta = 0;
+		rateclass->dropping_snacs = 0;
 	}
 
-	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) {
-		/* Can't pass in guint8 via ... varargs, so we use an unsigned int */
-		unsigned int dropping_snacs = rateclass->dropping_snacs;
-		ret = userfunc(od, conn, frame, code, classid, rateclass->windowsize, rateclass->clear, rateclass->alert, rateclass->limit, rateclass->disconnect, rateclass->current, rateclass->max, rateclass->delta, dropping_snacs);
+	rateclass->last.tv_sec = now.tv_sec - delta / 1000;
+	rateclass->last.tv_usec = now.tv_usec - (delta % 1000) * 1000;
+
+	purple_debug_misc("oscar", "rate %s (param ID 0x%04hx): curavg = %u, "
+			"maxavg = %u, alert at %u, clear warning at %u, limit at %u, "
+			"disconnect at %u, delta is %u, dropping is %u (window size = %u)\n",
+			(code < 5) ? codes[code] : codes[0], rateclass->classid,
+			rateclass->current, rateclass->max, rateclass->alert,
+			rateclass->clear, rateclass->limit, rateclass->disconnect,
+			delta, rateclass->dropping_snacs, rateclass->windowsize);
+
+	if (code == AIM_RATE_CODE_LIMIT) {
+		purple_debug_warning("oscar",  _("The last action you attempted "
+				"could not be performed because you are over the rate "
+				"limit. Please wait 10 seconds and try again.\n"));
 	}
 
-	return ret;
+	return 1;
 }
 
 /*
--- a/libpurple/protocols/oscar/flap_connection.c	Fri Jan 29 13:00:26 2010 +0900
+++ b/libpurple/protocols/oscar/flap_connection.c	Wed Feb 03 16:00:49 2010 +0900
@@ -106,21 +106,15 @@
 static struct rateclass *
 flap_connection_get_rateclass(FlapConnection *conn, guint16 family, guint16 subtype)
 {
-	GSList *tmp1;
 	gconstpointer key;
+	gpointer rateclass;
 
 	key = GUINT_TO_POINTER((family << 16) + subtype);
-
-	for (tmp1 = conn->rateclasses; tmp1 != NULL; tmp1 = tmp1->next)
-	{
-		struct rateclass *rateclass;
-		rateclass = tmp1->data;
+	rateclass = g_hash_table_lookup(conn->rateclass_members, key);
+	if (rateclass != NULL)
+		return rateclass;
 
-		if (g_hash_table_lookup(rateclass->members, key))
-			return rateclass;
-	}
-
-	return NULL;
+	return conn->default_rateclass;
 }
 
 /*
@@ -133,10 +127,10 @@
 	unsigned long timediff; /* In milliseconds */
 	guint32 current;
 
+	/* This formula is documented at http://dev.aol.com/aim/oscar/#RATELIMIT */
 	timediff = (now->tv_sec - rateclass->last.tv_sec) * 1000 + (now->tv_usec - rateclass->last.tv_usec) / 1000;
 	current = ((rateclass->current * (rateclass->windowsize - 1)) + timediff) / rateclass->windowsize;
 
-	/* This formula is taken from http://dev.aol.com/aim/oscar/#RATELIMIT */
 	return MIN(current, rateclass->max);
 }
 
@@ -258,14 +252,6 @@
 			rateclass->last.tv_sec = now.tv_sec;
 			rateclass->last.tv_usec = now.tv_usec;
 		}
-	} else {
-		/*
-		 * It's normal for SNACs 0x0001/0x0006 and 0x0001/0x0017 to be
-		 * sent before we receive rate info from the server, so don't
-		 * bother warning about them.
-		 */
-		if (family != 0x0001 || (subtype != 0x0006 && subtype != 0x0017))
-			purple_debug_warning("oscar", "No rate class found for family 0x%04hx subtype 0x%04hx\n", family, subtype);
 	}
 
 	if (enqueue)
@@ -354,6 +340,7 @@
 	conn->fd = -1;
 	conn->subtype = -1;
 	conn->type = type;
+	conn->rateclass_members = g_hash_table_new(g_direct_hash, g_direct_equal);
 
 	od->oscar_connections = g_slist_prepend(od->oscar_connections, conn);
 
@@ -421,13 +408,6 @@
 	conn->buffer_outgoing = NULL;
 }
 
-static void
-flap_connection_destroy_rateclass(struct rateclass *rateclass)
-{
-	g_hash_table_destroy(rateclass->members);
-	g_free(rateclass);
-}
-
 /**
  * Free a FlapFrame
  *
@@ -515,10 +495,12 @@
 	g_slist_free(conn->groups);
 	while (conn->rateclasses != NULL)
 	{
-		flap_connection_destroy_rateclass(conn->rateclasses->data);
+		g_free(conn->rateclasses->data);
 		conn->rateclasses = g_slist_delete_link(conn->rateclasses, conn->rateclasses);
 	}
 
+	g_hash_table_destroy(conn->rateclass_members);
+
 	if (conn->queued_snacs) {
 		while (!g_queue_is_empty(conn->queued_snacs))
 		{
--- a/libpurple/protocols/oscar/oscar.c	Fri Jan 29 13:00:26 2010 +0900
+++ b/libpurple/protocols/oscar/oscar.c	Wed Feb 03 16:00:49 2010 +0900
@@ -190,7 +190,6 @@
 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 *, ...);
@@ -1554,7 +1553,6 @@
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x000f, purple_selfinfo, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x001f, purple_memrequest, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x0021, oscar_icon_req,0);
-	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_RATECHANGE, purple_parse_ratechange, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_REDIRECT, purple_handle_redirect, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_MOTD, purple_parse_motd, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_EVIL, purple_parse_evilnotify, 0);
@@ -3871,56 +3869,6 @@
 	return 1;
 }
 
-static int purple_parse_ratechange(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
-	static const char *codes[5] = {
-		"invalid",
-		"change",
-		"warning",
-		"limit",
-		"limit cleared",
-	};
-	va_list ap;
-	guint16 code, rateclass;
-	guint32 windowsize, clear, alert, limit, disconnect, currentavg, maxavg, delta;
-	guint8 dropping_snacs;
-
-	va_start(ap, fr);
-	code = (guint16)va_arg(ap, unsigned int);
-	rateclass= (guint16)va_arg(ap, unsigned int);
-	windowsize = va_arg(ap, guint32);
-	clear = va_arg(ap, guint32);
-	alert = va_arg(ap, guint32);
-	limit = va_arg(ap, guint32);
-	disconnect = va_arg(ap, guint32);
-	currentavg = va_arg(ap, guint32);
-	maxavg = va_arg(ap, guint32);
-	delta = va_arg(ap, guint32);
-	dropping_snacs = (guint8)va_arg(ap, unsigned int);
-	va_end(ap);
-
-	purple_debug_misc("oscar",
-			   "rate %s (param ID 0x%04hx): curavg = %u, maxavg = %u, alert at %u, "
-		     "clear warning at %u, limit at %u, disconnect at %u, delta is %u, dropping is %u (window size = %u)\n",
-		     (code < 5) ? codes[code] : codes[0],
-		     rateclass,
-		     currentavg, maxavg,
-		     alert, clear,
-		     limit, disconnect,
-		     delta,
-		     dropping_snacs,
-		     windowsize
-		     );
-
-	if (code == AIM_RATE_CODE_LIMIT)
-	{
-		purple_debug_warning("oscar",  _("The last action you attempted could not be "
-				"performed because you are over the rate limit. "
-				"Please wait 10 seconds and try again.\n"));
-	}
-
-	return 1;
-}
-
 static int purple_parse_evilnotify(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
 #ifdef CRAZY_WARNING
 	va_list ap;
--- a/libpurple/protocols/oscar/oscar.h	Fri Jan 29 13:00:26 2010 +0900
+++ b/libpurple/protocols/oscar/oscar.h	Wed Feb 03 16:00:49 2010 +0900
@@ -445,6 +445,8 @@
 	guint16 seqnum_in; /**< The sequence number of most recently received packet. */
 	GSList *groups;
 	GSList *rateclasses; /* Contains nodes of struct rateclass. */
+	struct rateclass *default_rateclass;
+	GHashTable *rateclass_members; /* Key is family and subtype, value is pointer to the rateclass struct to use. */
 
 	GQueue *queued_snacs; /**< Contains QueuedSnacs. */
 	GQueue *queued_lowpriority_snacs; /**< Contains QueuedSnacs to send only once queued_snacs is empty */
@@ -1686,9 +1688,7 @@
 	guint32 disconnect;
 	guint32 current;
 	guint32 max;
-	guint32 delta;
 	guint8 dropping_snacs;
-	GHashTable *members; /* Key is family and subtype, value is TRUE. */
 
 	struct timeval last; /**< The time when we last sent a SNAC of this rate class. */
 };
--- a/pidgin/gtkblist.c	Fri Jan 29 13:00:26 2010 +0900
+++ b/pidgin/gtkblist.c	Wed Feb 03 16:00:49 2010 +0900
@@ -5622,6 +5622,51 @@
 
 }
 
+static gboolean
+pidgin_blist_search_equal_func(GtkTreeModel *model, gint column,
+			const gchar *key, GtkTreeIter *iter, gpointer data)
+{
+	PurpleBlistNode *node = NULL;
+	gboolean res = TRUE;
+	const char *compare = NULL;
+
+	if (!pidgin_tree_view_search_equal_func(model, column, key, iter, data))
+		return FALSE;
+
+	/* If the search string does not match the displayed label, then look
+	 * at the alternate labels for the nodes and search in them. Currently,
+	 * alternate labels that make sense are usernames/email addresses for
+	 * buddies (but only for the ones who don't have a local alias).
+	 */
+
+	gtk_tree_model_get(model, iter, NODE_COLUMN, &node, -1);
+	if (!node)
+		return TRUE;
+
+	compare = NULL;
+	if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+		PurpleBuddy *b = purple_contact_get_priority_buddy(PURPLE_CONTACT(node));
+		if (!purple_buddy_get_local_buddy_alias(b))
+			compare = purple_buddy_get_name(b);
+	} else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+		if (!purple_buddy_get_local_buddy_alias(PURPLE_BUDDY(node)))
+			compare = purple_buddy_get_name(PURPLE_BUDDY(node));
+	}
+
+	if (compare) {
+		char *tmp, *enteredstring;
+		tmp = g_utf8_normalize(key, -1, G_NORMALIZE_DEFAULT);
+		enteredstring = g_utf8_casefold(tmp, -1);
+		g_free(tmp);
+
+		if (purple_str_has_prefix(compare, enteredstring))
+			res = FALSE;
+		g_free(enteredstring);
+	}
+
+	return res;
+}
+
 static void pidgin_blist_show(PurpleBuddyList *list)
 {
 	PidginBuddyListPrivate *priv;
@@ -5858,7 +5903,8 @@
 
 	/* Enable CTRL+F searching */
 	gtk_tree_view_set_search_column(GTK_TREE_VIEW(gtkblist->treeview), NAME_COLUMN);
-	gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview), pidgin_tree_view_search_equal_func, NULL, NULL);
+	gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview),
+			pidgin_blist_search_equal_func, NULL, NULL);
 
 	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0);
 	gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview);
--- a/pidgin/gtkthemes.c	Fri Jan 29 13:00:26 2010 +0900
+++ b/pidgin/gtkthemes.c	Wed Feb 03 16:00:49 2010 +0900
@@ -309,7 +309,7 @@
 			while  (*i) {
 				char l[64];
 				int li = 0;
-				while (!isspace(*i) && li < sizeof(l) - 1) {
+				while (*i && !isspace(*i) && li < sizeof(l) - 1) {
 					if (*i == '\\' && *(i+1) != '\0')
 						i++;
 					l[li++] = *(i++);
--- a/pidgin/gtkutils.c	Fri Jan 29 13:00:26 2010 +0900
+++ b/pidgin/gtkutils.c	Wed Feb 03 16:00:49 2010 +0900
@@ -1586,8 +1586,8 @@
 						    _("You have dragged an image"),
 						    _("You can send this image as a file transfer, "
 						      "embed it into this message, or use it as the buddy icon for this user."),
-						    DND_FILE_TRANSFER, "OK", (GCallback)dnd_image_ok_callback,
-						    "Cancel", (GCallback)dnd_image_cancel_callback,
+						    DND_FILE_TRANSFER, _("OK"), (GCallback)dnd_image_ok_callback,
+						    _("Cancel"), (GCallback)dnd_image_cancel_callback,
 							account, who, NULL,
 							data,
 							_("Set as buddy icon"), DND_BUDDY_ICON,
@@ -1606,8 +1606,8 @@
 						    (ft ? _("You can send this image as a file transfer, or use it as the buddy icon for this user.") :
 						    _("You can insert this image into this message, or use it as the buddy icon for this user")),
 						    (ft ? DND_FILE_TRANSFER : DND_IM_IMAGE),
-							"OK", (GCallback)dnd_image_ok_callback,
-						    "Cancel", (GCallback)dnd_image_cancel_callback,
+							_("OK"), (GCallback)dnd_image_ok_callback,
+						    _("Cancel"), (GCallback)dnd_image_cancel_callback,
 							account, who, NULL,
 							data,
 						    _("Set as buddy icon"), DND_BUDDY_ICON,