# HG changeset patch # User Jeffrey Connelly # Date 1188178581 0 # Node ID 1b5e786d137aed21c0a4ee8d9bf34b019639f38f # Parent e5f73cebcb36376990d86ec981bea3bb8a39ab0c 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 diff -r e5f73cebcb36 -r 1b5e786d137a libpurple/conversation.c --- 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, diff -r e5f73cebcb36 -r 1b5e786d137a libpurple/protocols/myspace/zap.c --- 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, diff -r e5f73cebcb36 -r 1b5e786d137a libpurple/prpl.h --- 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; }; /** diff -r e5f73cebcb36 -r 1b5e786d137a libpurple/server.c --- 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); } diff -r e5f73cebcb36 -r 1b5e786d137a libpurple/server.h --- 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