comparison libpurple/protocols/jabber/message.c @ 29289:45795fd9c0a9

propagate from branch 'im.pidgin.pidgin' (head df25bed2c1c0d097b7f52fbfae76223d8552f0c3) to branch 'im.pidgin.cpw.attention_ui' (head 772ec7058f552b4a4384c599965f99566d903142)
author Marcus Lundblad <ml@update.uu.se>
date Thu, 07 May 2009 21:38:08 +0000
parents b2b1fa27047a aa29dac7924f
children 4c465be6c39c
comparison
equal deleted inserted replaced
29288:b2b1fa27047a 29289:45795fd9c0a9
948 return FALSE; 948 return FALSE;
949 break; 949 break;
950 } 950 }
951 } 951 }
952 952
953 static char *
954 jabber_message_smileyfy_xhtml(JabberMessage *jm, const char *xhtml)
955 {
956 PurpleAccount *account = purple_connection_get_account(jm->js->gc);
957 PurpleConversation *conv =
958 purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, jm->to,
959 account);
960
961 if (jabber_conv_support_custom_smileys(jm->js->gc, conv, jm->to)) {
962 GList *found_smileys = jabber_message_xhtml_find_smileys(xhtml);
963
964 if (found_smileys) {
965 gchar *smileyfied_xhtml = NULL;
966 const GList *iterator;
967
968 for (iterator = found_smileys; iterator ;
969 iterator = g_list_next(iterator)) {
970 const PurpleSmiley *smiley =
971 (PurpleSmiley *) iterator->data;
972 const gchar *shortcut = purple_smiley_get_shortcut(smiley);
973 const JabberData *data =
974 jabber_data_find_local_by_alt(shortcut);
975
976 /* the object has not been sent before */
977 if (!data) {
978 PurpleStoredImage *image =
979 purple_smiley_get_stored_image(smiley);
980 const gchar *ext = purple_imgstore_get_extension(image);
981 JabberStream *js = jm->js;
982
983 JabberData *new_data =
984 jabber_data_create_from_data(purple_imgstore_get_data(image),
985 purple_imgstore_get_size(image),
986 jabber_message_get_mimetype_from_ext(ext), js);
987 purple_debug_info("jabber",
988 "cache local smiley alt = %s, cid = %s\n",
989 shortcut, jabber_data_get_cid(new_data));
990 jabber_data_associate_local(new_data, shortcut);
991 }
992 }
993
994 smileyfied_xhtml =
995 jabber_message_get_smileyfied_xhtml(xhtml, found_smileys);
996 g_list_free(found_smileys);
997
998 return smileyfied_xhtml;
999 }
1000 }
1001
1002 return NULL;
1003 }
1004
953 void jabber_message_send(JabberMessage *jm) 1005 void jabber_message_send(JabberMessage *jm)
954 { 1006 {
955 xmlnode *message, *child; 1007 xmlnode *message, *child;
956 const char *type = NULL; 1008 const char *type = NULL;
957 1009
1033 child = xmlnode_new_child(message, "body"); 1085 child = xmlnode_new_child(message, "body");
1034 xmlnode_insert_data(child, jm->body, -1); 1086 xmlnode_insert_data(child, jm->body, -1);
1035 } 1087 }
1036 1088
1037 if(jm->xhtml) { 1089 if(jm->xhtml) {
1038 PurpleAccount *account = purple_connection_get_account(jm->js->gc); 1090 if ((child = xmlnode_from_str(jm->xhtml, -1))) {
1039 PurpleConversation *conv =
1040 purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, jm->to,
1041 account);
1042
1043 if (jabber_conv_support_custom_smileys(jm->js->gc, conv, jm->to)) {
1044 GList *found_smileys = jabber_message_xhtml_find_smileys(jm->xhtml);
1045
1046 if (found_smileys) {
1047 gchar *smileyfied_xhtml = NULL;
1048 const GList *iterator;
1049
1050 for (iterator = found_smileys; iterator ;
1051 iterator = g_list_next(iterator)) {
1052 const PurpleSmiley *smiley =
1053 (PurpleSmiley *) iterator->data;
1054 const gchar *shortcut = purple_smiley_get_shortcut(smiley);
1055 const JabberData *data =
1056 jabber_data_find_local_by_alt(shortcut);
1057
1058 /* the object has not been sent before */
1059 if (!data) {
1060 PurpleStoredImage *image =
1061 purple_smiley_get_stored_image(smiley);
1062 const gchar *ext = purple_imgstore_get_extension(image);
1063 JabberStream *js = jm->js;
1064
1065 JabberData *new_data =
1066 jabber_data_create_from_data(purple_imgstore_get_data(image),
1067 purple_imgstore_get_size(image),
1068 jabber_message_get_mimetype_from_ext(ext), js);
1069 purple_debug_info("jabber",
1070 "cache local smiley alt = %s, cid = %s\n",
1071 shortcut, jabber_data_get_cid(new_data));
1072 jabber_data_associate_local(new_data, shortcut);
1073 }
1074 }
1075
1076 smileyfied_xhtml =
1077 jabber_message_get_smileyfied_xhtml(jm->xhtml, found_smileys);
1078 child = xmlnode_from_str(smileyfied_xhtml, -1);
1079 g_free(smileyfied_xhtml);
1080 g_list_free(found_smileys);
1081 } else {
1082 child = xmlnode_from_str(jm->xhtml, -1);
1083 }
1084 } else {
1085 child = xmlnode_from_str(jm->xhtml, -1);
1086 }
1087 if(child) {
1088 xmlnode_insert_child(message, child); 1091 xmlnode_insert_child(message, child);
1089 } else { 1092 } else {
1090 purple_debug(PURPLE_DEBUG_ERROR, "jabber", 1093 purple_debug(PURPLE_DEBUG_ERROR, "jabber",
1091 "XHTML translation/validation failed, returning: %s\n", 1094 "XHTML translation/validation failed, returning: %s\n",
1092 jm->xhtml); 1095 jm->xhtml);
1096 jabber_send(jm->js, message); 1099 jabber_send(jm->js, message);
1097 1100
1098 xmlnode_free(message); 1101 xmlnode_free(message);
1099 } 1102 }
1100 1103
1104 /*
1105 * Compare the XHTML and plain strings passed in for "equality". Any HTML markup
1106 * other than <br/> (matches a newline) in the XHTML will cause this to return
1107 * FALSE.
1108 */
1109 static gboolean
1110 jabber_xhtml_plain_equal(const char *xhtml_escaped,
1111 const char *plain)
1112 {
1113 int i = 0;
1114 int j = 0;
1115 gboolean ret;
1116 char *xhtml = purple_unescape_html(xhtml_escaped);
1117
1118 while (xhtml[i] && plain[j]) {
1119 if (xhtml[i] == plain[j]) {
1120 i += 1;
1121 j += 1;
1122 continue;
1123 }
1124
1125 if (plain[j] == '\n' && !strncmp(xhtml+i, "<br/>", 5)) {
1126 i += 5;
1127 j += 1;
1128 continue;
1129 }
1130
1131 g_free(xhtml);
1132 return FALSE;
1133 }
1134
1135 /* Are we at the end of both strings? */
1136 ret = (xhtml[i] == plain[j]) && (xhtml[i] == '\0');
1137 g_free(xhtml);
1138 return ret;
1139 }
1140
1101 int jabber_message_send_im(PurpleConnection *gc, const char *who, const char *msg, 1141 int jabber_message_send_im(PurpleConnection *gc, const char *who, const char *msg,
1102 PurpleMessageFlags flags) 1142 PurpleMessageFlags flags)
1103 { 1143 {
1104 JabberMessage *jm; 1144 JabberMessage *jm;
1105 JabberBuddy *jb; 1145 JabberBuddy *jb;
1106 JabberBuddyResource *jbr; 1146 JabberBuddyResource *jbr;
1107 char *buf;
1108 char *xhtml; 1147 char *xhtml;
1148 char *tmp;
1109 char *resource; 1149 char *resource;
1110 1150
1111 if(!who || !msg) 1151 if(!who || !msg)
1112 return 0; 1152 return 0;
1113 1153
1138 1178
1139 if(jbr->chat_states != JABBER_CHAT_STATES_SUPPORTED) 1179 if(jbr->chat_states != JABBER_CHAT_STATES_SUPPORTED)
1140 jm->typing_style |= JM_TS_JEP_0022; 1180 jm->typing_style |= JM_TS_JEP_0022;
1141 } 1181 }
1142 1182
1143 buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); 1183 purple_markup_html_to_xhtml(msg, &xhtml, &jm->body);
1144 1184 tmp = jabber_message_smileyfy_xhtml(jm, xhtml);
1145 purple_markup_html_to_xhtml(buf, &xhtml, &jm->body); 1185 if (tmp) {
1146 g_free(buf);
1147
1148 if(!jbr || jbr->capabilities & JABBER_CAP_XHTML)
1149 jm->xhtml = xhtml;
1150 else
1151 g_free(xhtml); 1186 g_free(xhtml);
1187 xhtml = tmp;
1188 }
1189
1190 if ((!jbr || jbr->capabilities & JABBER_CAP_XHTML) &&
1191 !jabber_xhtml_plain_equal(xhtml, jm->body))
1192 jm->xhtml = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", xhtml);
1193
1194 g_free(xhtml);
1152 1195
1153 jabber_message_send(jm); 1196 jabber_message_send(jm);
1154 jabber_message_free(jm); 1197 jabber_message_free(jm);
1155 return 1; 1198 return 1;
1156 } 1199 }
1158 int jabber_message_send_chat(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags flags) 1201 int jabber_message_send_chat(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags flags)
1159 { 1202 {
1160 JabberChat *chat; 1203 JabberChat *chat;
1161 JabberMessage *jm; 1204 JabberMessage *jm;
1162 JabberStream *js; 1205 JabberStream *js;
1163 char *buf; 1206 char *xhtml;
1164 1207
1165 if(!msg || !gc) 1208 if(!msg || !gc)
1166 return 0; 1209 return 0;
1167 1210
1168 js = gc->proto_data; 1211 js = gc->proto_data;
1175 jm->js = gc->proto_data; 1218 jm->js = gc->proto_data;
1176 jm->type = JABBER_MESSAGE_GROUPCHAT; 1219 jm->type = JABBER_MESSAGE_GROUPCHAT;
1177 jm->to = g_strdup_printf("%s@%s", chat->room, chat->server); 1220 jm->to = g_strdup_printf("%s@%s", chat->room, chat->server);
1178 jm->id = jabber_get_next_id(jm->js); 1221 jm->id = jabber_get_next_id(jm->js);
1179 1222
1180 buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); 1223 purple_markup_html_to_xhtml(msg, &xhtml, &jm->body);
1181 purple_markup_html_to_xhtml(buf, &jm->xhtml, &jm->body); 1224
1182 g_free(buf); 1225 if (chat->xhtml && !jabber_xhtml_plain_equal(xhtml, jm->body))
1183 1226 jm->xhtml = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", xhtml);
1184 if(!chat->xhtml) { 1227
1185 g_free(jm->xhtml); 1228 g_free(xhtml);
1186 jm->xhtml = NULL;
1187 }
1188 1229
1189 jabber_message_send(jm); 1230 jabber_message_send(jm);
1190 jabber_message_free(jm); 1231 jabber_message_free(jm);
1191 1232
1192 return 1; 1233 return 1;
1234 jabber_message_free(jm); 1275 jabber_message_free(jm);
1235 1276
1236 return 0; 1277 return 0;
1237 } 1278 }
1238 1279
1239 void jabber_message_conv_closed(JabberStream *js, const char *who)
1240 {
1241 JabberMessage *jm;
1242 if (!purple_prefs_get_bool("/purple/conversations/im/send_typing"))
1243 return;
1244
1245 jm = g_new0(JabberMessage, 1);
1246 jm->js = js;
1247 jm->type = JABBER_MESSAGE_CHAT;
1248 jm->to = g_strdup(who);
1249 jm->id = jabber_get_next_id(jm->js);
1250 jm->typing_style = JM_TS_JEP_0085;
1251 jm->chat_state = JM_STATE_GONE;
1252 jabber_message_send(jm);
1253 jabber_message_free(jm);
1254 }
1255
1256 gboolean jabber_buzz_isenabled(JabberStream *js, const gchar *namespace) { 1280 gboolean jabber_buzz_isenabled(JabberStream *js, const gchar *namespace) {
1257 return js->allowBuzz; 1281 return js->allowBuzz;
1258 } 1282 }
1259 1283
1260 gboolean jabber_custom_smileys_isenabled(JabberStream *js, const gchar *namespace) 1284 gboolean jabber_custom_smileys_isenabled(JabberStream *js, const gchar *namespace)