changeset 19461:1b5e786d137a

In the attention API, use the PURPLE_NOTIFY_MESSAGE flag to serv_got_im() instead of manually writing to the conversation window, as suggested by sadrul at http://pidgin.im/pipermail/devel/2007-August/002935.html. Yahoo and MSN already use this flag to indicate an attention/notify-type message. Also split off half of serv_got_attention() into serv_send_attention(), see http://pidgin.im/pipermail/devel/2007-August/002940.html. Now the attention API integrates well with the patch to add PURPLE_MESSAGE_NOTIFY at http://hiks.net/drop/adium/libgaim.diff. See also: https://sourceforge.net/tracker/?func=detail&atid=300235&aid=1672389&group_id=235
author Jeffrey Connelly <jaconnel@calpoly.edu>
date Mon, 27 Aug 2007 01:36:21 +0000
parents e5f73cebcb36
children 105305518622 02a57d349b5c
files libpurple/conversation.c libpurple/protocols/myspace/zap.c libpurple/prpl.h libpurple/server.c libpurple/server.h
diffstat 5 files changed, 111 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/conversation.c	Mon Aug 27 00:09:17 2007 +0000
+++ b/libpurple/conversation.c	Mon Aug 27 01:36:21 2007 +0000
@@ -2123,33 +2123,6 @@
 										PURPLE_SUBTYPE_CONVERSATION),
 						 purple_value_new(PURPLE_TYPE_UINT));
 
-	purple_signal_register(handle, "receiving-im-attention",
-						 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
-						 purple_value_new(PURPLE_TYPE_BOOLEAN), 7,
-						 purple_value_new(PURPLE_TYPE_SUBTYPE,
-										PURPLE_SUBTYPE_ACCOUNT),
-						 purple_value_new_outgoing(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_SUBTYPE,
-										PURPLE_SUBTYPE_CONVERSATION));
-
-	purple_signal_register(handle, "received-im-attention",
-						 purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
-						 NULL, 7,
-						 purple_value_new(PURPLE_TYPE_SUBTYPE,
-										PURPLE_SUBTYPE_ACCOUNT),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_STRING),
-						 purple_value_new(PURPLE_TYPE_SUBTYPE,
-										PURPLE_SUBTYPE_CONVERSATION));
-
-
 	purple_signal_register(handle, "writing-chat-msg",
 						 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_UINT,
 						 purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
--- a/libpurple/protocols/myspace/zap.c	Mon Aug 27 00:09:17 2007 +0000
+++ b/libpurple/protocols/myspace/zap.c	Mon Aug 27 01:36:21 2007 +0000
@@ -93,16 +93,20 @@
 msim_send_zap(MsimSession *session, const gchar *username, guint code)
 {
 	gchar *zap_string;
+	gboolean rc;
 #ifndef MSIM_USE_ATTENTION_API
+	GList *types;
+	MsimAttentionType *attn;
 	gchar *zap_description;
 #endif
-	GList *types;
-	MsimAttentionType *attn;
-	gboolean rc;
 
 	g_return_val_if_fail(session != NULL, FALSE);
 	g_return_val_if_fail(username != NULL, FALSE);
 
+
+#ifdef MSIM_USE_ATTENTION_API
+	serv_send_attention(session->gc, username, code);
+#else
 	types = msim_attention_types(session->account);
 
 	attn = g_list_nth_data(types, code);
@@ -111,9 +115,6 @@
 	}
 
 
-#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);
 
@@ -218,12 +219,9 @@
 {
 	gchar *msg_text, *username;
 	gint zap;
+#ifndef MSIM_USE_ATTENTION_API
 	const gchar *zap_past_tense[10];
-#ifdef MSIM_USE_ATTENTION_API
-	MsimAttentionType attn;
-#else
 	gchar *zap_text;
-#endif
 
 	zap_past_tense[0] = _("zapped");
 	zap_past_tense[1] = _("whacked");
@@ -235,6 +233,7 @@
 	zap_past_tense[7] = _("hi-fived");
 	zap_past_tense[8] = _("punk'd");
 	zap_past_tense[9] = _("raspberried");
+#endif
 
 	msg_text = msim_msg_get_string(msg, "msg");
 	username = msim_msg_get_string(msg, "_username");
@@ -244,15 +243,10 @@
 
 	g_return_val_if_fail(sscanf(msg_text, "!!!ZAP_SEND!!!=RTE_BTN_ZAPS_%d", &zap) == 1, FALSE);
 
-	zap = CLAMP(zap, 0, sizeof(zap_past_tense) / sizeof(zap_past_tense[0]));
+	zap = CLAMP(zap, 0, 9);
 
-	/* TODO:ZAP: use msim_attention_types */
 #ifdef MSIM_USE_ATTENTION_API
-	attn.incoming_description = zap_past_tense[zap];
-	attn.outgoing_description = NULL;
-	attn.icon_name = NULL;		/* TODO: icon */
-
-	serv_got_attention(session->gc, username, &attn, TRUE);
+	serv_got_attention(session->gc, username, zap);
 #else
 	zap_text = g_strdup_printf(_("*** You have been %s! ***"), zap_past_tense[zap]);
 	serv_got_im(session->gc, username, zap_text, 
--- a/libpurple/prpl.h	Mon Aug 27 00:09:17 2007 +0000
+++ b/libpurple/prpl.h	Mon Aug 27 01:36:21 2007 +0000
@@ -94,10 +94,16 @@
 
 struct _PurpleAttentionType
 {
-	const char *icon_name;             /**< Icon to display (optional) */
 	const char *name;                  /**< Shown in GUI elements */
 	const char *incoming_description;  /**< Shown when sent */
 	const char *outgoing_description;  /**< Shown when receied */
+	const char *icon_name;             /**< Icon to display (optional) */
+
+	/* Reserved fields for future purposes */
+	gpointer _reserved1;
+	gpointer _reserved2;
+	gpointer _reserved3;
+	gpointer _reserved4;
 };
 
 /**
--- a/libpurple/server.c	Mon Aug 27 00:09:17 2007 +0000
+++ b/libpurple/server.c	Mon Aug 27 01:36:21 2007 +0000
@@ -242,73 +242,87 @@
 	}
 }
 
-/** Indicate that an attention message was sent or received. */
+PurpleAttentionType *purple_get_attention_type_from_code(PurpleAccount *account, guint type_code)
+{
+	PurplePlugin *prpl;
+	PurpleAttentionType* attn;
+	GList *(*function)(PurpleAccount *);
+
+	g_return_val_if_fail(account != NULL, NULL);
+
+	prpl = purple_find_prpl(purple_account_get_protocol_id(account));
+
+	/* Lookup the attention type in the protocol's attention_types list, if any. */
+	function = PURPLE_PLUGIN_PROTOCOL_INFO(prpl)->attention_types;
+	if (function) {
+		GList *attention_types;
+
+		attention_types = function(account);
+		attn = (PurpleAttentionType *)g_list_nth_data(attention_types, type_code);
+	} else {
+		attn = NULL;
+	}
+
+	return attn;
+}
+
 void
-serv_got_attention(PurpleConnection *gc, const char *who, PurpleAttentionType *attn, gboolean incoming)
+serv_send_attention(PurpleConnection *gc, const char *who, guint type_code)
 {
-	PurpleConversation *conv;
+	PurpleAttentionType *attn;
 	PurpleMessageFlags flags;
 	gchar *description;
-	int plugin_return;
-
+	time_t mtime;
 
-	/* For incoming messages, block the attention message if requested (privacy) */
-	if (incoming) {
-		gchar *who_copy;
+	g_return_if_fail(gc != NULL);
+	g_return_if_fail(who != NULL);
+
+	mtime = time(NULL);
+
+	attn = purple_get_attention_type_from_code(gc->account, type_code);
 
-		if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->set_permit_deny == NULL)
-			if (!purple_privacy_check(gc->account, who))
-				return;
+	if (attn && attn->outgoing_description) {
+		description = g_strdup_printf(_("Attention! %s %s."), attn->outgoing_description, who);
+	} else {
+		description = g_strdup(_("Attention!"));
+	}
+	
+	flags = PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_NOTIFY | PURPLE_MESSAGE_SYSTEM;
 
-		conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, gc->account);
-
-		who_copy = g_strdup(who);
+	/* TODO: icons, sound, shaking... same as serv_got_attention(). */
 
-		plugin_return = GPOINTER_TO_INT(
-			purple_signal_emit_return_1(purple_conversations_get_handle(),
-									  "receiving-im-attention", gc->account,
-									  &who_copy, attn->icon_name, attn->name, 
-									  attn->incoming_description,
-									  attn->outgoing_description, conv));
+	serv_got_im(gc, who, description, flags, mtime);
+
+	g_free(description);
+}
 
-		if (!attn || !who_copy || plugin_return) {
-			g_free(who_copy);
-			return;
-		}
+void
+serv_got_attention(PurpleConnection *gc, const char *who, guint type_code)
+{
+	PurpleMessageFlags flags;
+	PurpleAttentionType *attn;
+	gchar *description;
+	time_t mtime;
 
-		purple_signal_emit(purple_conversations_get_handle(), "received-im-attention", gc->account,
-						 who, attn->icon_name, attn->name,
-						 attn->incoming_description, attn->outgoing_description, conv);
-	}
+	mtime = time(NULL);
 
-	/* The attention message was allowed. Create a string representing the message. */
-	flags = PURPLE_MESSAGE_SYSTEM;
+	attn = purple_get_attention_type_from_code(gc->account, type_code);
+
+	/* PURPLE_MESSAGE_NOTIFY is for attention messages. */
+	flags = PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NOTIFY | PURPLE_MESSAGE_RECV;
 
 	/* TODO: if (attn->icon_name) is non-null, use it to lookup an emoticon and display
 	 * it next to the attention command. And if it is null, display a generic icon. */
 
-	if (incoming) {
-		if (attn->incoming_description) {
-			description = g_strdup_printf(_("Attention! You have been %s."), attn->incoming_description);
-		} else {
-			description = g_strdup(_("Attention!"));
-		}
-		flags |= PURPLE_MESSAGE_RECV;
+	if (attn && attn->incoming_description) {
+		description = g_strdup_printf(_("Attention! You have been %s."), attn->incoming_description);
 	} else {
-		if (attn->outgoing_description) {
-			description = g_strdup_printf(_("Attention! %s %s."), attn->outgoing_description, who);
-		} else {
-			description = g_strdup(_("Attention!"));
-		}
-		flags |= PURPLE_MESSAGE_SEND;
+		description = g_strdup(_("Attention!"));
 	}
 
-	/* Display it in the conversation window to the user. */
-	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, gc->account);
-	if (!conv)
-		conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, gc->account, who);
-
-	purple_conv_im_write(PURPLE_CONV_IM(conv), NULL, description, flags, time(NULL));
+	serv_got_im(gc, who, description, flags, mtime);
+	
+	/* TODO: sounds (depending on PurpleAttentionType), shaking, etc. */
 
 	g_free(description);
 }
--- a/libpurple/server.h	Mon Aug 27 00:09:17 2007 +0000
+++ b/libpurple/server.h	Mon Aug 27 01:36:21 2007 +0000
@@ -53,6 +53,35 @@
 
 void serv_move_buddy(PurpleBuddy *, PurpleGroup *, PurpleGroup *);
 int  serv_send_im(PurpleConnection *, const char *, const char *, PurpleMessageFlags flags);
+
+/** Get information about an account's attention commands, from the prpl. 
+ * 
+ * @return The attention command numbered 'code' from the prpl's attention_types, or NULL.
+ */
+PurpleAttentionType *purple_get_attention_type_from_code(PurpleAccount *account, guint type_code);
+
+/** Send an attention request message.
+ *
+ * @param gc The connection to send the message on.
+ * @param who Whose attention to request.
+ * @param type An index into the prpl's attention_types list determining the type
+ * 	of the attention request command to send. 0 if prpl only defines one
+ * 	(for example, Yahoo and MSN), but some protocols define more (MySpaceIM).
+ *
+ * Note that you can't send arbitrary PurpleAttentionType's, because there is
+ * only a fixed set of attention commands.
+ */
+void serv_send_attention(PurpleConnection *gc, const char *who, guint type_code);
+
+/** Process an incoming attention message. 
+ *
+ * @param gc The connection that received the attention message.
+ * @param who Who requested your attention.
+ * @param type An index into the prpl's attention_types list determining the type
+ * 	of the attention request command to send. 
+ */
+void serv_got_attention(PurpleConnection *gc, const char *who, guint type_code);
+
 void serv_get_info(PurpleConnection *, const char *);
 void serv_set_info(PurpleConnection *, const char *);
 
@@ -67,7 +96,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, struct _PurpleAttentionType *attn, gboolean incoming);
+
 
 /**
  * Receive a typing message from a remote user.  Either PURPLE_TYPING