Update of /cvsroot/gaim/gaim/src/protocols/msn
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12935/src/protocols/msn
Modified Files:
msn.c utils.c utils.h
Log Message:
Patch by David Vermeille to add outgoing formatting support for MSN. I'd
like to thank him, as a number of people have attempted this patch and
ended up discouraged when told it would break core/UI split. David went
ahead and stuck through it, and we now have some decent support. I also
realized during this that we weren't processing certain incoming colors
correctly, so that's taken care of now.
Index: msn.c
===================================================================
RCS file: /cvsroot/gaim/gaim/src/protocols/msn/msn.c,v
retrieving revision 1.264
retrieving revision 1.265
diff -u -d -p -r1.264 -r1.265
--- msn.c 27 Mar 2004 00:59:49 -0000 1.264
+++ msn.c 28 Mar 2004 21:38:22 -0000 1.265
@@ -487,6 +487,7 @@ msn_login(GaimAccount *account)
msn_http_session_init(session);
gc->proto_data = session;
+ gc->flags |= GAIM_CONNECTION_HTML;
gaim_connection_update_progress(gc, _("Connecting"), 0, MSN_CONNECT_STEPS);
@@ -532,14 +533,20 @@ msn_send_im(GaimConnection *gc, const ch
if (g_ascii_strcasecmp(who, gaim_account_get_username(account))) {
MsnMessage *msg;
MsnUser *user;
+ char *msgformat;
+ char *msgtext;
user = msn_user_new(session, who, NULL);
+ msn_import_html(message, &msgformat, &msgtext);
+
msg = msn_message_new();
msn_message_set_receiver(msg, user);
- msn_message_set_attr(msg, "X-MMS-IM-Format",
- "FN=MS%20Sans%20Serif; EF=; CO=0; PF=0");
- msn_message_set_body(msg, message);
+ msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat);
+ msn_message_set_body(msg, msgtext);
+
+ g_free(msgformat);
+ g_free(msgtext);
if (swboard != NULL) {
if (!msn_switchboard_send_msg(swboard, msg))
Index: utils.c
===================================================================
RCS file: /cvsroot/gaim/gaim/src/protocols/msn/utils.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -p -r1.9 -r1.10
--- utils.c 19 Mar 2004 20:17:31 -0000 1.9
+++ utils.c 28 Mar 2004 21:38:22 -0000 1.10
@@ -34,10 +34,12 @@ msn_parse_format(const char *mime, char
cur = strstr(mime, "FN=");
- if (cur && (*(cur = cur + 3) != ';')) {
+ if (cur && (*(cur = cur + 3) != ';'))
+ {
pre = g_string_append(pre, "<FONT FACE=\"");
- while (*cur && *cur != ';') {
+ while (*cur && *cur != ';')
+ {
pre = g_string_append_c(pre, *cur);
cur++;
}
@@ -48,8 +50,10 @@ msn_parse_format(const char *mime, char
cur = strstr(mime, "EF=");
- if (cur && (*(cur = cur + 3) != ';')) {
- while (*cur && *cur != ';') {
+ if (cur && (*(cur = cur + 3) != ';'))
+ {
+ while (*cur && *cur != ';')
+ {
pre = g_string_append_c(pre, '<');
pre = g_string_append_c(pre, *cur);
pre = g_string_append_c(pre, '>');
@@ -59,28 +63,42 @@ msn_parse_format(const char *mime, char
cur = strstr(mime, "CO=");
- if (cur && (*(cur = cur + 3) != ';')) {
+ if (cur && (*(cur = cur + 3) != ';'))
+ {
int i;
i = sscanf(cur, "%02x%02x%02x;", &colors[0], &colors[1], &colors[2]);
- if (i > 0) {
+ if (i > 0)
+ {
char tag[64];
- if (i == 1) {
- colors[2] = colors[0];
+ if (i == 1)
+ {
colors[1] = 0;
- colors[0] = 0;
+ colors[2] = 0;
}
- else if (i == 2) {
- colors[2] = colors[1];
- colors[1] = colors[0];
- colors[0] = 0;
+ else if (i == 2)
+ {
+ unsigned int temp = colors[0];
+
+ colors[0] = colors[1];
+ colors[1] = temp;
+ colors[2] = 0;
+ }
+ else if (i == 3)
+ {
+ unsigned int temp = colors[2];
+
+ colors[2] = colors[0];
+ colors[0] = temp;
}
g_snprintf(tag, sizeof(tag),
"<FONT COLOR=\"#%02hhx%02hhx%02hhx\">",
- colors[2], colors[1], colors[0]);
+ colors[0], colors[1], colors[2]);
+
+ gaim_debug_misc("msn", "Got: %s\n", tag);
pre = g_string_append(pre, tag);
post = g_string_prepend(post, "</FONT>");
@@ -103,3 +121,158 @@ msn_parse_format(const char *mime, char
else
g_free(cur);
}
+
+/*
+ * We need this because we're only supposed to encode spaces in the font
+ * names. gaim_url_encode() isn't acceptable.
+ */
+const char *
+encode_spaces(const char *str)
+{
+ static char buf[BUF_LEN];
+ const char *c;
+ char *d;
+
+ g_return_val_if_fail(str != NULL, NULL);
+
+ for (c = str, d = buf; *c != '\0'; c++)
+ {
+ if (*c == ' ')
+ {
+ *d++ = '%';
+ *d++ = '2';
+ *d++ = '0';
+ }
+ else
+ *d++ = *c;
+ }
+
+ return buf;
+}
+
+/*
+ * Taken from the zephyr plugin.
+ * This parses HTML formatting (put out by one of the gtkimhtml widgets
+ * and converts it to msn formatting. It doesn't deal with the tag closing,
+ * but gtkimhtml widgets give valid html.
+ * It currently deals properly with <b>, <u>, <i>, <font face=...>,
+ * <font color=...>.
+ * It ignores <font back=...> and <font size=...>
+ */
+void
+msn_import_html(const char *html, char **attributes, char **message)
+{
+ int len, retcount = 0;
+ const char *c;
+ char *msg;
+ char *fontface = NULL;
+ char fonteffect[4];
+ char fontcolor[7];
+
+ g_return_if_fail(html != NULL);
+ g_return_if_fail(attributes != NULL);
+ g_return_if_fail(message != NULL);
+
+ len = strlen(html);
+ msg = g_malloc0(len + 1);
+
+ memset(fontcolor, 0, sizeof(fontcolor));
+ memset(fonteffect, 0, sizeof(fontcolor));
+
+ for (c = html; *c != '\0';)
+ {
+ if (*c == '<')
+ {
+ if (!g_ascii_strncasecmp(c + 1, "i>", 2))
+ {
+ strcat(fonteffect, "I");
+ c += 3;
+ }
+ else if (!g_ascii_strncasecmp(c + 1, "b>", 2))
+ {
+ strcat(fonteffect, "B");
+ c += 3;
+ }
+ else if (!g_ascii_strncasecmp(c + 1, "u>", 2))
+ {
+ strcat(fonteffect, "U");
+ c += 3;
+ }
+ else if (!g_ascii_strncasecmp(c + 1, "a href=\"", 8))
+ {
+ c += 9;
+
+ while (g_ascii_strncasecmp(c, "\">", 2))
+ msg[retcount++] = *c++;
+
+ c += 2;
+
+ /* ignore descriptive string */
+ while (g_ascii_strncasecmp(c, "</a>", 4))
+ c++;
+
+ c += 4;
+ }
+ else if (!g_ascii_strncasecmp(c + 1, "font", 4))
+ {
+ c += 5;
+
+ while (!g_ascii_strncasecmp(c, " ", 1))
+ c++;
+
+ if (!g_ascii_strncasecmp(c, "color=\"#", 7))
+ {
+ c += 8;
+
+ fontcolor[0] = *(c + 4);
+ fontcolor[1] = *(c + 5);
+ fontcolor[2] = *(c + 2);
+ fontcolor[3] = *(c + 3);
+ fontcolor[4] = *c;
+ fontcolor[5] = *(c + 1);
+
+ c += 8;
+ }
+ else if (!g_ascii_strncasecmp(c, "face=\"", 6))
+ {
+ const char *end = NULL;
+ unsigned int namelen = 0;
+
+ c += 6;
+ end = strchr(c, '\"');
+ namelen = (unsigned int)(end - c);
+ fontface = g_strndup(c, namelen);
+ c = end + 2;
+ }
+ else
+ {
+ /* Drop all unrecognized/misparsed font tags */
+ while (g_ascii_strncasecmp(c, "\">", 2))
+ c++;
+
+ c += 2;
+ }
+ }
+ else
+ {
+ while (g_ascii_strncasecmp(c, ">", 1))
+ c++;
+
+ c++;
+ }
+ }
+ else
+ msg[retcount++] = *c++;
+ }
+
+ if (fontface == NULL)
+ fontface = g_strdup("MS Sans Serif");
+
+ *attributes = g_strdup_printf("FN=%s; EF=%s; CO=%s; PF=0",
+ encode_spaces(fontface),
+ fonteffect, fontcolor);
+ *message = g_strdup(msg);
+
+ g_free(fontface);
+ g_free(msg);
+}
Index: utils.h
===================================================================
RCS file: /cvsroot/gaim/gaim/src/protocols/msn/utils.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -p -r1.5 -r1.6
--- utils.h 19 Mar 2004 20:17:31 -0000 1.5
+++ utils.h 28 Mar 2004 21:38:22 -0000 1.6
@@ -33,4 +33,15 @@
*/
void msn_parse_format(const char *mime, char **pre_ret, char **post_ret);
+/**
+ * Parses the Gaim message formatting (html) into the MSN format.
+ *
+ * @param html The html message to format.
+ * @param attributes The returned attributes string.
+ * @param message The returned message string.
+ *
+ * @return The new message.
+ */
+void msn_import_html(const char *html, char **attributes, char **message);
+
#endif /* _MSN_UTILS_H_ */
|