Mercurial > pidgin
diff src/protocols/oscar/oscar.c @ 3212:56746b0868db
[gaim-migrate @ 3229]
More OSCAR stuff from KingAnt!
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sun, 05 May 2002 19:02:08 +0000 |
parents | 5e90ecb578c5 |
children | f1ac8b51ec6b |
line wrap: on
line diff
--- a/src/protocols/oscar/oscar.c Sun May 05 18:43:20 2002 +0000 +++ b/src/protocols/oscar/oscar.c Sun May 05 19:02:08 2002 +0000 @@ -243,6 +243,7 @@ static int gaim_parse_offgoing (aim_session_t *, aim_frame_t *, ...); static int gaim_parse_incoming_im(aim_session_t *, aim_frame_t *, ...); static int gaim_parse_misses (aim_session_t *, aim_frame_t *, ...); +static int gaim_parse_clientauto (aim_session_t *, aim_frame_t *, ...); static int gaim_parse_user_info (aim_session_t *, aim_frame_t *, ...); static int gaim_parse_motd (aim_session_t *, aim_frame_t *, ...); static int gaim_chatnav_info (aim_session_t *, aim_frame_t *, ...); @@ -691,6 +692,7 @@ aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, gaim_parse_incoming_im, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, gaim_parse_locerr, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, gaim_parse_misses, 0); + aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_CLIENTAUTORESP, gaim_parse_clientauto, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, gaim_parse_ratechange, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, gaim_parse_evilnotify, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, AIM_CB_LOK_ERROR, gaim_parse_searcherror, 0); @@ -1630,6 +1632,83 @@ return 1; } +static char *gaim_icq_status(int state) { + /* Make a cute little string that shows the status of the dude or dudet */ + if (state & AIM_ICQ_STATE_CHAT) + return g_strdup_printf("Free For Chat"); + else if (state & AIM_ICQ_STATE_DND) + return g_strdup_printf("Do Not Disturb"); + else if (state & AIM_ICQ_STATE_OUT) + return g_strdup_printf("Not Available"); + else if (state & AIM_ICQ_STATE_BUSY) + return g_strdup_printf("Occupied"); + else if (state & AIM_ICQ_STATE_AWAY) + 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 + return g_strdup_printf("Online"); +} + +static int gaim_parse_clientauto(aim_session_t *sess, aim_frame_t *fr, ...) { + struct gaim_connection *gc = sess->aux_data; + va_list ap; + fu16_t chan, reason; + char *who; + + va_start(ap, fr); + chan = (fu16_t)va_arg(ap, unsigned int); + who = va_arg(ap, char *); + reason = (fu16_t)va_arg(ap, unsigned int); + + switch(reason) { + case 0x0003: { /* Reply from an ICQ status message request */ + int state = (int)va_arg(ap, fu32_t); + char *msg = va_arg(ap, char *); + char *status_msg = gaim_icq_status(state); + char *dialog_msg, **splitmsg; + struct oscar_data *od = gc->proto_data; + GSList *l = od->evilhack; + gboolean evilhack = FALSE; + + /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ + splitmsg = g_strsplit(msg, "\r\n", 0); + + /* If who is in od->evilhack, then we're just getting the away message, otherwise this + * will just get appended to the info box (which is already showing). */ + while (l) { + char *x = l->data; + if (!strcmp(x, normalize(who))) { + evilhack = TRUE; + g_free(x); + od->evilhack = g_slist_remove(od->evilhack, x); + break; + } + l = l->next; + } + + if (evilhack) + dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR><BR>%s<BR>"), who, status_msg, g_strjoinv("<BR>", splitmsg)); + else + dialog_msg = g_strdup_printf(_("<B>Status:</B> %s<BR><HR><BR>%s<BR>"), status_msg, g_strjoinv("<BR>", splitmsg)); + g_show_info_text(gc, who, 2, dialog_msg, NULL); + + g_free(status_msg); + g_free(dialog_msg); + g_strfreev(splitmsg); + } break; + + default: { + debug_printf("Received an unknown client auto-response from %s. Type 0x%04x\n", who, reason); + } break; + } + va_end(ap); + + return 1; +} + static int gaim_parse_genericerr(aim_session_t *sess, aim_frame_t *fr, ...) { va_list ap; fu16_t reason; @@ -2397,6 +2476,7 @@ static int gaim_simpleinfo(aim_session_t *sess, aim_frame_t *fr, ...) { struct gaim_connection *gc = sess->aux_data; + struct buddy *budlight; va_list ap; struct aim_icq_simpleinfo *info; char buf[16 * 1024]; @@ -2411,13 +2491,31 @@ "<B>UIN:</B> %lu<BR>" "<B>Nick:</B> %s<BR>" "<B>Name:</B> %s %s<BR>" - "<B>Email:</B> %s\n", + "<B>Email:</B> %s<BR>\n", info->uin, info->nick, info->first, info->last, info->email); - g_show_info_text(gc, who, FALSE, buf, NULL); + /* If the contact is away, then we also want to get their status message + * and show it in the same window as info. g_show_info_text gets the status + * message if the third arg is 0 (this seems really gross to me). The + * parse-icq-status-message function knows if it is putting it's message in + * an info window because the name will _not_ be in od->evilhack. For getting + * only the away message the contact's UIN is put in od->evilhack. */ + if ((budlight = find_buddy(gc, who)) && ((budlight->uc >> 7) & (AIM_ICQ_STATE_AWAY || AIM_ICQ_STATE_DND || AIM_ICQ_STATE_OUT || AIM_ICQ_STATE_BUSY || AIM_ICQ_STATE_CHAT))) { + if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) + g_show_info_text(gc, who, 0, buf, NULL); + else { + char *state_msg = gaim_icq_status((budlight->uc & 0xff80) >> 7); + g_show_info_text(gc, who, 2, buf, "<B>Status:</B> ", state_msg, "<BR>\n<HR><BR><I>Remote client does not support sending status messages.</I><BR>\n", NULL); + free(state_msg); + } + } else { + char *state_msg = gaim_icq_status((budlight->uc & 0xff80) >> 7); + g_show_info_text(gc, who, 2, buf, "<B>Status:</B> ", state_msg, NULL); + free(state_msg); + } return 1; } @@ -2459,7 +2557,7 @@ at += g_snprintf(buf + at, len - at, "<B>%s has the following screen names:</B><BR>", address); for (i = 0; i < num; i++) at += g_snprintf(buf + at, len - at, "%s<BR>", &SNs[i * (MAXSNLEN + 1)]); - g_show_info_text(NULL, NULL, FALSE, buf, NULL); + g_show_info_text(NULL, NULL, 2, buf, NULL); g_free(buf); return 1; @@ -2635,10 +2733,22 @@ aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_AWAYMESSAGE); } -static void oscar_get_away(struct gaim_connection *g, char *name) { +static void oscar_get_away(struct gaim_connection *g, char *who) { struct oscar_data *odata = (struct oscar_data *)g->proto_data; - if (!odata->icq) - aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_GENERALINFO); + if (odata->icq) { + struct buddy *budlight = find_buddy(g, who); + if (budlight) + if ((budlight->uc & 0xff80) >> 7) + if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) + aim_send_im_ch2_geticqmessage(odata->sess, who, (budlight->uc & 0xff80) >> 7); + else + debug_printf("Error: Remote client does not support retrieval of status messages.\n"); + else + debug_printf("Error: The user %s has no status message, therefore not requesting.\n", who); + else + debug_printf("Error: Could not find %s in local contact list, therefore unable to request status message.\n", who); + } else + aim_getinfo(odata->sess, odata->conn, who, AIM_GETINFO_GENERALINFO); } static void oscar_get_caps(struct gaim_connection *g, char *name) { @@ -2729,13 +2839,13 @@ aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY); gc->away = ""; } else if (!strcmp(state, "Do Not Disturb")) { - aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_DND); + aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY); gc->away = ""; } else if (!strcmp(state, "Not Available")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY); gc->away = ""; } else if (!strcmp(state, "Occupied")) { - aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_BUSY); + aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY); gc->away = ""; } else if (!strcmp(state, "Free For Chat")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_CHAT); @@ -3236,12 +3346,12 @@ return icon_offline_xpm; if (uc & AIM_ICQ_STATE_CHAT) return icon_ffc_xpm; + if (uc & AIM_ICQ_STATE_DND) + return icon_dnd_xpm; + if (uc & AIM_ICQ_STATE_OUT) + return icon_na_xpm; if (uc & AIM_ICQ_STATE_BUSY) return icon_occ_xpm; - if (uc & AIM_ICQ_STATE_OUT) - return icon_na_xpm; - if (uc & AIM_ICQ_STATE_DND) - return icon_dnd_xpm; if (uc & AIM_ICQ_STATE_AWAY) return icon_away_xpm; return icon_online_xpm; @@ -3433,7 +3543,30 @@ static void oscar_get_away_msg(struct gaim_connection *gc, char *who) { struct oscar_data *od = gc->proto_data; od->evilhack = g_slist_append(od->evilhack, g_strdup(normalize(who))); - oscar_get_info(gc, who); + if (od->icq) { + struct buddy *budlight = find_buddy(gc, who); + if (budlight) + if ((budlight->uc >> 7) & (AIM_ICQ_STATE_AWAY || AIM_ICQ_STATE_DND || AIM_ICQ_STATE_OUT || AIM_ICQ_STATE_BUSY || AIM_ICQ_STATE_CHAT)) + if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) + aim_send_im_ch2_geticqmessage(od->sess, who, (budlight->uc & 0xff80) >> 7); + else { + char *state_msg = gaim_icq_status((budlight->uc & 0xff80) >> 7); + char *dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR><BR><I>Remote client does not support sending status messages.</I><BR>"), who, state_msg); + g_show_info_text(gc, who, 2, dialog_msg, NULL); + free(state_msg); + free(dialog_msg); + } + else { + char *state_msg = gaim_icq_status((budlight->uc & 0xff80) >> 7); + char *dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<BR><HR><BR><I>User has no status message.</I><BR>"), who, state_msg); + g_show_info_text(gc, who, 2, dialog_msg, NULL); + free(state_msg); + free(dialog_msg); + } + else + do_error_dialog("Could not find contact in local list, therefore unable to request status message.\n", "Gaim - Error"); + } else + oscar_get_info(gc, who); } static GList *oscar_buddy_menu(struct gaim_connection *gc, char *who) { @@ -3448,7 +3581,13 @@ pbm->gc = gc; m = g_list_append(m, pbm); - if (!odata->icq) { + if (odata->icq) { + pbm = g_new0(struct proto_buddy_menu, 1); + pbm->label = _("Get Status Msg"); + pbm->callback = oscar_get_away_msg; + pbm->gc = gc; + m = g_list_append(m, pbm); + } else { pbm = g_new0(struct proto_buddy_menu, 1); pbm->label = _("Get Away Msg"); pbm->callback = oscar_get_away_msg;