# HG changeset patch # User Luke Schierer # Date 1034345964 0 # Node ID 5e50f6746509a07f92dc194205307df57dc264a6 # Parent e2391338c394a0709a6ba4f7994aaa77c7cf803f [gaim-migrate @ 3766] (10:16:03) deryni: we're fully 'compliant'? (sorry if that betrays some underlying stupidity) (10:16:55) Paco-Paco: yes (10:17:24) Paco-Paco: provided the user has the font, on any of the services supporting unicode we should support every known language in the world :-) (10:17:36) Paco-Paco: well, as soon as we have a proper utf-8 input widget committer: Tailor Script diff -r e2391338c394 -r 5e50f6746509 ChangeLog --- a/ChangeLog Fri Oct 11 12:24:25 2002 +0000 +++ b/ChangeLog Fri Oct 11 14:19:24 2002 +0000 @@ -71,7 +71,7 @@ * Word-wrapping on mail notification text (Thanks, Andrew Molloy) * /topic with no argument displays the current topic (Thanks Mark Doliner) - * i18n fixes (Thanks Matt Wilson, Ethan Blanton, A Lee) + * Lots of i18n fixes (Thanks Matt Wilson, Ethan Blanton, A Lee) * Removed Ctrl-C binding for color * Docklet plugin--replaces the old GNOME applet. You'll need the Panel Notification Area applet for GNOME 2, or the kicker for diff -r e2391338c394 -r 5e50f6746509 src/gaim.h --- a/src/gaim.h Fri Oct 11 12:24:25 2002 +0000 +++ b/src/gaim.h Fri Oct 11 14:19:24 2002 +0000 @@ -468,14 +468,6 @@ extern char *convert_string(char *, const char *, const char *); extern const char *handle_uri(char *); -#ifdef HAVE_LANGINFO_CODESET -#define utf8_to_str(in) convert_string(in, nl_langinfo(CODESET), "UTF-8") -#define str_to_utf8(in) convert_string(in, "UTF-8", nl_langinfo(CODESET)) -#else -#define utf8_to_str(in) convert_string(in, "ISO-8859-1", "UTF-8") -#define str_to_utf8(in) convert_string(in, "UTF-8", "ISO-8859-1") -#endif - /*------------------------------------------------------------------------*/ /* Multi-Entry dialog and vCard dialog support */ /*------------------------------------------------------------------------*/ diff -r e2391338c394 -r 5e50f6746509 src/protocols/jabber/jabber.c --- a/src/protocols/jabber/jabber.c Fri Oct 11 12:24:25 2002 +0000 +++ b/src/protocols/jabber/jabber.c Fri Oct 11 14:19:24 2002 +0000 @@ -1305,8 +1305,6 @@ msg = xmlnode_get_data(y); } - msg = utf8_to_str(msg); - if (!from) return; @@ -1362,9 +1360,6 @@ g_free(from); } - if (msg) - g_free(msg); - } else if (!strcasecmp(type, "error")) { if ((y = xmlnode_get_tag(p->x, "error"))) { type = xmlnode_get_attrib(y, "code"); @@ -1389,12 +1384,9 @@ msg = xmlnode_get_data(y); } - msg = utf8_to_str(msg); - if ((subj = xmlnode_get_tag(p->x, "subject"))) { topic = xmlnode_get_data(subj); } - topic = utf8_to_str(topic); jc = find_existing_chat(GJ_GC(gjc), p->from); if (!jc) { @@ -1438,9 +1430,6 @@ } } - g_free(msg); - g_free(topic); - } else { debug_printf("unhandled message %s\n", type); } @@ -1764,9 +1753,6 @@ /* * Add or remove a buddy? Change buddy's alias or group? */ - if(name) - name = utf8_to_str(name); - if (BUD_SUB_TO_PEND(sub, ask) || BUD_SUBD_TO(sub, ask)) { if ((b = find_buddy(GJ_GC(gjc), buddyname)) == NULL) { debug_printf("adding buddy [4]: %s\n", buddyname); @@ -1806,9 +1792,6 @@ jabber_remove_gaim_buddy(GJ_GC(gjc), buddyname); } - if(name) - g_free(name); - g_free(buddyname); } @@ -2478,10 +2461,8 @@ xmlnode_insert_tag(y, "composing"); if (message && strlen(message)) { - char *utf8 = str_to_utf8((char*)message); y = xmlnode_insert_tag(x, "body"); - xmlnode_insert_cdata(y, utf8, -1); - g_free(utf8); + xmlnode_insert_cdata(y, message, -1); } gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x); @@ -2539,9 +2520,7 @@ */ if(my_alias != NULL && my_alias[0] != '\0' && strcmp(realwho, my_alias)) { - char *utf8 = str_to_utf8(my_alias); - xmlnode_put_attrib(y, "name", utf8); - g_free(utf8); + xmlnode_put_attrib(y, "name", my_alias); } /* @@ -2965,10 +2944,8 @@ g_free(subject); if (message && strlen(message)) { - char *utf8 = str_to_utf8((char*)message); y = xmlnode_insert_tag(x, "body"); - xmlnode_insert_cdata(y, utf8, -1); - g_free(utf8); + xmlnode_insert_cdata(y, message, -1); } gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x); @@ -3017,18 +2994,14 @@ if (message && strlen(message) > strlen("/topic ") && !g_strncasecmp(message, "/topic ", strlen("/topic "))) { char buf[8192]; - char *utf8 = str_to_utf8(message + strlen("/topic ")); y = xmlnode_insert_tag(x, "subject"); - xmlnode_insert_cdata(y, utf8, -1); + xmlnode_insert_cdata(y, message + strlen("/topic "), -1); y = xmlnode_insert_tag(x, "body"); - g_snprintf(buf, sizeof(buf), "/me has changed the subject to: %s", utf8); + g_snprintf(buf, sizeof(buf), "/me has changed the subject to: %s", message + strlen("/topic")); xmlnode_insert_cdata(y, buf, -1); - g_free(utf8); } else if (message && strlen(message)) { - char *utf8 = str_to_utf8(message); y = xmlnode_insert_tag(x, "body"); - xmlnode_insert_cdata(y, utf8, -1); - g_free(utf8); + xmlnode_insert_cdata(y, message, -1); } gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x); @@ -3054,10 +3027,8 @@ xmlnode_put_attrib(x, "type", "normal"); if (message && strlen(message)) { - char *utf8 = str_to_utf8(message); y = xmlnode_insert_tag(x, "body"); - xmlnode_insert_cdata(y, utf8, -1); - g_free(utf8); + xmlnode_insert_cdata(y, message, -1); } gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x); diff -r e2391338c394 -r 5e50f6746509 src/protocols/msn/msn.c --- a/src/protocols/msn/msn.c Fri Oct 11 12:24:25 2002 +0000 +++ b/src/protocols/msn/msn.c Fri Oct 11 14:19:24 2002 +0000 @@ -403,9 +403,7 @@ x = strstr(from, "\r\n"); *x = 0; subject += strlen("Subject: "); x = strstr(subject, "\r\n"); *x = 0; - from = utf8_to_str(from); connection_has_mail(gc, -1, from, subject, login_url); - g_free(from); } } } @@ -543,12 +541,9 @@ ms->total++; while (ms->txqueue) { char *send = add_cr(ms->txqueue->data); - char *utf8 = str_to_utf8(send); - g_free(send); g_snprintf(sendbuf, sizeof(sendbuf), "MSG %d N %d\r\n%s%s", ++ms->trId, - strlen(MIME_HEADER) + strlen(utf8), - MIME_HEADER, utf8); - g_free(utf8); + strlen(MIME_HEADER) + strlen(send), + MIME_HEADER, send); g_free(ms->txqueue->data); ms->txqueue = g_slist_remove(ms->txqueue, ms->txqueue->data); if (msn_write(ms->fd, sendbuf, strlen(sendbuf)) < 0) { @@ -646,7 +641,7 @@ static void msn_process_switch_msg(struct msn_switchboard *ms, char *msg) { - char *content, *agent, *format, *utf; + char *content, *agent, *format; char *message = NULL; int flags = 0; @@ -684,15 +679,12 @@ return; } skiphead += 4; - utf = utf8_to_str(skiphead); - strip_linefeed(utf); + strip_linefeed(skiphead); if (format) { - int len = strlen(utf) + strlen(format) + 1; - message = g_malloc(len); - g_snprintf(message, len, "%s%s", format, utf); + message = g_strdup_printf("%s%s", format, skiphead); } else { - message = utf; + message = g_strdup(skiphead); } if (ms->chat) @@ -701,9 +693,6 @@ serv_got_im(ms->gc, ms->msguser, message, flags, time(NULL), -1); g_free(message); - if (format) { - g_free(utf); - } } } @@ -874,11 +863,8 @@ { struct msn_data *md = map->gc->proto_data; char buf[MSN_BUF_LEN]; - char *srvfriend; - srvfriend = str_to_utf8(map->friend); - g_snprintf(buf, sizeof(buf), "ADD %d AL %s %s\r\n", ++md->trId, map->user, url_encode(srvfriend)); - g_free(srvfriend); + g_snprintf(buf, sizeof(buf), "ADD %d AL %s %s\r\n", ++md->trId, map->user, url_encode(map->friend)); if (msn_write(md->fd, buf, strlen(buf)) < 0) { hide_login_progress(map->gc, "Write error"); @@ -895,10 +881,9 @@ { struct msn_data *md = map->gc->proto_data; char buf[MSN_BUF_LEN]; - char *srvfriend = str_to_utf8(map->friend); if (*(map->user)) { - g_snprintf(buf, sizeof(buf), "ADD %d BL %s %s\r\n", ++md->trId, map->user, url_encode(srvfriend)); + g_snprintf(buf, sizeof(buf), "ADD %d BL %s %s\r\n", ++md->trId, map->user, url_encode(map->friend)); if (msn_write(md->fd, buf, strlen(buf)) < 0) { hide_login_progress(map->gc, "Write error"); signoff(map->gc); @@ -908,7 +893,6 @@ build_block_list(); } - g_free(srvfriend); g_free(map->user); g_free(map->friend); g_free(map); @@ -947,7 +931,7 @@ ap = g_new0(struct msn_add_permit, 1); ap->user = g_strdup(user); - ap->friend = utf8_to_str(friend); + ap->friend = g_strdup(friend); ap->gc = gc; g_snprintf(msg, sizeof(msg), _("The user %s (%s) wants to add %s to his or her buddy list."), @@ -1031,7 +1015,7 @@ if ((b = find_buddy(gc, user)) != NULL) { if (b->proto_data) g_free(b->proto_data); - b->proto_data = utf8_to_str(friend); + b->proto_data = g_strdup(friend); } if (!g_strcasecmp(state, "BSY")) { @@ -1076,7 +1060,7 @@ if (!g_strcasecmp(which, "FL") && pos) { struct msn_buddy *b = g_new0(struct msn_buddy, 1); b->user = g_strdup(who); - b->friend = utf8_to_str(friend); + b->friend = g_strdup(friend); md->fl = g_slist_append(md->fl, b); } else if (!g_strcasecmp(which, "AL") && pos) { char *dupl; @@ -1104,7 +1088,7 @@ debug_printf("Unresolved MSN RL entry\n"); ap = g_new0(struct msn_add_permit, 1); ap->user = g_strdup(who); - ap->friend = utf8_to_str(friend); + ap->friend = g_strdup(friend); ap->gc = gc; g_snprintf(msg, sizeof(msg), _("The user %s (%s) wants to add you to their buddy list"),ap->user, ap->friend); @@ -1185,7 +1169,7 @@ if ((b = find_buddy(gc, user)) != NULL) { if (b->proto_data) g_free(b->proto_data); - b->proto_data = utf8_to_str(friend); + b->proto_data = g_strdup(friend); } if (!g_strcasecmp(state, "BSY")) { @@ -1225,10 +1209,8 @@ GET_NEXT(tmp); friend = url_decode(tmp); - friend = utf8_to_str(friend); g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", friend); - g_free(friend); } else if (!g_strncasecmp(buf, "REM", 3)) { } else if (!g_strncasecmp(buf, "RNG", 3)) { struct msn_switchboard *ms; @@ -1406,7 +1388,7 @@ static void msn_process_main_msg(struct gaim_connection *gc, char *msg) { struct msn_data *md = gc->proto_data; - char *skiphead, *utf; + char *skiphead; char *content; content = strstr(msg, "Content-Type: "); @@ -1458,12 +1440,9 @@ if (!skiphead || !skiphead[4]) return; skiphead += 4; - utf = utf8_to_str(skiphead); - strip_linefeed(utf); + strip_linefeed(skiphead); - serv_got_im(gc, md->msguser, utf, 0, time(NULL), -1); - - g_free(utf); + serv_got_im(gc, md->msguser, skiphead, 0, time(NULL), -1); } static void msn_callback(gpointer data, gint source, GaimInputCondition cond) @@ -1631,9 +1610,7 @@ /* so here, we're either getting the challenge or the OK */ if (!g_strcasecmp(resp, "OK")) { - friend = utf8_to_str(friend); g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", friend); - g_free(friend); g_snprintf(sendbuf, sizeof(sendbuf), "SYN %d 0\r\n", ++md->trId); if (msn_write(md->fd, sendbuf, strlen(sendbuf)) < 0) { @@ -1651,9 +1628,7 @@ md5_byte_t di[16]; int i; - friend = utf8_to_str(friend); g_snprintf(buf2, sizeof(buf2), "%s%s", friend, gc->password); - g_free(friend); md5_init(&st); md5_append(&st, (const md5_byte_t *)buf2, strlen(buf2)); @@ -1890,7 +1865,7 @@ char buf[MSN_BUF_LEN]; if (ms) { - char *utf8, *send; + char *send; if (ms->txqueue) { debug_printf("appending to queue\n"); @@ -1899,12 +1874,10 @@ } send = add_cr(message); - utf8 = str_to_utf8(send); + g_snprintf(buf, sizeof(buf), "MSG %d N %d\r\n%s%s", ++ms->trId, + strlen(MIME_HEADER) + strlen(send), + MIME_HEADER, send); g_free(send); - g_snprintf(buf, sizeof(buf), "MSG %d N %d\r\n%s%s", ++ms->trId, - strlen(MIME_HEADER) + strlen(utf8), - MIME_HEADER, utf8); - g_free(utf8); if (msn_write(ms->fd, buf, strlen(buf)) < 0) msn_kill_switch(ms); debug_printf("\n"); @@ -1932,18 +1905,16 @@ { struct msn_switchboard *ms = msn_find_switch_by_id(gc, id); char buf[MSN_BUF_LEN]; - char *utf8, *send; + char *send; if (!ms) return -EINVAL; send = add_cr(message); - utf8 = str_to_utf8(send); + g_snprintf(buf, sizeof(buf), "MSG %d N %d\r\n%s%s", ++ms->trId, + strlen(MIME_HEADER) + strlen(send), + MIME_HEADER, send); g_free(send); - g_snprintf(buf, sizeof(buf), "MSG %d N %d\r\n%s%s", ++ms->trId, - strlen(MIME_HEADER) + strlen(utf8), - MIME_HEADER, utf8); - g_free(utf8); if (msn_write(ms->fd, buf, strlen(buf)) < 0) { msn_kill_switch(ms); return 0; @@ -2178,7 +2149,7 @@ if (!entry || *entry == '\0') alias = g_strdup(""); else - alias = str_to_utf8(entry); + alias = g_strdup(entry); if (strlen(alias) >= BUDDY_ALIAS_MAXLEN) { do_error_dialog(_("New MSN friendly name too long."), NULL, GAIM_ERROR); diff -r e2391338c394 -r 5e50f6746509 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Fri Oct 11 12:24:25 2002 +0000 +++ b/src/protocols/oscar/oscar.c Fri Oct 11 14:19:24 2002 +0000 @@ -1709,7 +1709,7 @@ } static int incomingim_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch1_args *args) { - char *tmp = g_malloc(BUF_LONG); + char *tmp; struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = gc->proto_data; int flags = 0; @@ -1769,23 +1769,40 @@ * HTML entity. */ if (args->icbmflags & AIM_IMFLAGS_UNICODE) { - int i; + int i, j; + GError *err = NULL; + FILE *fp; - for (i = 0, tmp[0] = '\0'; i < args->msglen; i += 2) { - unsigned short uni; - - uni = ((args->msg[i] & 0xff) << 8) | (args->msg[i+1] & 0xff); - - if ((uni < 128) || ((uni >= 160) && (uni <= 255))) { /* ISO 8859-1 */ + tmp = g_convert(args->msg, args->msglen, "UTF-8", "UCS-2BE", &j, &i, &err); + if (err) + debug_printf("Unicode IM conversion: %s\n", err->message); + if (!tmp) { + /* Conversion to HTML entities isn't a bad fallback */ + debug_printf ("AIM charset conversion failed!\n"); + for (i = 0, tmp[0] = '\0'; i < args->msglen; i += 2) { + unsigned short uni; - g_snprintf(tmp+strlen(tmp), BUF_LONG-strlen(tmp), "%c", uni); + uni = ((args->msg[i] & 0xff) << 8) | (args->msg[i+1] & 0xff); - } else { /* something else, do UNICODE entity */ - g_snprintf(tmp+strlen(tmp), BUF_LONG-strlen(tmp), "&#%04x;", uni); + if ((uni < 128) || ((uni >= 160) && (uni <= 255))) { /* ISO 8859-1 */ + + g_snprintf(tmp+strlen(tmp), BUF_LONG-strlen(tmp), "%c", uni); + + } else { /* something else, do UNICODE entity */ + g_snprintf(tmp+strlen(tmp), BUF_LONG-strlen(tmp), "&#%04x;", uni); + } + } } - } else - g_snprintf(tmp, BUF_LONG, "%s", args->msg); + } else if (args->icbmflags & AIM_IMFLAGS_ISO_8859_1) { + int i; + debug_printf("ISO-8859-1 IM"); + tmp = g_convert(args->msg, args->msglen, "UTF-8", "ISO-8859-1", NULL, &i, NULL); + } else { + /* ASCII is valid UTF-8 */ + debug_printf("ASCII IM\n"); + tmp = g_strdup(args->msg); + } if (args->icbmflags & AIM_IMFLAGS_TYPINGNOT) { char *who = normalize(userinfo->sn); @@ -1793,7 +1810,7 @@ g_hash_table_insert(od->supports_tn, who, who); } - strip_linefeed(tmp); + //strip_linefeed(tmp); serv_got_im(gc, userinfo->sn, tmp, flags, time(NULL), -1); g_free(tmp); @@ -3300,6 +3317,7 @@ struct icon_req *ir = NULL; char *who = normalize(name); struct stat st; + int i, len; args.flags = AIM_IMFLAGS_ACK | AIM_IMFLAGS_CUSTOMFEATURES; if (odata->icq) @@ -3339,11 +3357,48 @@ } args.destsn = name; - args.msg = message; - args.msglen = strlen(message); + + /* Determine how we can send this message. Per the + * warnings elsewhere in this file, these little + * checks determine the simplest encoding we can use + * for a given message send using it. */ + len = strlen(message); + i = 0; + while (message[i]) { + if ((unsigned char)message[i] > 0x7f) { + /* not ASCII! */ + args.flags |= AIM_IMFLAGS_ISO_8859_1; + break; + } + i++; + } + while (message[i]) { + /* ISO-8859-1 is 0x00-0xbf in the first byte + * followed by 0xc0-0xc3 in the second */ + if ((unsigned char)message[i] > 0x80 && ((unsigned char)message[i] > 0xbf || + ((unsigned char)message[i + 1] < 0xc0 || (unsigned char)message[i + 1] > 0xc3))) { + args.flags ^= AIM_IMFLAGS_ISO_8859_1; + args.flags |= AIM_IMFLAGS_UNICODE; + break; + } + i++; + } + if (args.flags & AIM_IMFLAGS_UNICODE) { + args.msg = g_convert(message, len, "UCS-2BE", "UTF-8", NULL, &len, NULL); + } else if (args.flags & AIM_IMFLAGS_UNICODE) { + args.msg = g_convert(message, len, "ISO-8859-1", "UTF-8", NULL, &len, NULL); + if (!args.msg) { + debug_printf("Someone tell Ethan his 8859-1 detection is wrong\n"); + args.flags ^= AIM_IMFLAGS_ISO_8859_1 | AIM_IMFLAGS_UNICODE; + len = strlen(message); + args.msg = g_convert(message, len, "UCS-2BE", "UTF8", NULL, &len, NULL); + } + } else { + args.msg = message; + } + args.msglen = len; ret = aim_send_im_ext(odata->sess, &args); - } if (ret >= 0) return 1; diff -r e2391338c394 -r 5e50f6746509 src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Fri Oct 11 12:24:25 2002 +0000 +++ b/src/protocols/yahoo/yahoo.c Fri Oct 11 14:19:24 2002 +0000 @@ -604,7 +604,7 @@ msg[j++] = m[i]; } msg[j] = 0; - serv_got_im(gc, from, utf8_to_str(msg), 0, tm, -1); + serv_got_im(gc, from, g_strdup(msg), 0, tm, -1); } else if (pkt->status == 2) { do_error_dialog(_("Your Yahoo! message did not get sent."), NULL, GAIM_ERROR); } @@ -1191,7 +1191,7 @@ { struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); - char *msg = str_to_utf8(what); + char *msg = g_strdup(what); yahoo_packet_hash(pkt, 1, gc->displayname); yahoo_packet_hash(pkt, 5, who); diff -r e2391338c394 -r 5e50f6746509 src/util.c --- a/src/util.c Fri Oct 11 12:24:25 2002 +0000 +++ b/src/util.c Fri Oct 11 14:19:24 2002 +0000 @@ -1173,51 +1173,6 @@ fclose(fd); } -char *convert_string(char *str, const char *destset, const char *srcset) -{ -#ifdef HAVE_ICONV - char *buf; - iconv_t cd; - size_t insize = 0; - size_t outsize = 0; - size_t nconv = 0; - char *inptr; - char *outptr; - char *ret; - - if (!str) - return NULL; - buf = g_malloc(strlen(str)*4); - insize = strlen(str); - inptr = str; - outsize = strlen(str)*4; - outptr = buf; - - cd = iconv_open(destset, srcset); - if (cd == (iconv_t) -1) { - g_free(buf); - debug_printf("iconv_open(%s, %s) Error\n",destset, srcset); - return g_strdup(str); - } - - nconv = iconv(cd, &inptr, &insize, &outptr, &outsize); - if (nconv == (size_t) -1) { - debug_printf("iconv Error\n"); - g_free(buf); - return g_strdup(str); - } - *outptr = '\0'; - iconv_close(cd); - - ret = g_strdup(buf); - g_free(buf); - - return ret; -#else - return g_strdup(str); -#endif -} - void strip_linefeed(gchar *text) { int i, j;