| 675 msim_msg_free(msg); |
675 msim_msg_free(msg); |
| 676 |
676 |
| 677 return rc; |
677 return rc; |
| 678 } |
678 } |
| 679 |
679 |
| |
680 /** Convert a font point size to purple's HTML font size. |
| |
681 * |
| |
682 * Based on libpurple/protocols/bonjour/jabber.c. |
| |
683 */ |
| |
684 static guint |
| |
685 msim_font_size_to_purple(int size) |
| |
686 { |
| |
687 if (size > 24) { |
| |
688 return 7; |
| |
689 } else if (size >= 21) { |
| |
690 return 6; |
| |
691 } else if (size >= 17) { |
| |
692 return 5; |
| |
693 } else if (size >= 14) { |
| |
694 return 4; |
| |
695 } else if (size >= 12) { |
| |
696 return 3; |
| |
697 } else if (size >= 10) { |
| |
698 return 2; |
| |
699 } |
| |
700 |
| |
701 return 1; |
| |
702 } |
| |
703 |
| |
704 /** Convert a msim markup font height to points. */ |
| |
705 static guint |
| |
706 msim_font_height_to_point(guint height) |
| |
707 { |
| |
708 /* See also: libpurple/protocols/bonjour/jabber.c |
| |
709 * _font_size_ichat_to_purple */ |
| |
710 switch (height) |
| |
711 { |
| |
712 case 11: return 8; |
| |
713 case 12: return 9; |
| |
714 case 13: return 10; |
| |
715 case 14: |
| |
716 case 15: return 11; |
| |
717 case 16: return 12; |
| |
718 case 17: |
| |
719 case 18: return 13; |
| |
720 case 19: return 14; |
| |
721 case 20: return 15; |
| |
722 case 21: return 16; |
| |
723 default: return 12; |
| |
724 } |
| |
725 } |
| |
726 |
| |
727 /** Convert an xmlnode of msim markup to an HTML string. |
| |
728 * @return An HTML string. Caller frees. |
| |
729 */ |
| |
730 static gchar *msim_markup_xmlnode_to_html(xmlnode *root) |
| |
731 { |
| |
732 xmlnode *node; |
| |
733 gchar *begin, *inner, *end; |
| |
734 gchar *final; |
| |
735 |
| |
736 if (!root) |
| |
737 return g_strdup(""); |
| |
738 |
| |
739 purple_debug_info("msim", "msim_markup_xmlnode_to_html: got root=%s\n", |
| |
740 root->name); |
| |
741 |
| |
742 begin = inner = end = NULL; |
| |
743 |
| |
744 if (!strcmp(root->name, "f")) |
| |
745 { |
| |
746 const gchar *face, *height_str, *decor_str; |
| |
747 GString *gs_end, *gs_begin; |
| |
748 guint decor, height; |
| |
749 |
| |
750 face = xmlnode_get_attrib(root, "n"); |
| |
751 height_str = xmlnode_get_attrib(root, "h"); |
| |
752 decor_str = xmlnode_get_attrib(root, "s"); |
| |
753 |
| |
754 if (height_str) |
| |
755 height = atol(height_str); |
| |
756 else |
| |
757 height = 12; |
| |
758 |
| |
759 if (decor_str) |
| |
760 decor = atol(decor_str); |
| |
761 else |
| |
762 decor = 0; |
| |
763 |
| |
764 gs_begin = g_string_new(""); |
| |
765 g_string_printf(gs_begin, "<font face='%s' size='%d'>", face, |
| |
766 msim_font_size_to_purple(msim_font_height_to_point(height))); |
| |
767 gs_end = g_string_new("</font>"); |
| |
768 |
| |
769 if (decor & 1) |
| |
770 { |
| |
771 g_string_append(gs_begin, "<b>"); |
| |
772 g_string_prepend(gs_end, "</b>"); |
| |
773 } |
| |
774 |
| |
775 if (decor & 2) |
| |
776 { |
| |
777 g_string_append(gs_begin, "<i>"); |
| |
778 g_string_append(gs_end, "</i>"); |
| |
779 } |
| |
780 |
| |
781 if (decor & 4) |
| |
782 { |
| |
783 g_string_append(gs_begin, "<u>"); |
| |
784 g_string_append(gs_end, "</u>"); |
| |
785 } |
| |
786 |
| |
787 |
| |
788 begin = gs_begin->str; |
| |
789 end = gs_end->str; |
| |
790 } else { |
| |
791 purple_debug_info("msim", "msim_markup_xmlnode_to_html: " |
| |
792 "unknown tag name=%s, ignoring", root->name); |
| |
793 begin = g_strdup(""); |
| |
794 end = g_strdup(""); |
| |
795 } |
| |
796 |
| |
797 /* Loop over all child nodes. */ |
| |
798 for (node = root->child; node != NULL; node = node->next) |
| |
799 { |
| |
800 switch (node->type) |
| |
801 { |
| |
802 case XMLNODE_TYPE_ATTRIB: |
| |
803 /* Attributes handled above. */ |
| |
804 break; |
| |
805 |
| |
806 case XMLNODE_TYPE_TAG: |
| |
807 /* A tag or tag with attributes. Recursively descend. */ |
| |
808 inner = msim_markup_xmlnode_to_html(node); |
| |
809 |
| |
810 purple_debug_info("msim", " ** node name=%s\n", node->name); |
| |
811 break; |
| |
812 |
| |
813 |
| |
814 case XMLNODE_TYPE_DATA: |
| |
815 /* Literal text. */ |
| |
816 inner = g_new0(char, node->data_sz + 1); |
| |
817 strncpy(inner, node->data, node->data_sz); |
| |
818 inner[node->data_sz + 1] = 0; |
| |
819 |
| |
820 purple_debug_info("msim", " ** node data=%s (%s)\n", inner, |
| |
821 node->data); |
| |
822 break; |
| |
823 |
| |
824 default: |
| |
825 purple_debug_info("msim", |
| |
826 "msim_markup_xmlnode_to_html: strange node\n"); |
| |
827 inner = g_strdup(""); |
| |
828 } |
| |
829 } |
| |
830 |
| |
831 final = g_strconcat(begin, inner, end, NULL); |
| |
832 g_free(begin); |
| |
833 g_free(inner); |
| |
834 g_free(end); |
| |
835 |
| |
836 purple_debug_info("msim", "msim_markup_xmlnode_to_gtkhtml: RETURNING %s\n", |
| |
837 final); |
| |
838 |
| |
839 return final; |
| |
840 } |
| |
841 |
| |
842 /** Convert MySpaceIM markup to GtkIMHtml markup. |
| |
843 * TODO |
| |
844 * |
| |
845 * @return GtkIMHtml markup string, must be g_free()'d. */ |
| |
846 gchar * |
| |
847 msim_markup_to_html(const gchar *raw) |
| |
848 { |
| |
849 xmlnode *root; |
| |
850 gchar *str; |
| |
851 |
| |
852 root = xmlnode_from_str(raw, -1); |
| |
853 if (!root) |
| |
854 { |
| |
855 purple_debug_info("msim", "msim_markup_to_html: couldn't parse " |
| |
856 "%s as XML, returning raw\n", raw); |
| |
857 return g_strdup(raw); |
| |
858 } |
| |
859 |
| |
860 str = msim_markup_xmlnode_to_html(root); |
| |
861 purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str); |
| |
862 |
| |
863 xmlnode_free(root); |
| |
864 |
| |
865 return g_strdup(str); |
| |
866 } |
| |
867 |
| 680 /** |
868 /** |
| 681 * Handle an incoming instant message. |
869 * Handle an incoming instant message. |
| 682 * |
870 * |
| 683 * @param session The session |
871 * @param session The session |
| 684 * @param msg Message from the server, containing 'f' (userid from) and 'msg'. |
872 * @param msg Message from the server, containing 'f' (userid from) and 'msg'. |
| 687 * @return TRUE if successful. |
875 * @return TRUE if successful. |
| 688 */ |
876 */ |
| 689 gboolean |
877 gboolean |
| 690 msim_incoming_im(MsimSession *session, MsimMessage *msg) |
878 msim_incoming_im(MsimSession *session, MsimMessage *msg) |
| 691 { |
879 { |
| 692 gchar *username; |
880 gchar *username, *msg_msim_markup, *msg_purple_markup; |
| 693 gchar *msg_text; |
|
| 694 |
881 |
| 695 username = msim_msg_get_string(msg, "_username"); |
882 username = msim_msg_get_string(msg, "_username"); |
| 696 msg_text = msim_msg_get_string(msg, "msg"); |
883 msg_msim_markup = msim_msg_get_string(msg, "msg"); |
| 697 |
884 |
| 698 /* TODO: replace msim-markup with gtkimhtml. */ |
885 msg_purple_markup = msim_markup_to_html(msg_msim_markup); |
| 699 |
886 g_free(msg_msim_markup); |
| 700 serv_got_im(session->gc, username, msg_text, PURPLE_MESSAGE_RECV, time(NULL)); |
887 |
| |
888 serv_got_im(session->gc, username, msg_purple_markup, |
| |
889 PURPLE_MESSAGE_RECV, time(NULL)); |
| 701 |
890 |
| 702 g_free(username); |
891 g_free(username); |
| 703 g_free(msg_text); |
892 g_free(msg_purple_markup); |
| 704 |
893 |
| 705 return TRUE; |
894 return TRUE; |
| 706 } |
895 } |
| 707 |
896 |
| 708 /** |
897 /** |
| 2357 else |
2548 else |
| 2358 { |
2549 { |
| 2359 purple_debug_info("msim", "msim_test_all - all tests passed!\n"); |
2550 purple_debug_info("msim", "msim_test_all - all tests passed!\n"); |
| 2360 } |
2551 } |
| 2361 exit(0); |
2552 exit(0); |
| |
2553 } |
| |
2554 |
| |
2555 int |
| |
2556 msim_test_xml(void) |
| |
2557 { |
| |
2558 gchar *msg_text; |
| |
2559 xmlnode *root, *n; |
| |
2560 guint failures; |
| |
2561 char *s; |
| |
2562 int len; |
| |
2563 |
| |
2564 failures = 0; |
| |
2565 |
| |
2566 msg_text = "<p><f n=\"Arial\" h=\"12\">woo!</f>xxx<c v='black'>yyy</c></p>"; |
| |
2567 |
| |
2568 purple_debug_info("msim", "msim_test_xml: msg_text=%s\n", msg_text); |
| |
2569 |
| |
2570 root = xmlnode_from_str(msg_text, -1); |
| |
2571 if (!root) |
| |
2572 { |
| |
2573 purple_debug_info("msim", "there is no root\n"); |
| |
2574 exit(0); |
| |
2575 } |
| |
2576 |
| |
2577 purple_debug_info("msim", "root name=%s, child name=%s\n", root->name, |
| |
2578 root->child->name); |
| |
2579 |
| |
2580 purple_debug_info("msim", "last child name=%s\n", root->lastchild->name); |
| |
2581 purple_debug_info("msim", "Root xml=%s\n", |
| |
2582 xmlnode_to_str(root, &len)); |
| |
2583 purple_debug_info("msim", "Child xml=%s\n", |
| |
2584 xmlnode_to_str(root->child, &len)); |
| |
2585 purple_debug_info("msim", "Lastchild xml=%s\n", |
| |
2586 xmlnode_to_str(root->lastchild, &len)); |
| |
2587 purple_debug_info("msim", "Next xml=%s\n", |
| |
2588 xmlnode_to_str(root->next, &len)); |
| |
2589 purple_debug_info("msim", "Next data=%s\n", |
| |
2590 xmlnode_get_data(root->next)); |
| |
2591 purple_debug_info("msim", "Child->next xml=%s\n", |
| |
2592 xmlnode_to_str(root->child->next, &len)); |
| |
2593 |
| |
2594 for (n = root->child; n; n = n->next) |
| |
2595 { |
| |
2596 if (n->name) |
| |
2597 { |
| |
2598 purple_debug_info("msim", " ** n=%s\n",n->name); |
| |
2599 } else { |
| |
2600 purple_debug_info("msim", " ** n data=%s\n", n->data); |
| |
2601 } |
| |
2602 } |
| |
2603 |
| |
2604 purple_debug_info("msim", "root data=%s, child data=%s, child 'h'=%s\n", |
| |
2605 xmlnode_get_data(root), |
| |
2606 xmlnode_get_data(root->child), |
| |
2607 xmlnode_get_attrib(root->child, "h")); |
| |
2608 |
| |
2609 |
| |
2610 for (n = root->child; |
| |
2611 n != NULL; |
| |
2612 n = n->next) |
| |
2613 { |
| |
2614 purple_debug_info("msim", "next name=%s\n", n->name); |
| |
2615 } |
| |
2616 |
| |
2617 s = xmlnode_to_str(root, &len); |
| |
2618 s[len] = 0; |
| |
2619 |
| |
2620 purple_debug_info("msim", "str: %s\n", s); |
| |
2621 g_free(s); |
| |
2622 |
| |
2623 xmlnode_free(root); |
| |
2624 |
| |
2625 exit(0); |
| |
2626 |
| |
2627 return failures; |
| 2362 } |
2628 } |
| 2363 |
2629 |
| 2364 /** Test MsimMessage for basic functionality. */ |
2630 /** Test MsimMessage for basic functionality. */ |
| 2365 int |
2631 int |
| 2366 msim_test_msg(void) |
2632 msim_test_msg(void) |