changeset 19240:258a721f6ae9

merge of '639773488963c6e7b2de9d73d6ee3abe3b3c51b1' and 'b888bc5c0494c9dd0398baba81e4d602ac88948f'
author Jeffrey Connelly <jaconnel@calpoly.edu>
date Mon, 13 Aug 2007 06:00:06 +0000
parents 829b00936eef (current diff) 0f46f13c0805 (diff)
children 0651af21ceee
files pidgin/sounds/Makefile.am pidgin/sounds/Makefile.mingw pidgin/sounds/alert.wav pidgin/sounds/login.wav pidgin/sounds/logout.wav pidgin/sounds/receive.wav pidgin/sounds/send.wav
diffstat 5 files changed, 216 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/myspace/myspace.c	Mon Aug 13 03:58:49 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Mon Aug 13 06:00:06 2007 +0000
@@ -37,9 +37,7 @@
 #include "persist.h"
 #include "myspace.h"
 
-
-/* Loosely based on Miranda plugin by Scott Ellis, formatting.cpp, 
- * https://server.scottellis.com.au/websvn/filedetails.php?repname=Miranda+Plugins&path=%2FMySpace%2Fformatting.cpp&rev=0&sc=0 */
+/* Globals */
 
 /* The names in in emoticon_names (for <i n=whatever>) map to corresponding 
  * entries in emoticon_symbols (for the ASCII representation of the emoticon).
@@ -47,7 +45,7 @@
  * Multiple emoticon symbols in Pidgin can map to one name. List the
  * canonical form, as inserted by the "Smile!" dialog, first. For example,
  * :) comes before :-), because although both are recognized as 'happy',
- * the first is inserted by the smiley button. 
+ * the first is inserted by the smiley button (first symbol in theme).
  *
  * Note that symbols are case-sensitive in Pidgin -- :-X is not :-x. */
 static struct MSIM_EMOTICON
@@ -95,7 +93,8 @@
 };
 
 /* Internal functions */
-static void msim_send_zap(PurpleBlistNode *node, gpointer zap_num_ptr);
+static gboolean msim_send_zap(MsimSession *session, const gchar *username, guint code);
+static void msim_send_zap_from_menu(PurpleBlistNode *node, gpointer zap_num_ptr);
 
 #ifdef MSIM_DEBUG_MSG
 static void print_hash_item(gpointer key, gpointer value, gpointer user_data);
@@ -283,60 +282,149 @@
 	return types;
 }
 
+/** Get zap types. */
+GList *
+msim_attention_types(PurpleAccount *acct)
+{
+	static GList *types = NULL;
+	PurpleAttentionType* attn;
+
+	if (!types) {
+#define _MSIM_ADD_NEW_ATTENTION(icn, des, incoming, outgoing)              \
+		attn = g_new0(PurpleAttentionType, 1);                     \
+		attn->icon = icn;                                          \
+		attn->description = des;                                   \
+		attn->incoming_description = incoming;                     \
+		attn->outgoing_description = outgoing;                     \
+		types = g_list_append(types, attn);
+
+		/* TODO: icons for each zap */
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("zap"), _("zapped"), _("Zapping"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("whack"), _("whacked"), _("Whacking"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("torch"), _("torched"), _("Torching"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("smooch"), _("smooched"), _("Smooching"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("hug"), _("hugged"), _("Hugging"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("bslap"), _("bslapped"), _("Bslapping"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("goose"), _("goosed"), _("Goosing"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("hi-five"), _("hi-fived"), _("Hi-fiving"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("punk"), _("punk'd"), _("Punking"));
+		_MSIM_ADD_NEW_ATTENTION(NULL, _("raspberry"), _("raspberried"), _("Raspberry'ing"));
+	}
+
+	return types;
+}
+
+/** Send a zap */
+gboolean
+msim_send_attention(PurpleConnection *gc, gchar *username, guint code)
+{
+	GList *types;
+	MsimSession *session;
+	PurpleAttentionType *attn;
+	PurpleBuddy *buddy;
+
+	session = (MsimSession *)gc->proto_data;
+
+	/* Look for this attention type, by the code index given. */
+	types = msim_attention_types(gc->account);
+	attn = (PurpleAttentionType *)g_list_nth_data(types, code);
+
+	if (!attn) {
+		purple_debug_info("msim_send_attention", "got invalid zap code %d\n", code);
+		return FALSE;
+	}
+
+	buddy = purple_find_buddy(session->account, username);
+	if (!buddy) {
+		return FALSE;
+	}
+
+	/* TODO: make use of the PurpleAttentionType we found, instead of
+	 * doing it all over in msim_send_zap_from_menu. */
+	msim_send_zap_from_menu(&buddy->node, GUINT_TO_POINTER(code));
+
+	return TRUE;
+}
+
+/** Send a zap to a user. */
+static gboolean
+msim_send_zap(MsimSession *session, const gchar *username, guint code)
+{
+	gchar *zap_string;
+#ifndef MSIM_USE_ATTENTION_API
+	gchar *zap_description;
+#endif
+	GList *types;
+	PurpleAttentionType *attn;
+	gboolean rc;
+
+	g_return_val_if_fail(session != NULL, FALSE);
+	g_return_val_if_fail(username != NULL, FALSE);
+
+	types = msim_attention_types(session->account);
+
+	attn = g_list_nth_data(types, code);
+	if (!attn) {
+		return FALSE;
+	}
+
+
+#ifdef MSIM_USE_ATTENTION_API
+	serv_got_attention(session->gc, username, attn, FALSE);
+#else
+	zap_description = g_strdup_printf("*** Attention: %s %s ***", attn->outgoing_description,
+			username);
+
+	serv_got_im(session->gc, username, zap_description,
+			PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_SYSTEM, time(NULL));
+
+	g_free(zap_description);
+#endif
+
+	/* Construct and send the actual zap command. */
+	zap_string = g_strdup_printf("!!!ZAP_SEND!!!=RTE_BTN_ZAPS_%d", code);
+
+	if (!msim_send_bm(session, username, zap_string, MSIM_BM_ACTION)) {
+		purple_debug_info("msim_send_zap_from_menu", "msim_send_bm failed: zapping %s with %s",
+				username, zap_string);
+		rc = FALSE;
+	} else {
+		rc = TRUE;
+	}
+	
+	g_free(zap_string);
+
+	return rc;
+
+}
+
 /** Zap someone. Callback from msim_blist_node_menu zap menu. */
 static void
-msim_send_zap(PurpleBlistNode *node, gpointer zap_num_ptr)
+msim_send_zap_from_menu(PurpleBlistNode *node, gpointer zap_num_ptr)
 {
 	PurpleBuddy *buddy;
+	PurpleAccount *account;
 	PurpleConnection *gc;
 	MsimSession *session;
-	gchar *username, *zap_string, *zap_text;
 	guint zap;
-	const gchar *zap_gerund[10];
 
 	if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) {
 		/* Only know about buddies for now. */
 		return;
 	}
 
-	zap_gerund[0] = _("Zapping");
-	zap_gerund[1] = _("Whacking");
-	zap_gerund[2] = _("Torching");
-	zap_gerund[3] = _("Smooching");
-	zap_gerund[4] = _("Hugging");
-	zap_gerund[5] = _("Bslapping");
-	zap_gerund[6] = _("Goosing");
-	zap_gerund[7] = _("Hi-fiving");
-	zap_gerund[8] = _("Punking");
-	zap_gerund[9] = _("Raspberry'ing");
- 
 	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
 
 	buddy = (PurpleBuddy *)node;
-	gc = purple_account_get_connection(buddy->account);
-	g_return_if_fail(gc != NULL);
-
+
+	/* Find the session */
+	account = buddy->account;
+	gc = purple_account_get_connection(account);
 	session = (MsimSession *)gc->proto_data;
-	g_return_if_fail(session != NULL);
-
-	username = buddy->name;
-	g_return_if_fail(username != NULL);
 
 	zap = GPOINTER_TO_INT(zap_num_ptr);
-	zap_string = g_strdup_printf("!!!ZAP_SEND!!!=RTE_BTN_ZAPS_%d", zap);
-	zap_text = g_strdup_printf("*** %s! ***", zap_gerund[zap]);
-
-	serv_got_im(session->gc, username, zap_text, 
-			PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_SYSTEM, time(NULL));
-
-	if (!msim_send_bm(session, username, zap_string, MSIM_BM_ACTION)) {
-		purple_debug_info("msim_send_zap", "msim_send_bm failed: zapping %s with %s",
-				username, zap_string);
-	}
-
-	g_free(zap_string);
-	g_free(zap_text);
-	return;
+
+	g_return_if_fail(msim_send_zap(session, buddy->name, zap));
 }
 
 
@@ -345,7 +433,9 @@
 msim_blist_node_menu(PurpleBlistNode *node)
 {
 	GList *menu, *zap_menu;
+	GList *types;
 	PurpleMenuAction *act;
+	/* Warning: hardcoded to match that in msim_attention_types. */
 	const gchar *zap_names[10];
 	guint i;
 
@@ -355,22 +445,22 @@
 	}
 
 	/* Names from official client. */
-	zap_names[0] = _("zap");
-	zap_names[1] = _("whack");
-	zap_names[2] = _("torch");
-	zap_names[3] = _("smooch");
-	zap_names[4] = _("hug");
-	zap_names[5] = _("bslap");
-	zap_names[6] = _("goose");
-	zap_names[7] = _("hi-five");
-	zap_names[8] = _("punk'd");
-	zap_names[9] = _("raspberry");
- 
+	types = msim_attention_types(NULL);
+	i = 0;
+	do
+	{
+		PurpleAttentionType *attn;
+
+		attn = (PurpleAttentionType *)types->data;
+		zap_names[i] = attn->description;
+		++i;
+	} while ((types = g_list_next(types)));
+
 	menu = zap_menu = NULL;
 
-	/* TODO: move to / command, or better yet new API  */
+	/* TODO: get rid of once is accessible directly in GUI */
 	for (i = 0; i < sizeof(zap_names) / sizeof(zap_names[0]); ++i) {
-		act = purple_menu_action_new(zap_names[i], PURPLE_CALLBACK(msim_send_zap),
+		act = purple_menu_action_new(zap_names[i], PURPLE_CALLBACK(msim_send_zap_from_menu),
 				GUINT_TO_POINTER(i), NULL);
 		zap_menu = g_list_append(zap_menu, act);
 	}
@@ -1592,9 +1682,14 @@
 static gboolean
 msim_incoming_zap(MsimSession *session, MsimMessage *msg)
 {
-	gchar *msg_text, *username, *zap_text;
+	gchar *msg_text, *username;
 	gint zap;
 	const gchar *zap_past_tense[10];
+#ifdef MSIM_USE_ATTENTION_API
+	PurpleAttentionType attn;
+#else
+	gchar *zap_text;
+#endif
 
 	zap_past_tense[0] = _("zapped");
 	zap_past_tense[1] = _("whacked");
@@ -1617,12 +1712,20 @@
 
 	zap = CLAMP(zap, 0, sizeof(zap_past_tense) / sizeof(zap_past_tense[0]));
 
+	/* TODO:ZAP: use msim_attention_types */
+#ifdef MSIM_USE_ATTENTION_API
+	attn.incoming_description = zap_past_tense[zap];
+	attn.outgoing_description = NULL;
+	attn.icon = NULL;		/* TODO: icon */
+
+	serv_got_attention(session->gc, username, &attn, TRUE);
+#else
 	zap_text = g_strdup_printf(_("*** You have been %s! ***"), zap_past_tense[zap]);
-
 	serv_got_im(session->gc, username, zap_text, 
 			PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_SYSTEM, time(NULL));
-
 	g_free(zap_text);
+#endif
+
 	g_free(msg_text);
 	g_free(username);
 
@@ -3865,12 +3968,17 @@
 	NULL,              /* can_receive_file */
 	NULL,              /* send_file */
 	NULL,              /* new_xfer */
-	msim_offline_message, /* offline_message */
+	msim_offline_message,  /* offline_message */
 	NULL,              /* whiteboard_prpl_ops */
-	msim_send_really_raw,     /* send_raw */
-	NULL,               /* roomlist_room_serialize */
+	msim_send_really_raw,  /* send_raw */
+	NULL,                  /* roomlist_room_serialize */
+#ifdef MSIM_USE_ATTENTION_API
+	msim_send_attention,   /* send_attention */
+	msim_attention_types,  /* attention_types */
+#else
 	NULL,               /* _purple_reserved1 */
 	NULL,               /* _purple_reserved2 */
+#endif
 	NULL,               /* _purple_reserved3 */
 	NULL                /* _purple_reserved4 */
 };
--- a/libpurple/protocols/myspace/myspace.h	Mon Aug 13 03:58:49 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.h	Mon Aug 13 06:00:06 2007 +0000
@@ -67,6 +67,9 @@
  * you want to actually use the plugin! */
 /*#define MSIM_SELF_TEST            */
 
+/* Use the attention API for zaps? */
+#define MSIM_USE_ATTENTION_API
+
 /* Constants */
 
 /* Maximum length of a password that is acceptable. This is the limit
@@ -231,6 +234,9 @@
 gboolean msim_load(PurplePlugin *plugin);
 GList *msim_status_types(PurpleAccount *acct);
 
+GList *msim_attention_types(PurpleAccount *acct);
+gboolean msim_send_attention(PurpleConnection *gc, gchar *username, guint code);
+
 GList *msim_blist_node_menu(PurpleBlistNode *node);
 
 const gchar *msim_list_icon(PurpleAccount *acct, PurpleBuddy *buddy);
--- a/libpurple/prpl.h	Mon Aug 13 03:58:49 2007 +0000
+++ b/libpurple/prpl.h	Mon Aug 13 06:00:06 2007 +0000
@@ -91,6 +91,18 @@
 	gboolean secret;
 };
 
+typedef struct _PurpleAttentionType PurpleAttentionType;
+
+/** A type of "attention" message (zap, nudge, buzz, etc. depending on the
+ * protocol) that can be sent and received. */
+struct _PurpleAttentionType {
+	PurpleStoredImage *icon;
+	const gchar *description;		/**< Shown before sending. */
+	const gchar *incoming_description;	/**< Shown when sent. */
+	const gchar *outgoing_description;	/**< Shown when received. */
+};
+
+
 /**
  * Protocol options
  *
@@ -324,8 +336,10 @@
 	/* room list serialize */
 	char *(*roomlist_room_serialize)(PurpleRoomlistRoom *room);
 
-	void (*_purple_reserved1)(void);
-	void (*_purple_reserved2)(void);
+	/* Attention API, for sending zaps/nudges/buzzes */
+	gboolean (*send_attention)(PurpleConnection *gc, gchar *username, guint type);
+	GList *(*attention_types)(PurpleAccount *acct);
+
 	void (*_purple_reserved3)(void);
 	void (*_purple_reserved4)(void);
 };
--- a/libpurple/server.c	Mon Aug 13 03:58:49 2007 +0000
+++ b/libpurple/server.c	Mon Aug 13 06:00:06 2007 +0000
@@ -242,6 +242,32 @@
 	}
 }
 
+/** Indicate that an attention message was sent or received. */
+void
+serv_got_attention(PurpleConnection *gc, const char *who, PurpleAttentionType *attn, gboolean incoming)
+{
+	gchar *description;
+
+	if (incoming) {
+		if (attn->incoming_description) {
+			description = g_strdup_printf(_("Attention! You have been %s."), attn->incoming_description);
+		} else {
+			description = g_strdup(_("Attention!"));
+		}
+	} else {
+		if (attn->outgoing_description) {
+			description = g_strdup_printf(_("Attention! %s %s."), attn->outgoing_description, who);
+		} else {
+			description = g_strdup(_("Attention!"));
+		}
+	}
+
+	serv_got_im(gc, who, description, PURPLE_MESSAGE_SYSTEM |
+			(incoming ? PURPLE_MESSAGE_RECV : PURPLE_MESSAGE_SEND), time(NULL));
+
+	g_free(description);
+}
+
 /*
  * Move a buddy from one group to another on server.
  *
--- a/libpurple/server.h	Mon Aug 13 03:58:49 2007 +0000
+++ b/libpurple/server.h	Mon Aug 13 06:00:06 2007 +0000
@@ -67,6 +67,7 @@
 int  serv_chat_send(PurpleConnection *, int, const char *, PurpleMessageFlags flags);
 void serv_alias_buddy(PurpleBuddy *);
 void serv_got_alias(PurpleConnection *gc, const char *who, const char *alias);
+void serv_got_attention(PurpleConnection *gc, const char *who, PurpleAttentionType *attn, gboolean incoming);
 
 /**
  * Receive a typing message from a remote user.  Either PURPLE_TYPING