Mercurial > pidgin.yaz
diff libpurple/protocols/oscar/oscar.c @ 29812:365b90fa23cf
This patch comes from the combined work of contributors minstrel, NightFox,
bob007, salieff, and nops (these are their trac usernames). I have made
some minor tweaks to the patch, but these shouldn't be a problem. This patch
needs some TLC before we can merge it anywhere else; it adds API so it must
hit im.pidgin.pidgin.next.minor before hitting im.pidgin.pidgin. Refs #4508.
author | John Bailey <rekkanoryo@rekkanoryo.org> |
---|---|
date | Thu, 13 Nov 2008 17:04:53 +0000 |
parents | dd787f8d5e91 |
children | 297d83036107 |
line wrap: on
line diff
--- a/libpurple/protocols/oscar/oscar.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/oscar/oscar.c Thu Nov 13 17:04:53 2008 +0000 @@ -59,6 +59,11 @@ #define OSCAR_STATUS_ID_NA "na" #define OSCAR_STATUS_ID_OCCUPIED "occupied" #define OSCAR_STATUS_ID_FREE4CHAT "free4chat" +#define OSCAR_STATUS_ID_EVIL "evil" +#define OSCAR_STATUS_ID_DEPRESSION "depression" +#define OSCAR_STATUS_ID_ATHOME "athome" +#define OSCAR_STATUS_ID_ATWORK "atwork" +#define OSCAR_STATUS_ID_LUNCH "lunch" #define OSCAR_STATUS_ID_CUSTOM "custom" #define OSCAR_STATUS_ID_MOBILE "mobile" @@ -68,7 +73,7 @@ static OscarCapability purple_caps = (OSCAR_CAPABILITY_CHAT | OSCAR_CAPABILITY_BUDDYICON | OSCAR_CAPABILITY_DIRECTIM | OSCAR_CAPABILITY_SENDFILE | OSCAR_CAPABILITY_UNICODE | OSCAR_CAPABILITY_INTEROPERATE | - OSCAR_CAPABILITY_SHORTCAPS); + OSCAR_CAPABILITY_SHORTCAPS | OSCAR_CAPABILITY_ICQSERVERRELAY | OSCAR_CAPABILITY_NEWCAPS | OSCAR_CAPABILITY_XTRAZ); static guint8 features_aim[] = {0x01, 0x01, 0x01, 0x02}; static guint8 features_icq[] = {0x01, 0x06}; @@ -670,6 +675,9 @@ case OSCAR_CAPABILITY_GAMES: case OSCAR_CAPABILITY_GAMES2: tmp = _("Games"); + case OSCAR_CAPABILITY_XTRAZ: + case OSCAR_CAPABILITY_NEWCAPS: + tmp = _("ICQ Xtraz"); break; case OSCAR_CAPABILITY_ADDINS: tmp = _("Add-Ins"); @@ -750,9 +758,17 @@ return g_strdup_printf(_("Away")); else if (state & AIM_ICQ_STATE_WEBAWARE) return g_strdup_printf(_("Web Aware")); - else if (state & AIM_ICQ_STATE_INVISIBLE) - return g_strdup_printf(_("Invisible")); - else + else if (state & AIM_ICQ_STATE_EVIL) + return g_strdup_printf(_("Evil")); + else if (state & AIM_ICQ_STATE_DEPRESSION) + return g_strdup_printf(_("Depression")); + else if (state & AIM_ICQ_STATE_ATHOME) + return g_strdup_printf(_("At home")); + else if (state & AIM_ICQ_STATE_ATWORK) + return g_strdup_printf(_("At work")); + else if (state & AIM_ICQ_STATE_LUNCH) + return g_strdup_printf(_("At lunch")); + else return g_strdup_printf(_("Online")); } @@ -1992,6 +2008,16 @@ status_id = OSCAR_STATUS_ID_AWAY; else if (type & AIM_ICQ_STATE_INVISIBLE) status_id = OSCAR_STATUS_ID_INVISIBLE; + else if (type & AIM_ICQ_STATE_EVIL) + status_id = OSCAR_STATUS_ID_EVIL; + else if (type & AIM_ICQ_STATE_DEPRESSION) + status_id = OSCAR_STATUS_ID_DEPRESSION; + else if (type & AIM_ICQ_STATE_ATHOME) + status_id = OSCAR_STATUS_ID_ATHOME; + else if (type & AIM_ICQ_STATE_ATWORK) + status_id = OSCAR_STATUS_ID_ATWORK; + else if (type & AIM_ICQ_STATE_LUNCH) + status_id = OSCAR_STATUS_ID_LUNCH; else status_id = OSCAR_STATUS_ID_AVAILABLE; } else { @@ -2308,7 +2334,9 @@ { PurpleConnection *gc; PurpleAccount *account; + PurpleMessageFlags flags = 0; char *message = NULL; + char *rtfmsg = NULL; g_return_val_if_fail(od != NULL, 0); g_return_val_if_fail(od->gc != NULL, 0); @@ -2338,6 +2366,21 @@ } } + + if (args->info.rtfmsg.rtfmsg != NULL) + { + if (args->encoding != NULL) + { + char *encoding = NULL; + encoding = oscar_encoding_extract(args->encoding); + rtfmsg = oscar_encoding_to_utf8(account, encoding, args->info.rtfmsg.rtfmsg, + strlen(args->info.rtfmsg.rtfmsg)); + g_free(encoding); + } else { + if (g_utf8_validate(args->info.rtfmsg.rtfmsg, strlen(args->info.rtfmsg.rtfmsg), NULL)) + rtfmsg = g_strdup(args->info.rtfmsg.rtfmsg); + } + } if (args->type & OSCAR_CAPABILITY_CHAT) { char *encoding, *utf8name, *tmp; @@ -2425,6 +2468,21 @@ { purple_debug_error("oscar", "Got an ICQ Server Relay message of " "type %d\n", args->info.rtfmsg.msgtype); + purple_debug_error("oscar", "Sending X-Status Reply\n"); + + if(args->info.rtfmsg.msgtype == 26) + icq_relay_xstatus(od, userinfo->sn, args->cookie); + + if(args->info.rtfmsg.msgtype == 1) + { + if(rtfmsg) + serv_got_im(gc, userinfo->sn, rtfmsg, flags, + time(NULL)); + else + serv_got_im(gc, userinfo->sn, args->info.rtfmsg.rtfmsg, flags, + time(NULL)); + + } } else @@ -2828,7 +2886,6 @@ args = va_arg(ap, struct aim_incomingim_ch4_args *); ret = incomingim_chan4(od, conn, userinfo, args, 0); } break; - default: { purple_debug_warning("oscar", "ICBM received on unsupported channel (channel " @@ -2976,6 +3033,28 @@ } break; + case 0x0006: { /* Reply from an ICQ status message request */ + char *statusmsg, **splitmsg; + PurpleNotifyUserInfo *user_info; + + /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ + statusmsg = oscar_icqstatus(state); + splitmsg = g_strsplit(msg, "\r\n", 0); + + user_info = purple_notify_user_info_new(); + + purple_notify_user_info_add_pair(user_info, _("UIN"), who); + purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg); + purple_notify_user_info_add_section_break(user_info); + purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("<BR>", splitmsg)); + + g_free(statusmsg); + g_strfreev(splitmsg); + + purple_notify_userinfo(gc, who, user_info, NULL, NULL); + purple_notify_user_info_destroy(user_info); + + } break; default: { purple_debug_warning("oscar", "Received an unknown client auto-response from %s. " @@ -4629,10 +4708,22 @@ data |= AIM_ICQ_STATE_CHAT; else if (!strcmp(status_id, OSCAR_STATUS_ID_INVISIBLE)) data |= AIM_ICQ_STATE_INVISIBLE; + else if (!strcmp(status_id, OSCAR_STATUS_ID_EVIL)) + data |= AIM_ICQ_STATE_EVIL; + else if (!strcmp(status_id, OSCAR_STATUS_ID_DEPRESSION)) + data |= AIM_ICQ_STATE_DEPRESSION; + else if (!strcmp(status_id, OSCAR_STATUS_ID_ATWORK)) + data |= AIM_ICQ_STATE_ATWORK; + else if (!strcmp(status_id, OSCAR_STATUS_ID_ATHOME)) + data |= AIM_ICQ_STATE_ATHOME; + else if (!strcmp(status_id, OSCAR_STATUS_ID_LUNCH)) + data |= AIM_ICQ_STATE_LUNCH; else if (!strcmp(status_id, OSCAR_STATUS_ID_CUSTOM)) data |= AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY; + aim_srv_setextrainfo(od, TRUE, data, FALSE, NULL, NULL); + } static void @@ -5777,6 +5868,7 @@ return "secure"; if (userinfo->icqinfo.status & AIM_ICQ_STATE_BIRTHDAY) return "birthday"; + return aim_get_custom_icon_filename(userinfo->customicon); } return NULL; } @@ -5998,9 +6090,53 @@ purple_value_new(PURPLE_TYPE_STRING), NULL); status_types = g_list_prepend(status_types, type); - type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, OSCAR_STATUS_ID_FREE4CHAT, - _("Free For Chat"), TRUE, is_icq, FALSE); + _("Free For Chat"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + + status_types = g_list_prepend(status_types, type); + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_EVIL, + _("Evil"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_DEPRESSION, + _("Depression"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_ATHOME, + _("At home"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_ATWORK, + _("At work"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_LUNCH, + _("Lunch"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, @@ -6010,9 +6146,12 @@ purple_value_new(PURPLE_TYPE_STRING), NULL); status_types = g_list_prepend(status_types, type); - type = purple_status_type_new_full(PURPLE_STATUS_INVISIBLE, + type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE, OSCAR_STATUS_ID_INVISIBLE, - NULL, TRUE, TRUE, FALSE); + NULL, TRUE, TRUE, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); type = purple_status_type_new_full(PURPLE_STATUS_MOBILE, OSCAR_STATUS_ID_MOBILE, NULL, FALSE, FALSE, TRUE); @@ -6180,6 +6319,23 @@ aim_locate_getinfoshort(gc->proto_data, purple_buddy_get_name(buddy), 0x00000003); } +static void oscar_get_icqxstatusmsg (PurpleBlistNode *node, gpointer ignore) +{ + PurpleBuddy *buddy; + PurpleConnection *gc; + PurpleAccount *account; + + + g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); + + buddy = (PurpleBuddy *)node; + gc = purple_account_get_connection(buddy->account); + account = purple_connection_get_account(gc); + purple_debug_info("oscar", "Manual X-Status Get From %s to %s:\n", purple_buddy_get_name(buddy), account->username); + + icq_im_xstatus_request(gc->proto_data, purple_buddy_get_name(buddy)); +} + static GList * oscar_buddy_menu(PurpleBuddy *buddy) { @@ -6207,15 +6363,14 @@ NULL, NULL); menu = g_list_prepend(menu, act); -#if 0 if (od->icq) { - act = purple_menu_action_new(_("Get Status Msg"), - PURPLE_CALLBACK(oscar_get_icqstatusmsg), + act = purple_menu_action_new(_("Get X-Status Msg"), + PURPLE_CALLBACK(oscar_get_icqxstatusmsg), NULL, NULL); menu = g_list_prepend(menu, act); } -#endif + if (userinfo && aim_sncmp(purple_account_get_username(buddy->account), buddy->name) && @@ -6599,6 +6754,79 @@ purple_xfer_request(xfer); } +static void +oscar_show_icq_custom_icons_cb(PurpleConnection *gc, PurpleRequestFields *fields) { + OscarData *od = gc->proto_data; + PurpleAccount *account = purple_connection_get_account(gc); + PurpleRequestField *f; + GList *l; + + f = purple_request_fields_get_field(fields, "customicon"); + l = purple_request_field_list_get_selected(f); + + if (l) { + gpointer d = purple_request_field_list_get_data(f, l->data); + purple_account_set_int(account, "customicon", GPOINTER_TO_INT(d)); + } + + aim_locate_setcaps(od, purple_caps); +} + +static void +oscar_show_icq_custom_icons(PurplePluginAction *action) +{ + guint32 i; + gint32 customicon; + PurpleConnection *gc = (PurpleConnection *) action->context; + PurpleAccount *account = purple_connection_get_account(gc); + PurpleRequestFields *fields; + PurpleRequestFieldGroup *g; + PurpleRequestField *f; + char* na_fn; + + customicon = purple_account_get_int(account, "customicon", 0); + + fields = purple_request_fields_new(); + + g = purple_request_field_group_new(NULL); + + f = purple_request_field_list_new("customicon", _("XStatus")); + + purple_request_field_list_set_pixbuf(f, TRUE); + + na_fn = g_build_filename("pixmaps", "pidgin", "emblems", "16", "not-authorized.png", NULL); + + purple_request_field_list_add_icon(f, _("None"), na_fn, GINT_TO_POINTER(-1)); + if (customicon == 0) + purple_request_field_list_add_selected(f, _("None")); + + g_free(na_fn); + + for (i = 1; i < aim_get_custom_icons_count(); i++) { + char* icon_path = g_strdup_printf("%s.png", aim_get_custom_icon_filename(i)); + char* filename = g_build_filename("pixmaps", "pidgin", "emblems", "16", icon_path, NULL); + + purple_request_field_list_add_icon(f, _(aim_get_custom_icon_descriptivename(i)), filename, GINT_TO_POINTER(i)); + + if (customicon == i) + purple_request_field_list_add_selected(f, _(aim_get_custom_icon_descriptivename(i))); + + g_free(filename); + g_free(icon_path); + } + purple_request_field_group_add_field(g, f); + + purple_request_fields_add_group(fields, g); + + purple_request_fields(gc, _("Set Custom Icon"), _("Set Custom Icon"), + NULL, fields, + _("OK"), G_CALLBACK(oscar_show_icq_custom_icons_cb), + _("Cancel"), NULL, + purple_connection_get_account(gc), NULL, NULL, + gc); +} + + GList * oscar_actions(PurplePlugin *plugin, gpointer context) { @@ -6641,6 +6869,10 @@ act = purple_plugin_action_new(_("Set Privacy Options..."), oscar_show_icq_privacy_opts); menu = g_list_prepend(menu, act); + + act = purple_plugin_action_new(_("Set Custom Icon..."), + oscar_show_icq_custom_icons); + menu = g_list_prepend(menu, act); } else {