# HG changeset patch # User John Bailey # Date 1273791060 0 # Node ID eafb928fe61452c6a56befb5d37384f3bb146713 # Parent 129f973c38b535cc52eb8a9b9beb73c1ca94441f# Parent 478a75d3100fb5f27127f8cc239cfc64c0786ab0 propagate from branch 'im.pidgin.pidgin.mxit' (head ad23bba01aa6026230a0aa76ea2e27d0dfb5c106) to branch 'im.pidgin.pidgin' (head 54b2ac9fc179bd46065882041bbaa7b4b6bafce6) diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/actions.c --- a/libpurple/protocols/mxit/actions.c Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/actions.c Thu May 13 22:51:00 2010 +0000 @@ -35,89 +35,6 @@ #include "profile.h" -/* MXit Moods */ -static const char* moods[] = { - /* 0 */ N_("None"), - /* 1 */ N_("Angry"), - /* 2 */ N_("Excited"), - /* 3 */ N_("Grumpy"), - /* 4 */ N_("Happy"), - /* 5 */ N_("In Love"), - /* 6 */ N_("Invincible"), - /* 7 */ N_("Sad"), - /* 8 */ N_("Hot"), - /* 9 */ N_("Sick"), - /* 10 */ N_("Sleepy") -}; - - -/*------------------------------------------------------------------------ - * The user has selected to change their current mood. - * - * @param gc The connection object - * @param fields The fields from the request pop-up - */ -static void mxit_cb_set_mood( PurpleConnection* gc, PurpleRequestFields* fields ) -{ - struct MXitSession* session = (struct MXitSession*) gc->proto_data; - int mood = purple_request_fields_get_choice( fields, "mood" ); - - purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_set_mood (%i)\n", mood ); - - if ( !PURPLE_CONNECTION_IS_VALID( gc ) ) { - purple_debug_error( MXIT_PLUGIN_ID, "Unable to set mood; account offline.\n" ); - return; - } - - /* Save the new mood in session */ - session->mood = mood; - - /* now send the update to MXit */ - mxit_send_mood( session, mood ); -} - - -/*------------------------------------------------------------------------ - * Create and display the mood selection window to the user. - * - * @param action The action object - */ -static void mxit_cb_action_mood( PurplePluginAction* action ) -{ - PurpleConnection* gc = (PurpleConnection*) action->context; - struct MXitSession* session = (struct MXitSession*) gc->proto_data; - - PurpleRequestFields* fields = NULL; - PurpleRequestFieldGroup* group = NULL; - PurpleRequestField* field = NULL; - unsigned int i = 0; - - purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_action_mood\n" ); - - fields = purple_request_fields_new(); - group = purple_request_field_group_new( NULL ); - purple_request_fields_add_group( fields, group ); - - /* show current mood */ - field = purple_request_field_string_new( "current", _( "Current Mood" ), _( moods[session->mood] ), FALSE ); - purple_request_field_string_set_editable( field, FALSE ); /* current mood field is not editable */ - purple_request_field_group_add_field( group, field ); - - /* add all moods to list */ - field = purple_request_field_choice_new( "mood", _( "New Mood" ), 0 ); - for ( i = 0; i < ARRAY_SIZE( moods ); i++ ) { - purple_request_field_choice_add( field, _( moods[i] ) ); - } - purple_request_field_set_required( field, TRUE ); - purple_request_field_choice_set_default_value( field, session->mood ); - purple_request_field_group_add_field( group, field ); - - /* (reference: "libpurple/request.h") */ - purple_request_fields( gc, _( "Mood" ), _( "Change your Mood" ), _( "How do you feel right now?" ), fields, _( "Set" ), - G_CALLBACK( mxit_cb_set_mood ), _( "Cancel" ), NULL, purple_connection_get_account( gc ), NULL, NULL, gc ); -} - - /*------------------------------------------------------------------------ * The user has selected to change their profile. * @@ -409,10 +326,6 @@ PurplePluginAction* action = NULL; GList* m = NULL; - /* display / change mood */ - action = purple_plugin_action_new( _( "Change Mood..." ), mxit_cb_action_mood ); - m = g_list_append( m, action ); - /* display / change profile */ action = purple_plugin_action_new( _( "Change Profile..." ), mxit_cb_action_profile ); m = g_list_append( m, action ); diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/login.c --- a/libpurple/protocols/mxit/login.c Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/login.c Thu May 13 22:51:00 2010 +0000 @@ -67,7 +67,7 @@ /* configure the connection (reference: "libpurple/connection.h") */ con = purple_account_get_connection( account ); con->proto_data = session; - con->flags |= PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_HTML; + con->flags |= PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_SUPPORT_MOODS; session->con = con; /* add account */ diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/multimx.c --- a/libpurple/protocols/mxit/multimx.c Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/multimx.c Thu May 13 22:51:00 2010 +0000 @@ -142,6 +142,10 @@ multimx->chatid = groupchatID++; multimx->state = state; + /* determine our nickname (from profile) */ + if (session->profile && (session->profile->nickname[0] != '\0')) + multimx->nickname = g_strdup(session->profile->nickname); + /* Add to GroupChat list */ session->rooms = g_list_append(session->rooms, multimx); @@ -160,6 +164,10 @@ /* Remove from GroupChat list */ session->rooms = g_list_remove(session->rooms, multimx); + /* free nickname */ + if (multimx->nickname) + g_free(multimx->nickname); + /* Deallocate it */ free (multimx); multimx = NULL; @@ -213,6 +221,38 @@ /*------------------------------------------------------------------------ + * A user was kicked from the GroupChat. + * + * @param session The MXit session object + * @param multimx The MultiMX room object + * @param nickname The nickname of the user who was kicked + */ +static void member_kicked(struct MXitSession* session, struct multimx* multimx, const char* nickname) +{ + PurpleConversation *convo; + + purple_debug_info(MXIT_PLUGIN_ID, "member_kicked: '%s'\n", nickname); + + convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc); + if (convo == NULL) { + purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname); + return; + } + + /* who was kicked? - compare to our original nickname */ + if (purple_utf8_strcasecmp(nickname, multimx->nickname) == 0) + { + /* you were kicked */ + purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "MXit", _("You have been kicked from this MultiMX."), PURPLE_MESSAGE_SYSTEM, time(NULL)); + purple_conv_chat_clear_users(PURPLE_CONV_CHAT(convo)); + serv_got_chat_left(session->con, multimx->chatid); + } + else + purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, _("was kicked")); +} + + +/*------------------------------------------------------------------------ * Update the full GroupChat member list. * * @param session The MXit session object @@ -375,6 +415,12 @@ member_removed(mx->session, multimx, msg); mx->processed = TRUE; } + else if ((ofs = strstr(msg, " has been kicked")) != NULL) { + /* Somebody has been kicked */ + *ofs = '\0'; + member_kicked(mx->session, multimx, msg); + mx->processed = TRUE; + } else if (g_str_has_prefix(msg, "The following users are in this MultiMx:") == TRUE) { member_update(mx->session, multimx, msg + strlen("The following users are in this MultiMx:") + 1); mx->processed = TRUE; @@ -582,8 +628,8 @@ mxit_send_message(session, multimx->roomid, message, TRUE, FALSE); /* Determine our nickname to display */ - if (session->profile && (session->profile->nickname[0] != '\0')) /* default is profile name (since that's what everybody else sees) */ - nickname = session->profile->nickname; + if (multimx->nickname) + nickname = multimx->nickname; else nickname = purple_account_get_alias(purple_connection_get_account(gc)); /* local alias */ diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/multimx.h --- a/libpurple/protocols/mxit/multimx.h Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/multimx.h Thu May 13 22:51:00 2010 +0000 @@ -41,6 +41,7 @@ char roomname[MXIT_CP_MAX_ALIAS_LEN]; /* name of the room */ char roomid[MXIT_CP_MAX_JID_LEN]; /* internal JID for room */ int chatid; /* libpurple chat ID */ + char* nickname; /* our nickname in the room */ short state; /* state */ }; diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/mxit.c --- a/libpurple/protocols/mxit/mxit.c Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/mxit.c Thu May 13 22:51:00 2010 +0000 @@ -92,6 +92,9 @@ goto skip; con = purple_account_get_connection( account ); +// /* determine if it's a command-response to send */ +// is_command = g_str_has_prefix( parts[4], "::type=reply|" ); + /* send click message back to MXit */ mxit_send_message( con->proto_data, parts[3], parts[4], FALSE, is_command ); @@ -418,6 +421,24 @@ char* statusmsg1; char* statusmsg2; + /* Handle mood changes */ + if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) { + const char* moodid = purple_status_get_attr_string( status, PURPLE_MOOD_NAME ); + int mood; + + /* convert the purple mood to a mxit mood */ + mood = mxit_convert_mood( moodid ); + if ( mood < 0 ) { + /* error, mood not found */ + purple_debug_info( MXIT_PLUGIN_ID, "Mood status NOT found! (id = %s)\n", moodid ); + return; + } + + /* update mood state */ + mxit_send_mood( session, mood ); + return; + } + /* get the status id (reference: "libpurple/status.h") */ statusid = purple_status_get_id( status ); @@ -635,7 +656,7 @@ mxit_get_text_table, /* get_account_text_table */ NULL, /* initiate_media */ NULL, /* get_media_caps */ - NULL, /* get_moods */ + mxit_get_moods, /* get_moods */ NULL, /* set_public_alias */ NULL /* get_public_alias */ }; diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/mxit.h --- a/libpurple/protocols/mxit/mxit.h Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/mxit.h Thu May 13 22:51:00 2010 +0000 @@ -151,7 +151,6 @@ /* personal (profile) */ struct MXitProfile* profile; /* user's profile information */ - int mood; /* user's current mood */ /* libpurple */ PurpleAccount* acc; /* pointer to the libpurple internal account struct */ diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/protocol.c --- a/libpurple/protocols/mxit/protocol.c Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/protocol.c Thu May 13 22:51:00 2010 +0000 @@ -962,6 +962,31 @@ /*------------------------------------------------------------------------ + * Send a message event packet. + * + * @param session The MXit session object + * @param to The username of the original sender (ie, recipient of the event) + * @param id The identifier of the event (received in message) + * @param event Identified the type of event + */ +void mxit_send_msgevent( struct MXitSession* session, const char* to, const char* id, int event) +{ + char data[CP_MAX_PACKET]; + int datalen; + + purple_debug_info( MXIT_PLUGIN_ID, "mxit_send_msgevent: to=%s id=%s event=%i\n", to, id, event ); + + /* convert the packet to a byte stream */ + datalen = sprintf( data, "ms=%s%c%s%c%i", /* "ms"=contactAddress \1 id \1 event */ + to, CP_FLD_TERM, id, CP_FLD_TERM, event + ); + + /* queue packet for transmission */ + mxit_queue_packet( session, data, datalen, CP_CMD_MSGEVENT ); +} + + +/*------------------------------------------------------------------------ * Send packet to create a MultiMX room. * * @param session The MXit session object @@ -1355,6 +1380,12 @@ return; } + if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) { + /* delivery notification is requested */ + if ( records[0]->fcount >= 4 ) + mxit_send_msgevent( session, records[0]->fields[0]->data, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED ); + } + /* create and initialise new markup struct */ mx = g_new0( struct RXMsgData, 1 ); mx->msg = g_string_sized_new( msglen ); @@ -1917,6 +1948,8 @@ /* profile update */ case CP_CMD_SPLASHCLICK : /* splash-screen clickthrough */ + case CP_CMD_MSGEVENT : + /* event message */ break; default : @@ -2020,6 +2053,7 @@ mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Profile Error" ), _( errdesc ) ); break; case CP_CMD_SPLASHCLICK : + case CP_CMD_MSGEVENT : /* ignore error */ break; case CP_CMD_PING : diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/protocol.h --- a/libpurple/protocols/mxit/protocol.h Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/protocol.h Thu May 13 22:51:00 2010 +0000 @@ -72,6 +72,9 @@ #define MXIT_CF_EXT_MARKUP 0x040000 #define MXIT_CF_PLAIN_PWD 0x080000 #define MXIT_CF_NO_GATEWAYS 0x100000 +#define MXIT_CF_NO_AVATARS 0x200000 +#define MXIT_CF_GAMING 0x400000 +#define MXIT_CF_GAMING_UPDATE 0x800000 /* Client features supported by this implementation */ #define MXIT_CP_FEATURES ( MXIT_CF_FILE_TRANSFER | MXIT_CF_FILE_ACCESS | MXIT_CF_AUDIO | MXIT_CF_MARKUP | MXIT_CF_EXT_MARKUP | MXIT_CF_NO_GATEWAYS | MXIT_CF_IMAGES | MXIT_CF_COMMANDS | MXIT_CF_VIBES | MXIT_CF_MIDP2 ) @@ -126,6 +129,7 @@ #define CP_CMD_MEDIA 0x001B /* (27) get multimedia message */ #define CP_CMD_SPLASHCLICK 0x001F /* (31) splash-screen clickthrough */ #define CP_CMD_STATUS 0x0020 /* (32) set shown presence & status */ +#define CP_CMD_MSGEVENT 0x0023 /* (35) Raise message event */ #define CP_CMD_MOOD 0x0029 /* (41) set mood */ #define CP_CMD_KICK 0x002B /* (43) login kick */ #define CP_CMD_GRPCHAT_CREATE 0x002C /* (44) create new groupchat */ @@ -147,6 +151,8 @@ #define RX_STATE_PROC 0x03 /* process read data */ /* message flags */ +#define CP_MSG_NOTIFY_DELIVERY 0x0002 /* request delivery notification */ +#define CP_MSG_NOTIFY_READ 0x0004 /* request read notification */ #define CP_MSG_ENCRYPTED 0x0010 /* message is encrypted */ #define CP_MSG_MARKUP 0x0200 /* message may contain markup */ #define CP_MSG_EMOTICON 0x0400 /* message may contain custom emoticons */ @@ -164,6 +170,9 @@ #define CP_MSGTYPE_FORM 0x06 /* mxit custom form */ #define CP_MSGTYPE_COMMAND 0x07 /* mxit command */ +/* message event types */ +#define CP_MSGEVENT_DELIVERED 0x02 /* message was delivered */ +#define CP_MSGEVENT_DISPLAYED 0x04 /* message was viewed */ /* extended profile attribute fields */ #define CP_PROFILE_BIRTHDATE "birthdate" /* Birthdate (String - ISO 8601 format) */ @@ -284,6 +293,7 @@ void mxit_send_deny_sub( struct MXitSession* session, const char* username ); void mxit_send_update_contact( struct MXitSession* session, const char* username, const char* alias, const char* groupname ); void mxit_send_splashclick( struct MXitSession* session, const char* splashid ); +void mxit_send_msgevent( struct MXitSession* session, const char* to, const char* id, int event); void mxit_send_file( struct MXitSession* session, const char* username, const char* filename, const unsigned char* buf, int buflen ); void mxit_send_file_reject( struct MXitSession* session, const char* fileid ); diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/roster.c --- a/libpurple/protocols/mxit/roster.c Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/roster.c Thu May 13 22:51:00 2010 +0000 @@ -81,6 +81,12 @@ statuslist = g_list_append( statuslist, type ); } + /* add Mood option */ + type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD, "mood", NULL, FALSE, TRUE, TRUE, + PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new( PURPLE_TYPE_STRING ), + NULL); + statuslist = g_list_append( statuslist, type ); + return statuslist; } @@ -127,6 +133,57 @@ * Moods */ +/* moods (reference: libpurple/status.h) */ +static PurpleMood mxit_moods[] = { + {"angry", N_("Angry"), NULL}, + {"excited", N_("Excited"), NULL}, + {"grumpy", N_("Grumpy"), NULL}, + {"happy", N_("Happy"), NULL}, + {"in_love", N_("In love"), NULL}, + {"invincible", N_("Invincible"), NULL}, + {"sad", N_("Sad"), NULL}, + {"hot", N_("Hot"), NULL}, + {"sick", N_("Sick"), NULL}, + {"sleepy", N_("Sleepy"), NULL}, + /* Mark the last record. */ + { NULL, NULL, NULL } +}; + + +/*------------------------------------------------------------------------ + * Returns the MXit mood code, given the unique mood ID. + * + * @param id The mood ID + * @return The MXit mood code + */ +int mxit_convert_mood( const char* id ) +{ + unsigned int i; + + /* Mood is being unset */ + if ( id == NULL ) + return MXIT_MOOD_NONE; + + for ( i = 0; i < ARRAY_SIZE( mxit_moods ) - 1; i++ ) { + if ( strcmp( mxit_moods[i].mood, id ) == 0 ) /* mood found! */ + return i + 1; /* because MXIT_MOOD_NONE is 0 */ + } + + return -1; +} + + +/*------------------------------------------------------------------------ + * Return the list of MXit-supported moods. + * + * @param account The MXit account object + */ +PurpleMood* mxit_get_moods(PurpleAccount *account) +{ + return mxit_moods; +} + + /*------------------------------------------------------------------------ * Returns the MXit mood as a string, given the MXit mood's ID. * @@ -259,6 +316,12 @@ else purple_prpl_got_user_status( session->acc, newbuddy->name, mxit_statuses[contact->presence].id, NULL ); + /* update the buddy's mood */ + if ( contact->mood == MXIT_MOOD_NONE ) + purple_prpl_got_user_status_deactive( session->acc, newbuddy->name, "mood" ); + else + purple_prpl_got_user_status( session->acc, newbuddy->name, "mood", PURPLE_MOOD_NAME, mxit_moods[contact->mood-1].mood, NULL ); + /* update avatar */ if ( contact->avatarId ) { mxit_get_avatar( session, newbuddy->name, contact->avatarId ); @@ -346,6 +409,12 @@ /* update the buddy's status (reference: "libpurple/prpl.h") */ purple_prpl_got_user_status( session->acc, contact->username, mxit_statuses[contact->presence].id, NULL ); + + /* update the buddy's mood */ + if ( contact->mood == MXIT_MOOD_NONE ) + purple_prpl_got_user_status_deactive( session->acc, contact->username, "mood" ); + else + purple_prpl_got_user_status( session->acc, contact->username, "mood", PURPLE_MOOD_NAME, mxit_moods[contact->mood-1].mood, NULL ); } @@ -388,6 +457,10 @@ contact->presence = presence; contact->mood = mood; + /* validate mood */ + if (( contact->mood < MXIT_MOOD_NONE ) || ( contact->mood > MXIT_MOOD_SLEEPY )) + contact->mood = MXIT_MOOD_NONE; + g_strlcpy( contact->customMood, customMood, sizeof( contact->customMood ) ); // TODO: Download custom mood frame. @@ -419,6 +492,12 @@ purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, "message", contact->statusMsg, NULL ); else purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, NULL ); + + /* update the buddy's mood */ + if ( contact->mood == MXIT_MOOD_NONE ) + purple_prpl_got_user_status_deactive( session->acc, username, "mood" ); + else + purple_prpl_got_user_status( session->acc, username, "mood", PURPLE_MOOD_NAME, mxit_moods[contact->mood-1].mood, NULL ); } diff -r 129f973c38b5 -r eafb928fe614 libpurple/protocols/mxit/roster.h --- a/libpurple/protocols/mxit/roster.h Thu May 13 22:45:19 2010 +0000 +++ b/libpurple/protocols/mxit/roster.h Thu May 13 22:51:00 2010 +0000 @@ -119,6 +119,7 @@ const char* mxit_convert_subtype_to_name( short subtype ); /* Moods */ +int mxit_convert_mood( const char* id ); const char* mxit_convert_mood_to_name( short id ); /* MXit Protocol callbacks */ @@ -134,6 +135,7 @@ void mxit_buddy_alias( PurpleConnection* gc, const char* who, const char* alias ); void mxit_buddy_group( PurpleConnection* gc, const char* who, const char* old_group, const char* new_group ); void mxit_rename_group( PurpleConnection* gc, const char* old_name, PurpleGroup* group, GList* moved_buddies ); +PurpleMood* mxit_get_moods(PurpleAccount *account); #endif /* _MXIT_ROSTER_H_ */ diff -r 129f973c38b5 -r eafb928fe614 pidgin/pixmaps/emotes/small/16/Makefile.am --- a/pidgin/pixmaps/emotes/small/16/Makefile.am Thu May 13 22:45:19 2010 +0000 +++ b/pidgin/pixmaps/emotes/small/16/Makefile.am Thu May 13 22:51:00 2010 +0000 @@ -5,7 +5,10 @@ cinema.png \ disappointed.png \ embarrassed.png \ + grumpy.png \ + hot.png \ internet.png \ + invincible.png \ music.png \ restroom.png \ search.png \ diff -r 129f973c38b5 -r eafb928fe614 pidgin/pixmaps/emotes/small/16/grumpy.png Binary file pidgin/pixmaps/emotes/small/16/grumpy.png has changed diff -r 129f973c38b5 -r eafb928fe614 pidgin/pixmaps/emotes/small/16/hot.png Binary file pidgin/pixmaps/emotes/small/16/hot.png has changed diff -r 129f973c38b5 -r eafb928fe614 pidgin/pixmaps/emotes/small/16/invincible.png Binary file pidgin/pixmaps/emotes/small/16/invincible.png has changed