# HG changeset patch
# User Jeffrey Connelly
# Date 1183616185 0
# Node ID 13bba54b429d31da2c30e92ccf589ed02d3b5c30
# Parent 231b87b76da4c9d1b7b4adbf45e1a9310f4c7faa
Support sending some formatted text in instant messages.
Currently supported is:
* bold
* italic
* underline
* font face
Bold/italic/underline cannot be nested yet.
diff -r 231b87b76da4 -r 13bba54b429d libpurple/protocols/myspace/CHANGES
--- a/libpurple/protocols/myspace/CHANGES Thu Jul 05 06:10:30 2007 +0000
+++ b/libpurple/protocols/myspace/CHANGES Thu Jul 05 06:16:25 2007 +0000
@@ -5,6 +5,7 @@
* Time out if no data from server within a certain amount of time (keep alives).
* Remove "Sign on as hidden" option, and always set status to current status
when signing on.
+* Some support for sending formatted text.
2007-07-03 Jeff Connelly - 0.10
* On incoming instant messages, add support for:
diff -r 231b87b76da4 -r 13bba54b429d libpurple/protocols/myspace/myspace.c
--- a/libpurple/protocols/myspace/myspace.c Thu Jul 05 06:10:30 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.c Thu Jul 05 06:16:25 2007 +0000
@@ -282,6 +282,7 @@
gc = purple_account_get_connection(acct);
gc->proto_data = msim_session_new(acct);
+ gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_URLDESC;
/* Passwords are limited in length. */
if (strlen(acct->password) > MSIM_MAX_PASSWORD_LENGTH)
@@ -516,6 +517,8 @@
PurpleMessageFlags flags)
{
MsimSession *session;
+ gchar *message_msim;
+ int rc;
g_return_val_if_fail(gc != NULL, -1);
g_return_val_if_fail(who != NULL, -1);
@@ -527,7 +530,9 @@
g_return_val_if_fail(MSIM_SESSION_VALID(session), -1);
- if (msim_send_bm(session, who, message, MSIM_BM_INSTANT))
+ message_msim = html_to_msim_markup(message);
+
+ if (msim_send_bm(session, who, message_msim, MSIM_BM_INSTANT))
{
/* Return 1 to have Purple show this IM as being sent, 0 to not. I always
* return 1 even if the message could not be sent, since I don't know if
@@ -537,10 +542,13 @@
/* TODO: maybe if message is delayed, don't echo to conv window,
* but do echo it to conv window manually once it is actually
* sent? Would be complicated. */
- return 1;
+ rc = 1;
} else {
- return -1;
+ rc = -1;
}
+
+ g_free(message_msim);
+
/*
* In MySpace, you login with your email address, but don't talk to other
* users using their email address. So there is currently an asymmetry in the
@@ -553,6 +561,8 @@
* TODO: Make the sent IM's appear as from the user's username, instead of
* their email address. Purple uses the login (in MSIM, the email)--change this.
*/
+
+ return rc;
}
/** Send a buddy message of a given type.
@@ -678,7 +688,7 @@
g_string_prepend(gs_end, "");
}
- if (decor & MSIM_TEXT_ITALICS)
+ if (decor & MSIM_TEXT_ITALIC)
{
g_string_append(gs_begin, "");
g_string_append(gs_end, "");
@@ -811,12 +821,84 @@
*end = g_strdup("
");
}
-
-/** Convert an xmlnode of msim markup to an HTML string.
+/** Convert an individual msim markup tag to HTML. */
+void msim_markup_tag_to_html(xmlnode *root, gchar **begin, gchar **end)
+{
+ if (!strcmp(root->name, "f"))
+ {
+ msim_markup_f_to_html(root, begin, end);
+ } else if (!strcmp(root->name, "p")) {
+ msim_markup_p_to_html(root, begin, end);
+ } else if (!strcmp(root->name, "c")) {
+ msim_markup_c_to_html(root, begin, end);
+ } else if (!strcmp(root->name, "b")) {
+ msim_markup_b_to_html(root, begin, end);
+ } else if (!strcmp(root->name, "i")) {
+ msim_markup_i_to_html(root, begin, end);
+ } else {
+ purple_debug_info("msim", "msim_markup_tag_to_html: "
+ "unknown tag name=%s, ignoring", root->name);
+ *begin = g_strdup("");
+ *end = g_strdup("");
+ }
+}
+
+/** Convert an individual HTML tag to msim markup. */
+void html_tag_to_msim_markup(xmlnode *root, gchar **begin, gchar **end)
+{
+ /* TODO: TODO XXX */
+ /*
+ *begin = g_strdup_printf("[begin-%s]", root->name);
+ *end = g_strdup_printf("[end-%s]", root->name);
+ */
+
+ /* TODO: Coalesce nested tags into one tag!
+ * Currently, the 's' value will be overwritten when b/i/u is nested
+ * within another one, and only the inner-most formatting will be
+ * applied to the text. */
+ if (!strcmp(root->name, "b"))
+ {
+ *begin = g_strdup_printf("", MSIM_TEXT_BOLD);
+ *end = g_strdup("");
+ } else if (!strcmp(root->name, "i")) {
+ *begin = g_strdup_printf("", MSIM_TEXT_ITALIC);
+ *end = g_strdup("");
+ } else if (!strcmp(root->name, "u")) {
+ *begin = g_strdup_printf("", MSIM_TEXT_UNDERLINE);
+ *end = g_strdup("");
+ } else if (!strcmp(root->name, "font")) {
+ const gchar *size;
+ const gchar *face;
+
+ size = xmlnode_get_attrib(root, "size");
+ face = xmlnode_get_attrib(root, "face");
+
+ if (face && size)
+ *begin = g_strdup_printf("", face, size);
+ else if (face)
+ *begin = g_strdup_printf("", face);
+ else if (size)
+ *begin = g_strdup_printf("", face);
+ else
+ *begin = g_strdup("");
+
+ *end = g_strdup("");
+
+ /* TODO: color (bg uses ), emoticons */
+ } else {
+ *begin = g_strdup_printf("[%s]", root->name);
+ *end = g_strdup_printf("[/%s]", root->name);
+ }
+}
+
+/** Convert an xmlnode of msim markup or HTML to an HTML string or msim markup.
+ *
+ * @param f Function to convert tags.
+ *
* @return An HTML string. Caller frees.
*/
static gchar *
-msim_markup_xmlnode_to_html(xmlnode *root)
+msim_convert_xmlnode(xmlnode *root, MSIM_XMLNODE_CONVERT f)
{
xmlnode *node;
gchar *begin, *inner, *end;
@@ -825,28 +907,12 @@
if (!root || !root->name)
return g_strdup("");
- purple_debug_info("msim", "msim_markup_xmlnode_to_html: got root=%s\n",
+ purple_debug_info("msim", "msim_convert_xmlnode: got root=%s\n",
root->name);
begin = inner = end = NULL;
- if (!strcmp(root->name, "f"))
- {
- msim_markup_f_to_html(root, &begin, &end);
- } else if (!strcmp(root->name, "p")) {
- msim_markup_p_to_html(root, &begin, &end);
- } else if (!strcmp(root->name, "c")) {
- msim_markup_c_to_html(root, &begin, &end);
- } else if (!strcmp(root->name, "b")) {
- msim_markup_b_to_html(root, &begin, &end);
- } else if (!strcmp(root->name, "i")) {
- msim_markup_i_to_html(root, &begin, &end);
- } else {
- purple_debug_info("msim", "msim_markup_xmlnode_to_html: "
- "unknown tag name=%s, ignoring", root->name);
- begin = g_strdup("");
- end = g_strdup("");
- }
+ f(root, &begin, &end);
/* Loop over all child nodes. */
for (node = root->child; node != NULL; node = node->next)
@@ -859,7 +925,7 @@
case XMLNODE_TYPE_TAG:
/* A tag or tag with attributes. Recursively descend. */
- inner = msim_markup_xmlnode_to_html(node);
+ inner = msim_convert_xmlnode(node, f);
g_return_val_if_fail(inner != NULL, NULL);
purple_debug_info("msim", " ** node name=%s\n", node->name);
@@ -876,7 +942,7 @@
default:
purple_debug_info("msim",
- "msim_markup_xmlnode_to_html: strange node\n");
+ "msim_convert_xmlnode: strange node\n");
inner = g_strdup("");
}
}
@@ -892,11 +958,9 @@
return final;
}
-/** Convert MySpaceIM markup to Purple (HTML) markup.
- *
- * @return Purple markup string, must be g_free()'d. */
+/** Convert XML to something based on MSIM_XMLNODE_CONVERT. */
gchar *
-msim_markup_to_html(const gchar *raw)
+msim_convert_xml(const gchar *raw, MSIM_XMLNODE_CONVERT f)
{
xmlnode *root;
gchar *str;
@@ -909,12 +973,32 @@
return g_strdup(raw);
}
- str = msim_markup_xmlnode_to_html(root);
+ str = msim_convert_xmlnode(root, f);
purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str);
xmlnode_free(root);
- return g_strdup(str);
+ return str;
+}
+
+/** High-level function to convert MySpaceIM markup to Purple (HTML) markup.
+ *
+ * @return Purple markup string, must be g_free()'d. */
+gchar *
+msim_markup_to_html(const gchar *raw)
+{
+ return msim_convert_xml(raw,
+ (MSIM_XMLNODE_CONVERT)(msim_markup_tag_to_html));
+}
+
+/** High-level function to convert Purple (HTML) to MySpaceIM markup.
+ *
+ * @return HTML markup string, must be g_free()'d. */
+gchar *
+html_to_msim_markup(const gchar *raw)
+{
+ return msim_convert_xml(raw,
+ (MSIM_XMLNODE_CONVERT)(html_tag_to_msim_markup));
}
/**
@@ -1572,8 +1656,7 @@
purple_prpl_got_user_status(session->account, session->username, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
#endif
-
- /* Set status to current status. */
+ /* Notify servers of our current status. */
msim_set_status(session->account,
purple_account_get_active_status(session->account));
diff -r 231b87b76da4 -r 13bba54b429d libpurple/protocols/myspace/myspace.h
--- a/libpurple/protocols/myspace/myspace.h Thu Jul 05 06:10:30 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.h Thu Jul 05 06:16:25 2007 +0000
@@ -141,7 +141,7 @@
/* Text formatting bits for */
#define MSIM_TEXT_BOLD 1
-#define MSIM_TEXT_ITALICS 2
+#define MSIM_TEXT_ITALIC 2
#define MSIM_TEXT_UNDERLINE 4
/* Random number in every MsimSession, to ensure it is valid. */
@@ -205,7 +205,16 @@
void msim_unrecognized(MsimSession *session, MsimMessage *msg, gchar *note);
+
+typedef void (*MSIM_XMLNODE_CONVERT)(xmlnode *, gchar **, gchar **);
+void msim_markup_tag_to_html(xmlnode *root, gchar **begin, gchar **end);
+void html_tag_to_msim_markup(xmlnode *root, gchar **begin, gchar **end);
+gchar *msim_convert_xml(const gchar *raw, MSIM_XMLNODE_CONVERT f);
+
+/* High-level msim markup <=> html conversion functions. */
gchar *msim_markup_to_html(const gchar *raw);
+gchar *html_to_msim_markup(const gchar *raw);
+
int msim_incoming_im(MsimSession *session, MsimMessage *msg);
int msim_incoming_action(MsimSession *session, MsimMessage *msg);