# HG changeset patch # User Jeffrey Connelly # Date 1186984806 0 # Node ID 258a721f6ae9b6bd5142e1b14bebee1cc17a2007 # Parent 829b00936eef2754fc690eef41180d7651e6c1fa# Parent 0f46f13c080597db7db3e1c662889b5d12b56dd9 merge of '639773488963c6e7b2de9d73d6ee3abe3b3c51b1' and 'b888bc5c0494c9dd0398baba81e4d602ac88948f' diff -r 829b00936eef -r 258a721f6ae9 libpurple/protocols/myspace/myspace.c --- 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 ) 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 */ }; diff -r 829b00936eef -r 258a721f6ae9 libpurple/protocols/myspace/myspace.h --- 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); diff -r 829b00936eef -r 258a721f6ae9 libpurple/prpl.h --- 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); }; diff -r 829b00936eef -r 258a721f6ae9 libpurple/server.c --- 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. * diff -r 829b00936eef -r 258a721f6ae9 libpurple/server.h --- 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