Mercurial > pidgin
annotate src/protocols/jabber/message.c @ 12645:fc28451f5d96
[gaim-migrate @ 14983]
SF Patch #1314512 from Sadrul (who has a patch for everything)
"This patch introduces a flag for protocol plugins that
support offline messages (like Y!M and ICQ). This was
encouraged by the following conversation:
<sadrul> should offline buddies be listed/enabled in
the send-to menu?
<rekkanoryo> i would think only for protocols that
support offline messaging, if it's indicated that the
buddy is offline
-- <snip> --
<Bleeter> sadrul: personally, I'd like to see a
'supports offline' flag of some description
<Bleeter> one could then redirect (via plugins) through
email or alternative methods
<Bleeter> just a thought
<Paco-Paco> yeah, that sounds like a reasonble thing to have
This patch uses this flag to disable the buddies in the
send-to menu who are offline and the protocol doesn't
support offline messages."
I made this make the label insensitive instead of the whole menuitem. This
should address SimGuy's concerns about inconsistency (i.e. you could create a
conversation with someone via the buddy list that you couldn't create via the
Send To menu). I also hacked up some voodoo to show the label as sensitive when
moused-over, as that looks better (given the label-insensitive thing is itself a
hack). I think this works quite well.
BUG NOTE:
This makes more obvious an existing bug. The Send To menu isn't updated when
buddies sign on or off or change status (at least under some circumstances).
We need to fix that anyway, so I'm not going to let it hold up this commit.
Switching tabs will clear it up. I'm thinking we just might want to build the
contents of that menu when it is selected. That would save us a mess of
inefficient signal callbacks that update the Send To menus in open windows all
the time.
AIM NOTE:
This assumes that AIM can't offline message. That's not strictly true. You can
message invisible users on AIM. However, by design, we can't tell when a user
is invisible without resorting to dirty hackery. In practice, this isn't a
problem, as you can still select the AIM user from the menu. And really, how
often will you be choosing the Invisible contact, rather than the user going
Invisible in the middle of a conversation or IMing you while they're Invisible?
JABBER NOTE:
This assumes that Jabber can always offline message. This isn't strictly true.
Sadrul said:
I have updated Jabber according to this link which seems to
talk about how to determine the existence offline-message
support in a server:
http://www.jabber.org/jeps/jep-0013.html#discover
However, jabber.org doesn't seem to send the required
info. So I am not sure about it.
He later said:
I talked to Nathan and he said offline message support is
mostly assumed for most jabber servers. GTalk doesn't yet
support it, but they are working on it. So I have made
jabber to always return TRUE.
If there is truly no way to detect offline messaging capability, then this is
an acceptable solution. We could special case Google Talk because of its
popularity, and remove that later. It's probably not worth it though.
MSN NOTE:
This assumes that MSN can never offline message. That's effectively true, but
to be technically correct, MSN can offline message if there's already a
switchboard conversation open with a user. We could write an offline_message
function in the MSN prpl to detect that, but it'd be of limited usefulness,
especially given that under most circumstances (where this might matter), the
switchboard connection will be closed almost immediately.
CVS NOTE:
I'm writing to share a tragic little story.
I have a PC that I use for Gaim development. One day, I was writing a commit
message on it, when all of a suddent it went berserk. The screen started
flashing, and the whole commit message just disappeared. All of it. And it was
a good commit message! I had to cram and rewrite it really quickly. Needless to
say, my rushed commit message wasn't nearly as good, and I blame the PC for that.
Seriously, though, what kind of version control system loses your commit
message on a broken connection to the server? Stupid!
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Fri, 23 Dec 2005 19:26:04 +0000 |
parents | 4d3119205a33 |
children | fcde3faa1f57 |
rev | line source |
---|---|
7014 | 1 /* |
2 * gaim - Jabber Protocol Plugin | |
3 * | |
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 #include "internal.h" | |
22 | |
23 #include "debug.h" | |
24 #include "notify.h" | |
25 #include "server.h" | |
7095
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7014
diff
changeset
|
26 #include "util.h" |
7014 | 27 |
28 #include "buddy.h" | |
29 #include "chat.h" | |
30 #include "message.h" | |
31 #include "xmlnode.h" | |
32 | |
33 #define JABBER_TYPING_NOTIFY_INT 15 | |
34 | |
35 void jabber_message_free(JabberMessage *jm) | |
36 { | |
37 if(jm->from) | |
38 g_free(jm->from); | |
39 if(jm->to) | |
40 g_free(jm->to); | |
41 if(jm->subject) | |
42 g_free(jm->subject); | |
43 if(jm->body) | |
44 g_free(jm->body); | |
45 if(jm->xhtml) | |
46 g_free(jm->xhtml); | |
47 if(jm->password) | |
48 g_free(jm->password); | |
7145 | 49 if(jm->etc) |
50 g_list_free(jm->etc); | |
7014 | 51 |
52 g_free(jm); | |
53 } | |
54 | |
7145 | 55 static void handle_chat(JabberMessage *jm) |
7014 | 56 { |
57 JabberID *jid = jabber_id_new(jm->from); | |
58 char *from; | |
59 | |
60 JabberBuddy *jb; | |
61 JabberBuddyResource *jbr; | |
62 | |
7310 | 63 if(!jid) |
64 return; | |
65 | |
7014 | 66 jb = jabber_buddy_find(jm->js, jm->from, TRUE); |
7306 | 67 jbr = jabber_buddy_find_resource(jb, jid->resource); |
7014 | 68 |
8043 | 69 if(jabber_find_unnormalized_conv(jm->from, jm->js->gc->account)) { |
7014 | 70 from = g_strdup(jm->from); |
7258 | 71 } else if(jid->node) { |
10490 | 72 if(jid->resource) { |
73 GaimConversation *conv; | |
7258 | 74 |
10490 | 75 from = g_strdup_printf("%s@%s", jid->node, jid->domain); |
76 conv = jabber_find_unnormalized_conv(from, jm->js->gc->account); | |
77 if(conv) { | |
78 gaim_conversation_set_name(conv, jm->from); | |
79 } | |
80 g_free(from); | |
81 } | |
7258 | 82 from = g_strdup(jm->from); |
83 } else { | |
7014 | 84 from = g_strdup(jid->domain); |
7258 | 85 } |
7014 | 86 |
87 if(!jm->xhtml && !jm->body) { | |
88 if(jm->events & JABBER_MESSAGE_EVENT_COMPOSING) | |
89 serv_got_typing(jm->js->gc, from, 0, GAIM_TYPING); | |
90 else | |
91 serv_got_typing_stopped(jm->js->gc, from); | |
92 } else { | |
8400 | 93 if(jbr) { |
94 if(jm->events & JABBER_MESSAGE_EVENT_COMPOSING) | |
95 jbr->capabilities |= JABBER_CAP_COMPOSING; | |
96 if(jbr->thread_id) | |
97 g_free(jbr->thread_id); | |
98 jbr->thread_id = g_strdup(jbr->thread_id); | |
99 } | |
7014 | 100 serv_got_im(jm->js->gc, from, jm->xhtml ? jm->xhtml : jm->body, 0, |
101 jm->sent); | |
102 } | |
103 | |
104 g_free(from); | |
105 jabber_id_free(jid); | |
106 } | |
107 | |
7145 | 108 static void handle_headline(JabberMessage *jm) |
109 { | |
110 char *title; | |
111 GString *body = g_string_new(""); | |
112 GList *etc; | |
113 | |
114 title = g_strdup_printf(_("Message from %s"), jm->from); | |
115 | |
116 if(jm->xhtml) | |
117 g_string_append(body, jm->xhtml); | |
118 else if(jm->body) | |
119 g_string_append(body, jm->body); | |
120 | |
121 for(etc = jm->etc; etc; etc = etc->next) { | |
122 xmlnode *x = etc->data; | |
123 const char *xmlns = xmlnode_get_attrib(x, "xmlns"); | |
124 if(xmlns && !strcmp(xmlns, "jabber:x:oob")) { | |
125 xmlnode *url, *desc; | |
126 char *urltxt, *desctxt; | |
127 | |
128 url = xmlnode_get_child(x, "url"); | |
129 desc = xmlnode_get_child(x, "desc"); | |
130 | |
131 if(!url || !desc) | |
132 continue; | |
133 | |
134 urltxt = xmlnode_get_data(url); | |
135 desctxt = xmlnode_get_data(desc); | |
136 | |
137 /* I'm all about ugly hacks */ | |
138 if(body->len && !strcmp(body->str, jm->body)) | |
139 g_string_printf(body, "<a href='%s'>%s</a>", | |
140 urltxt, desctxt); | |
141 else | |
142 g_string_append_printf(body, "<br/><a href='%s'>%s</a>", | |
143 urltxt, desctxt); | |
144 | |
145 g_free(urltxt); | |
146 g_free(desctxt); | |
147 } | |
148 } | |
149 | |
150 gaim_notify_formatted(jm->js->gc, title, jm->subject ? jm->subject : title, | |
151 NULL, body->str, NULL, NULL); | |
152 | |
153 g_free(title); | |
154 g_string_free(body, TRUE); | |
155 } | |
156 | |
157 static void handle_groupchat(JabberMessage *jm) | |
7014 | 158 { |
159 JabberID *jid = jabber_id_new(jm->from); | |
7310 | 160 JabberChat *chat; |
161 | |
162 if(!jid) | |
163 return; | |
164 | |
165 chat = jabber_chat_find(jm->js, jid->node, jid->domain); | |
7014 | 166 |
167 if(!chat) | |
168 return; | |
169 | |
7971 | 170 if(jm->subject) { |
7183 | 171 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(chat->conv), jid->resource, |
172 jm->subject); | |
7971 | 173 if(!jm->xhtml && !jm->body) { |
9762 | 174 char *msg, *tmp, *tmp2; |
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10607
diff
changeset
|
175 tmp = g_markup_escape_text(jm->subject, -1); |
9762 | 176 tmp2 = gaim_markup_linkify(tmp); |
7971 | 177 if(jid->resource) |
9762 | 178 msg = g_strdup_printf(_("%s has set the topic to: %s"), jid->resource, tmp2); |
7971 | 179 else |
9762 | 180 msg = g_strdup_printf(_("The topic is: %s"), tmp2); |
7971 | 181 gaim_conv_chat_write(GAIM_CONV_CHAT(chat->conv), "", msg, GAIM_MESSAGE_SYSTEM, jm->sent); |
9762 | 182 g_free(tmp); |
183 g_free(tmp2); | |
7971 | 184 g_free(msg); |
185 } | |
186 } | |
7014 | 187 |
7630 | 188 if(jm->xhtml || jm->body) { |
189 if(jid->resource) | |
9584 | 190 serv_got_chat_in(jm->js->gc, chat->id, jid->resource, |
12216 | 191 jm->delayed ? GAIM_MESSAGE_DELAYED : 0, |
7630 | 192 jm->xhtml ? jm->xhtml : jm->body, jm->sent); |
193 else if(chat->muc) | |
194 gaim_conv_chat_write(GAIM_CONV_CHAT(chat->conv), "", | |
195 jm->xhtml ? jm->xhtml : jm->body, | |
196 GAIM_MESSAGE_SYSTEM, jm->sent); | |
197 } | |
198 | |
7014 | 199 jabber_id_free(jid); |
200 } | |
201 | |
7145 | 202 static void handle_groupchat_invite(JabberMessage *jm) |
7014 | 203 { |
7310 | 204 GHashTable *components; |
7014 | 205 JabberID *jid = jabber_id_new(jm->to); |
206 | |
7310 | 207 if(!jid) |
208 return; | |
209 | |
210 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
211 | |
7332 | 212 g_hash_table_replace(components, g_strdup("room"), g_strdup(jid->node)); |
7448 | 213 g_hash_table_replace(components, g_strdup("server"), g_strdup(jid->domain)); |
7332 | 214 g_hash_table_replace(components, g_strdup("handle"), |
215 g_strdup(jm->js->user->node)); | |
216 g_hash_table_replace(components, g_strdup("password"), | |
217 g_strdup(jm->password)); | |
7014 | 218 |
219 jabber_id_free(jid); | |
10774 | 220 serv_got_chat_invite(jm->js->gc, jm->to, jm->from, jm->body, components); |
7014 | 221 } |
222 | |
7145 | 223 static void handle_error(JabberMessage *jm) |
7014 | 224 { |
225 char *buf; | |
226 | |
227 if(!jm->body) | |
228 return; | |
229 | |
230 buf = g_strdup_printf(_("Message delivery to %s failed: %s"), | |
231 jm->from, jm->error); | |
232 | |
7944 | 233 gaim_notify_formatted(jm->js->gc, _("Jabber Message Error"), _("Jabber Message Error"), buf, |
234 jm->xhtml ? jm->xhtml : jm->body, NULL, NULL); | |
7014 | 235 |
236 g_free(buf); | |
237 } | |
238 | |
239 void jabber_message_parse(JabberStream *js, xmlnode *packet) | |
240 { | |
241 JabberMessage *jm; | |
242 const char *type; | |
243 xmlnode *child; | |
244 | |
245 if(strcmp(packet->name, "message")) | |
246 return; | |
247 | |
248 jm = g_new0(JabberMessage, 1); | |
249 jm->js = js; | |
250 jm->sent = time(NULL); | |
9584 | 251 jm->delayed = FALSE; |
7014 | 252 |
253 type = xmlnode_get_attrib(packet, "type"); | |
254 | |
255 if(type) { | |
256 if(!strcmp(type, "normal")) | |
257 jm->type = JABBER_MESSAGE_NORMAL; | |
258 else if(!strcmp(type, "chat")) | |
259 jm->type = JABBER_MESSAGE_CHAT; | |
260 else if(!strcmp(type, "groupchat")) | |
261 jm->type = JABBER_MESSAGE_GROUPCHAT; | |
262 else if(!strcmp(type, "headline")) | |
263 jm->type = JABBER_MESSAGE_HEADLINE; | |
264 else if(!strcmp(type, "error")) | |
265 jm->type = JABBER_MESSAGE_ERROR; | |
266 else | |
267 jm->type = JABBER_MESSAGE_OTHER; | |
268 } else { | |
269 jm->type = JABBER_MESSAGE_NORMAL; | |
270 } | |
271 | |
272 jm->from = g_strdup(xmlnode_get_attrib(packet, "from")); | |
273 jm->to = g_strdup(xmlnode_get_attrib(packet, "to")); | |
274 | |
275 for(child = packet->child; child; child = child->next) { | |
8135 | 276 if(child->type != XMLNODE_TYPE_TAG) |
7014 | 277 continue; |
278 | |
279 if(!strcmp(child->name, "subject")) { | |
280 if(!jm->subject) | |
281 jm->subject = xmlnode_get_data(child); | |
8400 | 282 } else if(!strcmp(child->name, "thread")) { |
283 if(!jm->thread_id) | |
284 jm->thread_id = xmlnode_get_data(child); | |
7014 | 285 } else if(!strcmp(child->name, "body")) { |
286 if(!jm->body) | |
7894 | 287 jm->body = xmlnode_to_str(child, NULL); |
7241 | 288 } else if(!strcmp(child->name, "html")) { |
11788 | 289 if(!jm->xhtml && xmlnode_get_child(child, "body")) |
7642 | 290 jm->xhtml = xmlnode_to_str(child, NULL); |
7014 | 291 } else if(!strcmp(child->name, "error")) { |
292 const char *code = xmlnode_get_attrib(child, "code"); | |
293 char *code_txt = NULL; | |
294 char *text = xmlnode_get_data(child); | |
295 | |
296 if(code) | |
297 code_txt = g_strdup_printf(_(" (Code %s)"), code); | |
298 | |
299 if(!jm->error) | |
300 jm->error = g_strdup_printf("%s%s", text ? text : "", | |
301 code_txt ? code_txt : ""); | |
302 | |
303 g_free(code_txt); | |
304 g_free(text); | |
305 } else if(!strcmp(child->name, "x")) { | |
306 const char *xmlns = xmlnode_get_attrib(child, "xmlns"); | |
307 if(xmlns && !strcmp(xmlns, "jabber:x:event")) { | |
308 if(xmlnode_get_child(child, "composing")) | |
309 jm->events |= JABBER_MESSAGE_EVENT_COMPOSING; | |
310 } else if(xmlns && !strcmp(xmlns, "jabber:x:delay")) { | |
311 const char *timestamp = xmlnode_get_attrib(child, "stamp"); | |
9584 | 312 jm->delayed = TRUE; |
7014 | 313 if(timestamp) |
8577 | 314 jm->sent = gaim_str_to_time(timestamp, TRUE); |
7014 | 315 } else if(xmlns && !strcmp(xmlns, "jabber:x:conference") && |
11230 | 316 jm->type != JABBER_MESSAGE_GROUPCHAT_INVITE && |
317 jm->type != JABBER_MESSAGE_ERROR) { | |
7014 | 318 const char *jid = xmlnode_get_attrib(child, "jid"); |
319 if(jid) { | |
320 jm->type = JABBER_MESSAGE_GROUPCHAT_INVITE; | |
321 g_free(jm->to); | |
322 jm->to = g_strdup(jid); | |
323 } | |
324 } else if(xmlns && !strcmp(xmlns, | |
11230 | 325 "http://jabber.org/protocol/muc#user") && |
326 jm->type != JABBER_MESSAGE_ERROR) { | |
7014 | 327 xmlnode *invite = xmlnode_get_child(child, "invite"); |
328 if(invite) { | |
329 xmlnode *reason, *password; | |
7968 | 330 const char *jid = xmlnode_get_attrib(invite, "from"); |
7014 | 331 g_free(jm->to); |
332 jm->to = jm->from; | |
333 jm->from = g_strdup(jid); | |
334 if((reason = xmlnode_get_child(invite, "reason"))) { | |
335 g_free(jm->body); | |
336 jm->body = xmlnode_get_data(reason); | |
337 } | |
11576
c66b972519e8
[gaim-migrate @ 13845]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11230
diff
changeset
|
338 if((password = xmlnode_get_child(child, "password"))) |
7014 | 339 jm->password = xmlnode_get_data(password); |
340 | |
341 jm->type = JABBER_MESSAGE_GROUPCHAT_INVITE; | |
342 } | |
7145 | 343 } else { |
344 jm->etc = g_list_append(jm->etc, child); | |
7014 | 345 } |
346 } | |
347 } | |
348 | |
349 switch(jm->type) { | |
350 case JABBER_MESSAGE_NORMAL: | |
351 case JABBER_MESSAGE_CHAT: | |
7145 | 352 handle_chat(jm); |
353 break; | |
7014 | 354 case JABBER_MESSAGE_HEADLINE: |
7145 | 355 handle_headline(jm); |
7014 | 356 break; |
357 case JABBER_MESSAGE_GROUPCHAT: | |
358 handle_groupchat(jm); | |
359 break; | |
360 case JABBER_MESSAGE_GROUPCHAT_INVITE: | |
361 handle_groupchat_invite(jm); | |
362 break; | |
363 case JABBER_MESSAGE_ERROR: | |
364 handle_error(jm); | |
365 break; | |
366 case JABBER_MESSAGE_OTHER: | |
367 gaim_debug(GAIM_DEBUG_INFO, "jabber", | |
368 "Received message of unknown type: %s\n", type); | |
369 break; | |
370 } | |
371 jabber_message_free(jm); | |
372 } | |
373 | |
374 void jabber_message_send(JabberMessage *jm) | |
375 { | |
376 xmlnode *message, *child; | |
377 const char *type = NULL; | |
378 | |
379 message = xmlnode_new("message"); | |
380 | |
381 switch(jm->type) { | |
382 case JABBER_MESSAGE_NORMAL: | |
383 type = "normal"; | |
384 break; | |
385 case JABBER_MESSAGE_CHAT: | |
386 case JABBER_MESSAGE_GROUPCHAT_INVITE: | |
387 type = "chat"; | |
388 break; | |
389 case JABBER_MESSAGE_HEADLINE: | |
390 type = "headline"; | |
391 break; | |
392 case JABBER_MESSAGE_GROUPCHAT: | |
393 type = "groupchat"; | |
394 break; | |
395 case JABBER_MESSAGE_ERROR: | |
396 type = "error"; | |
397 break; | |
398 case JABBER_MESSAGE_OTHER: | |
399 type = NULL; | |
400 break; | |
401 } | |
402 | |
403 if(type) | |
404 xmlnode_set_attrib(message, "type", type); | |
405 | |
406 xmlnode_set_attrib(message, "to", jm->to); | |
407 | |
8400 | 408 if(jm->thread_id) { |
409 child = xmlnode_new_child(message, "thread"); | |
410 xmlnode_insert_data(child, jm->thread_id, -1); | |
411 } | |
412 | |
7971 | 413 if(jm->events || (!jm->body && !jm->xhtml && !jm->subject)) { |
7014 | 414 child = xmlnode_new_child(message, "x"); |
415 xmlnode_set_attrib(child, "xmlns", "jabber:x:event"); | |
416 if(jm->events & JABBER_MESSAGE_EVENT_COMPOSING) | |
417 xmlnode_new_child(child, "composing"); | |
418 } | |
419 | |
420 if(jm->subject) { | |
421 child = xmlnode_new_child(message, "subject"); | |
422 xmlnode_insert_data(child, jm->subject, -1); | |
423 } | |
424 | |
425 if(jm->body) { | |
426 child = xmlnode_new_child(message, "body"); | |
427 xmlnode_insert_data(child, jm->body, -1); | |
428 } | |
429 | |
430 if(jm->xhtml) { | |
431 child = xmlnode_from_str(jm->xhtml, -1); | |
432 if(child) { | |
433 xmlnode_insert_child(message, child); | |
434 } else { | |
435 gaim_debug(GAIM_DEBUG_ERROR, "jabber", | |
436 "XHTML translation/validation failed, returning: %s\n", | |
437 jm->xhtml); | |
438 } | |
439 } | |
440 | |
441 jabber_send(jm->js, message); | |
442 | |
443 xmlnode_free(message); | |
444 } | |
445 | |
446 int jabber_message_send_im(GaimConnection *gc, const char *who, const char *msg, | |
12216 | 447 GaimMessageFlags flags) |
7014 | 448 { |
449 JabberMessage *jm; | |
450 JabberBuddy *jb; | |
451 JabberBuddyResource *jbr; | |
452 char *buf; | |
7135 | 453 char *xhtml; |
7306 | 454 char *resource; |
7014 | 455 |
456 if(!who || !msg) | |
457 return 0; | |
458 | |
7306 | 459 resource = jabber_get_resource(who); |
460 | |
7014 | 461 jb = jabber_buddy_find(gc->proto_data, who, TRUE); |
7306 | 462 jbr = jabber_buddy_find_resource(jb, resource); |
463 | |
464 g_free(resource); | |
7014 | 465 |
466 jm = g_new0(JabberMessage, 1); | |
467 jm->js = gc->proto_data; | |
468 jm->type = JABBER_MESSAGE_CHAT; | |
469 jm->events = JABBER_MESSAGE_EVENT_COMPOSING; | |
470 jm->to = g_strdup(who); | |
8400 | 471 if(jbr && jbr->thread_id) |
472 jm->thread_id = jbr->thread_id; | |
7014 | 473 |
7773 | 474 buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); |
7014 | 475 |
7135 | 476 gaim_markup_html_to_xhtml(buf, &xhtml, &jm->body); |
7014 | 477 g_free(buf); |
478 | |
479 if(!jbr || jbr->capabilities & JABBER_CAP_XHTML) | |
480 jm->xhtml = xhtml; | |
481 else | |
482 g_free(xhtml); | |
483 | |
484 jabber_message_send(jm); | |
485 jabber_message_free(jm); | |
486 return 1; | |
487 } | |
488 | |
12216 | 489 int jabber_message_send_chat(GaimConnection *gc, int id, const char *msg, GaimMessageFlags flags) |
7014 | 490 { |
491 JabberChat *chat; | |
492 JabberMessage *jm; | |
8042 | 493 JabberStream *js; |
9130 | 494 char *buf; |
7014 | 495 |
8042 | 496 if(!msg || !gc) |
7014 | 497 return 0; |
498 | |
8042 | 499 js = gc->proto_data; |
7014 | 500 chat = jabber_chat_find_by_id(js, id); |
501 | |
8043 | 502 if(!chat) |
503 return 0; | |
504 | |
9130 | 505 jm = g_new0(JabberMessage, 1); |
506 jm->js = gc->proto_data; | |
507 jm->type = JABBER_MESSAGE_GROUPCHAT; | |
508 jm->to = g_strdup_printf("%s@%s", chat->room, chat->server); | |
509 | |
8858 | 510 buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); |
9130 | 511 gaim_markup_html_to_xhtml(buf, &jm->xhtml, &jm->body); |
8858 | 512 g_free(buf); |
513 | |
9130 | 514 if(!chat->xhtml) { |
515 g_free(jm->xhtml); | |
516 jm->xhtml = NULL; | |
7923 | 517 } |
518 | |
9130 | 519 jabber_message_send(jm); |
520 jabber_message_free(jm); | |
521 | |
7014 | 522 return 1; |
523 } | |
524 | |
525 int jabber_send_typing(GaimConnection *gc, const char *who, int typing) | |
526 { | |
527 JabberMessage *jm; | |
528 JabberBuddy *jb; | |
529 JabberBuddyResource *jbr; | |
7306 | 530 char *resource = jabber_get_resource(who); |
7014 | 531 |
532 jb = jabber_buddy_find(gc->proto_data, who, TRUE); | |
7306 | 533 jbr = jabber_buddy_find_resource(jb, resource); |
534 | |
535 g_free(resource); | |
7014 | 536 |
7187 | 537 if(!jbr || !(jbr->capabilities & JABBER_CAP_COMPOSING)) |
7014 | 538 return 0; |
539 | |
540 jm = g_new0(JabberMessage, 1); | |
541 jm->js = gc->proto_data; | |
542 jm->type = JABBER_MESSAGE_CHAT; | |
543 jm->to = g_strdup(who); | |
544 | |
545 if(typing == GAIM_TYPING) | |
546 jm->events = JABBER_MESSAGE_EVENT_COMPOSING; | |
547 | |
548 jabber_message_send(jm); | |
549 jabber_message_free(jm); | |
550 | |
551 return JABBER_TYPING_NOTIFY_INT; | |
552 } | |
553 |