# HG changeset patch # User Mark Doliner # Date 1076306548 0 # Node ID 862dc2839646f5fa305319d1a7d09b71781cf874 # Parent 4beaf6b3548347e9fc2e40589c17649c1c9cb30b [gaim-migrate @ 8942] Alright, this should make aim support non-ascii chars in chats. I guess I should actually test that... Anyway, it doesn't seem to break anything. It's a patch from Uli Luckas. Yay. committer: Tailor Script diff -r 4beaf6b35483 -r 862dc2839646 pixmaps/status/default/Makefile.am --- a/pixmaps/status/default/Makefile.am Sat Feb 07 23:24:31 2004 +0000 +++ b/pixmaps/status/default/Makefile.am Mon Feb 09 06:02:28 2004 +0000 @@ -24,6 +24,7 @@ notauthorized.png \ occupied.png \ offline.png \ + rendezvous.png \ secure.png \ trepia.png \ wireless.png \ diff -r 4beaf6b35483 -r 862dc2839646 src/protocols/oscar/aim.h --- a/src/protocols/oscar/aim.h Sat Feb 07 23:24:31 2004 +0000 +++ b/src/protocols/oscar/aim.h Mon Feb 09 06:02:28 2004 +0000 @@ -1119,7 +1119,7 @@ #define AIM_CHATFLAGS_NOREFLECT 0x0001 #define AIM_CHATFLAGS_AWAY 0x0002 -faim_export int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, fu16_t flags, const char *msg, int msglen); +faim_export int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, fu16_t flags, const char *msg, int msglen, char *charset); faim_export int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance); faim_export int aim_chat_attachname(aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance); faim_export char *aim_chat_getname(aim_conn_t *conn); diff -r 4beaf6b35483 -r 862dc2839646 src/protocols/oscar/chat.c --- a/src/protocols/oscar/chat.c Sat Feb 07 23:24:31 2004 +0000 +++ b/src/protocols/oscar/chat.c Mon Feb 09 06:02:28 2004 +0000 @@ -476,7 +476,7 @@ * * XXX convert this to use tlvchains */ -faim_export int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, fu16_t flags, const char *msg, int msglen) +faim_export int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, fu16_t flags, const char *msg, int msglen, char *charset) { int i; aim_frame_t *fr; @@ -534,6 +534,11 @@ */ aim_tlvlist_add_raw(&itl, 0x0001, msglen, msg); + /* + * SubTLV: Type 2: Encoding + */ + aim_tlvlist_add_raw(&itl, 0x0002, strlen(charset), charset); + /* * Type 5: Message block. Contains more TLVs. * @@ -587,6 +592,8 @@ fu16_t channel; aim_tlvlist_t *otl; char *msg = NULL; + int len; + char *charset = NULL; aim_msgcookie_t *ck; memset(&userinfo, 0, sizeof(aim_userinfo_t)); @@ -657,14 +664,22 @@ /* * Type 0x0001: Message. */ - if (aim_tlv_gettlv(itl, 0x0001, 1)) + if (aim_tlv_gettlv(itl, 0x0001, 1)) { msg = aim_tlv_getstr(itl, 0x0001, 1); + len = aim_tlv_gettlv(itl, 0x0001, 1)->length; + } + + /* + * Type 0x0002: Charset. + */ + if (aim_tlv_gettlv(itl, 0x0002, 1)) + charset = aim_tlv_getstr(itl, 0x0002, 1); aim_tlvlist_free(&itl); } if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) - ret = userfunc(sess, rx, &userinfo, msg); + ret = userfunc(sess, rx, &userinfo, len, msg, charset); aim_info_free(&userinfo); free(cookie); diff -r 4beaf6b35483 -r 862dc2839646 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Sat Feb 07 23:24:31 2004 +0000 +++ b/src/protocols/oscar/oscar.c Mon Feb 09 06:02:28 2004 +0000 @@ -454,6 +454,22 @@ return c; } +static struct chat_connection *find_oscar_chat_by_conv(GaimConnection *gc, + GaimConversation *conv) { + GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; + struct chat_connection *c = NULL; + + while (g) { + c = (struct chat_connection *)g->data; + if (c->cnv == conv) + break; + g = g->next; + c = NULL; + } + + return c; +} + static void gaim_odc_disconnect(aim_session_t *sess, aim_conn_t *conn) { GaimConnection *gc = sess->aux_data; OscarData *od = (OscarData *)gc->proto_data; @@ -3398,15 +3414,39 @@ GaimConnection *gc = sess->aux_data; va_list ap; aim_userinfo_t *info; + GError *err = NULL; char *msg; + char *tmp; + int len; + char *charset; + int convlen; struct chat_connection *ccon = find_oscar_chat_by_conn(gc, fr->conn); va_start(ap, fr); info = va_arg(ap, aim_userinfo_t *); + len = va_arg(ap, int); msg = va_arg(ap, char *); + charset = va_arg(ap, char *); va_end(ap); - serv_got_chat_in(gc, ccon->id, info->sn, 0, msg, time((time_t)NULL)); + if (charset) { + if (strcmp(charset, "unicode-2-0") == 0) + charset = "UCS-2BE"; + } else { + charset = "iso-8859-1"; + } + + tmp = g_convert(msg, len, "UTF-8", charset, NULL, &convlen, &err); + + if (err) { + gaim_debug(GAIM_DEBUG_INFO, "oscar", + "Unicode Chat conversion: %s\n", err->message); + tmp = g_strdup(_("(There was an error receiving this message)")); + g_error_free(err); + } + + serv_got_chat_in(gc, ccon->id, info->sn, 0, tmp, time((time_t)NULL)); + g_free(tmp); return 1; } @@ -4860,19 +4900,26 @@ GaimBuddy *b; struct aim_ssi_item *curitem; int tmp; - /* XXX - use these? va_list ap; + fu16_t fmtver, numitems; + struct aim_ssi_item *items; + fu32_t timestamp; va_start(ap, fr); fmtver = (fu16_t)va_arg(ap, int); numitems = (fu16_t)va_arg(ap, int); - items = va_arg(ap, struct aim_ssi_item); + items = va_arg(ap, struct aim_ssi_item *); timestamp = va_arg(ap, fu32_t); - va_end(ap); */ + va_end(ap); gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: syncing local list and server list\n"); + if ((timestamp == 0) || (numitems == 0)) { + gaim_notify_error(gc, NULL, "Got AIM SSI with a 0 timestamp or 0 numitems, not syncing, tell KingAnt! And tell him if your buddy list actually works or not. Thanks! Oh, IM him at markdoliner on AIM/ICQ.", NULL); + return 1; + } + /* Clean the buddy list */ aim_ssi_cleanlist(sess); @@ -5329,59 +5376,76 @@ serv_got_chat_left(g, gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))); } -static int oscar_chat_send(GaimConnection *g, int id, const char *message) { - OscarData *od = (OscarData *)g->proto_data; - GSList *bcs = g->buddy_chats; - GaimConversation *b = NULL; +static int oscar_send_chat(GaimConnection *gc, int id, const char *message) { + OscarData *od = (OscarData *)gc->proto_data; + GError *err = NULL; + GaimConversation *conv = NULL; struct chat_connection *c = NULL; char *buf, *buf2; - guint i, j; - - while (bcs) { - b = (GaimConversation *)bcs->data; - if (id == gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))) - break; - bcs = bcs->next; - b = NULL; - } - if (!b) + char *charset = NULL; + int encoding; + int len; + + if (!(conv = gaim_find_chat(gc, id))) return -EINVAL; - bcs = od->oscar_chats; - while (bcs) { - c = (struct chat_connection *)bcs->data; - if (b == c->cnv) - break; - bcs = bcs->next; - c = NULL; - } - if (!c) + if (!(c = find_oscar_chat_by_conv(gc, conv))) return -EINVAL; - buf = g_malloc(strlen(message) * 4 + 1); - for (i = 0, j = 0; i < strlen(message); i++) { - if (message[i] == '\n') { - buf[j++] = '<'; - buf[j++] = 'B'; - buf[j++] = 'R'; - buf[j++] = '>'; - } else { - buf[j++] = message[i]; + buf = gaim_strdup_withhtml(message); + len = strlen(buf); + + encoding = oscar_encoding_check(buf); + if (encoding == AIM_IMFLAGS_UNICODE) { + gaim_debug(GAIM_DEBUG_INFO, "oscar", "Sending Unicode Chat\n"); + charset = "unicode-2-0"; + buf2 = g_convert(buf, len, "UCS-2BE", "UTF-8", NULL, &len, &err); + if (err) { + gaim_debug(GAIM_DEBUG_ERROR, "oscar", + "Error converting a unicode message: %s\n", + err->message); + gaim_debug(GAIM_DEBUG_ERROR, "oscar", + "This really shouldn't happen!\n"); + /* We really shouldn't try to send the + * IM now, but I'm not sure what to do */ + g_error_free(err); + } + } else if (encoding & AIM_IMFLAGS_ISO_8859_1) { + gaim_debug(GAIM_DEBUG_INFO, "oscar", + "Sending ISO-8859-1 Chat\n"); + charset = "iso-8859-1"; + buf2 = g_convert(buf, len, "ISO-8859-1", "UTF-8", NULL, &len, &err); + if (err) { + gaim_debug(GAIM_DEBUG_ERROR, "oscar", + "conversion error: %s\n", err->message); + gaim_debug(GAIM_DEBUG_ERROR, "oscar", + "Someone tell Ethan his 8859-1 detection is wrong\n"); + g_error_free(err); + encoding = AIM_IMFLAGS_UNICODE; + buf2 = g_convert(buf, len, "UCS-2BE", "UTF8", NULL, &len, &err); + if (err) { + gaim_debug(GAIM_DEBUG_ERROR, "oscar", + "Error in unicode fallback: %s\n", err->message); + g_error_free(err); + } } - } - buf[j] = '\0'; - - if (strlen(buf) > c->maxlen) + } else { + charset = "us-ascii"; + buf2 = g_strdup(buf); + } + + if (len > c->maxlen) return -E2BIG; - buf2 = gaim_markup_strip_html(buf); - if (strlen(buf2) > c->maxvis) { - g_free(buf2); + g_free(buf); + buf = gaim_markup_strip_html(buf2); + g_free(buf2); + if (strlen(buf) > c->maxvis) { + g_free(buf); return -E2BIG; } - g_free(buf2); - - aim_chat_send_im(od->sess, c->conn, 0, buf, strlen(buf)); + + aim_chat_send_im(od->sess, c->conn, 0, buf, len, charset); g_free(buf); return 0; } @@ -6682,7 +6746,7 @@ oscar_chat_invite, oscar_chat_leave, NULL, - oscar_chat_send, + oscar_send_chat, oscar_keepalive, NULL, NULL,