2
* $Id: composing.c,v 1.13 2009/04/03 11:21:35 cdidier Exp $
4
* Copyright (C) 2007,2008,2009 Colin DIDIER
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License along
16
* with this program; if not, write to the Free Software Foundation, Inc.,
17
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
* XEP-0022: Message Events
29
#include "xmpp-servers.h"
30
#include "xmpp-queries.h"
32
#include "tool_datalist.h"
35
#define XMLNS_EVENT "jabber:x:event"
37
static DATALIST *composings;
39
#define send_start(server, dest, id) \
40
send_composing_event(server, dest, id, TRUE)
41
#define send_stop(server, dest, id) \
42
send_composing_event(server, dest, id, FALSE)
45
send_composing_event(XMPP_SERVER_REC *server, const char *dest, const char *id,
52
recoded = xmpp_recode_out(dest);
53
lmsg = lm_message_new_with_sub_type(recoded,
54
LM_MESSAGE_TYPE_MESSAGE, LM_MESSAGE_SUB_TYPE_CHAT);
56
node = lm_message_node_add_child(lmsg->node, "x", NULL);
57
lm_message_node_set_attribute(node, XMLNS, XMLNS_EVENT);
59
lm_message_node_add_child(node, "composing", NULL);
61
lm_message_node_add_child(node, "id", id);
62
signal_emit("xmpp send message", 2, server, lmsg);
63
lm_message_unref(lmsg);
67
sig_composing_start(XMPP_SERVER_REC *server, const char *dest)
71
g_return_if_fail(IS_XMPP_SERVER(server));
72
g_return_if_fail(dest != NULL);
73
if ((rec = datalist_find(composings, server, dest)) != NULL)
74
send_start(server, dest, rec->data);
78
sig_composing_stop(XMPP_SERVER_REC *server, const char *dest)
82
g_return_if_fail(IS_XMPP_SERVER(server));
83
g_return_if_fail(dest != NULL);
84
if ((rec = datalist_find(composings, server, dest)) != NULL)
85
send_stop(server, dest, rec->data);
89
sig_composing_show(XMPP_SERVER_REC *server, const char *dest)
91
XMPP_QUERY_REC *query;
93
if ((query = xmpp_query_find(server, dest)) != NULL)
94
query->composing_visible = TRUE;
98
sig_composing_hide(XMPP_SERVER_REC *server, const char *dest)
100
XMPP_QUERY_REC *query;
102
if ((query = xmpp_query_find(server, dest)) != NULL)
103
query->composing_visible = FALSE;
107
sig_recv_message(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type,
108
const char *id, const char *from, const char *to)
112
if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET
113
&& type != LM_MESSAGE_SUB_TYPE_HEADLINE
114
&& type != LM_MESSAGE_SUB_TYPE_NORMAL
115
&& type != LM_MESSAGE_SUB_TYPE_CHAT)
116
|| server->ischannel(SERVER(server), from))
118
node = lm_find_node(lmsg->node, "x", XMLNS, XMLNS_EVENT);
120
signal_emit("xmpp composing hide", 2, server, from);
123
if (lm_message_node_get_child(lmsg->node, "body") != NULL
124
|| lm_message_node_get_child(lmsg->node, "subject") != NULL) {
125
if (lm_message_node_get_child(node, "composing") != NULL)
126
datalist_add(composings, server, from, g_strdup(id));
128
datalist_remove(composings, server, from);
129
signal_emit("xmpp composing hide", 2, server, from);
131
if (lm_message_node_get_child(node, "composing") != NULL)
132
signal_emit("xmpp composing show", 2, server, from);
134
signal_emit("xmpp composing hide", 2, server, from);
139
sig_send_message(XMPP_SERVER_REC *server, LmMessage *lmsg)
142
LmMessageSubType type;
144
type = lm_message_get_sub_type(lmsg);
145
if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET
146
&& type != LM_MESSAGE_SUB_TYPE_HEADLINE
147
&& type != LM_MESSAGE_SUB_TYPE_NORMAL
148
&& type != LM_MESSAGE_SUB_TYPE_CHAT)
149
|| (lm_message_node_get_child(lmsg->node, "body") == NULL
150
&& lm_message_node_get_child(lmsg->node, "subject") == NULL))
152
/* request composing events */
153
node = lm_message_node_add_child(lmsg->node, "x", NULL);
154
lm_message_node_set_attribute(node, XMLNS, XMLNS_EVENT);
155
lm_message_node_add_child(node, "composing", NULL);
159
sig_offline(XMPP_SERVER_REC *server, const char *jid)
161
g_return_if_fail(IS_XMPP_SERVER(server));
162
datalist_remove(composings, server, jid);
166
sig_disconnected(XMPP_SERVER_REC *server)
168
if (IS_XMPP_SERVER(server))
169
datalist_cleanup(composings, server);
173
freedata_func(DATALIST_REC *rec)
181
composings = datalist_new(freedata_func);
182
disco_add_feature(XMLNS_EVENT);
183
signal_add("xmpp composing start", sig_composing_start);
184
signal_add("xmpp composing stop", sig_composing_stop);
185
signal_add("xmpp composing show", sig_composing_show);
186
signal_add("xmpp composing hide", sig_composing_hide);
187
signal_add("xmpp recv message", sig_recv_message);
188
signal_add("xmpp send message", sig_send_message);
189
signal_add("xmpp presence offline", sig_offline);
190
signal_add("server disconnected", sig_disconnected);
194
composing_deinit(void)
196
signal_remove("xmpp composing start", sig_composing_start);
197
signal_remove("xmpp composing stop", sig_composing_stop);
198
signal_remove("xmpp composing show", sig_composing_show);
199
signal_remove("xmpp composing hide", sig_composing_hide);
200
signal_remove("xmpp recv message", sig_recv_message);
201
signal_remove("xmpp send message", sig_send_message);
202
signal_remove("xmpp presence offline", sig_offline);
203
signal_remove("server disconnected", sig_disconnected);
204
datalist_destroy(composings);