security: reset READY flag when dropping context
[siplcs.git] / src / telepathy / telepathy-status.c
blob2b034a86a0a03071ca3e9973cd381199c719f498
1 /**
2 * @file telepathy-status.c
4 * pidgin-sipe
6 * Copyright (C) 2012 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <glib-object.h>
24 #include <telepathy-glib/base-connection.h>
25 #include <telepathy-glib/telepathy-glib.h>
27 #include "sipe-backend.h"
28 #include "sipe-common.h"
29 #include "sipe-core.h"
31 #include "telepathy-private.h"
33 static const TpPresenceStatusOptionalArgumentSpec args[] = {
34 { .name = "message", .dtype = "s" },
35 { .name = NULL, .dtype = NULL }
38 /* Sipe core activity <-> Telepathy status mapping */
39 #define SIPE_TELEPATHY_STATUS(_name, _type, _self, _args) \
40 { \
41 .name = (_name), \
42 .presence_type = (_type), \
43 .self = (_self), \
44 .optional_arguments = (_args), \
46 #define SIPE_TELEPATHY_STATUS_NONE(_name, _type, _self) \
47 SIPE_TELEPATHY_STATUS(_name, _type, _self, NULL)
48 #define SIPE_TELEPATHY_STATUS_MESSAGE(_name, _type, _self) \
49 SIPE_TELEPATHY_STATUS(_name, _type, _self, args)
50 static const TpPresenceStatusSpec statuses[SIPE_ACTIVITY_NUM_TYPES + 1] = {
51 /* SIPE_ACTIVITY_UNSET */ SIPE_TELEPATHY_STATUS_NONE( "unset", TP_CONNECTION_PRESENCE_TYPE_UNSET, FALSE),
52 /* SIPE_ACTIVITY_AVAILABLE */ SIPE_TELEPATHY_STATUS_MESSAGE("available", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, TRUE),
53 /* SIPE_ACTIVITY_ONLINE */ SIPE_TELEPATHY_STATUS_MESSAGE("online", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, TRUE),
54 /* SIPE_ACTIVITY_INACTIVE */ SIPE_TELEPATHY_STATUS_MESSAGE("idle", TP_CONNECTION_PRESENCE_TYPE_AWAY, TRUE),
55 /* SIPE_ACTIVITY_BUSY */ SIPE_TELEPATHY_STATUS_MESSAGE("busy", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
56 /* SIPE_ACTIVITY_BUSYIDLE */ SIPE_TELEPATHY_STATUS_MESSAGE("busyidle", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
57 /* SIPE_ACTIVITY_DND */ SIPE_TELEPATHY_STATUS_MESSAGE("do-not-disturb", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
58 /* SIPE_ACTIVITY_BRB */ SIPE_TELEPATHY_STATUS_MESSAGE("be-right-back", TP_CONNECTION_PRESENCE_TYPE_AWAY, TRUE),
59 /* SIPE_ACTIVITY_AWAY */ SIPE_TELEPATHY_STATUS_MESSAGE("away", TP_CONNECTION_PRESENCE_TYPE_AWAY, TRUE),
60 /* SIPE_ACTIVITY_LUNCH */ SIPE_TELEPATHY_STATUS_MESSAGE("out-to-lunch", TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY, TRUE),
61 /* SIPE_ACTIVITY_INVISIBLE */ SIPE_TELEPATHY_STATUS_NONE( "invisible", TP_CONNECTION_PRESENCE_TYPE_HIDDEN, TRUE),
62 /* SIPE_ACTIVITY_OFFLINE */ SIPE_TELEPATHY_STATUS_NONE( "offline", TP_CONNECTION_PRESENCE_TYPE_OFFLINE, FALSE),
63 /* SIPE_ACTIVITY_ON_PHONE */ SIPE_TELEPATHY_STATUS_MESSAGE("on-the-phone", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
64 /* SIPE_ACTIVITY_IN_CONF */ SIPE_TELEPATHY_STATUS_MESSAGE("in-a-conference", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
65 /* SIPE_ACTIVITY_IN_MEETING */ SIPE_TELEPATHY_STATUS_MESSAGE("in-a-meeting", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
66 /* SIPE_ACTIVITY_OOF */ SIPE_TELEPATHY_STATUS_MESSAGE("out-of-office", TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY, TRUE),
67 /* SIPE_ACTIVITY_URGENT_ONLY */ SIPE_TELEPATHY_STATUS_MESSAGE("urgent-interruptions-only", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
68 /* end-of-array indicator */ SIPE_TELEPATHY_STATUS_NONE( NULL, 0, FALSE)
71 static gboolean status_available(SIPE_UNUSED_PARAMETER GObject *object,
72 guint index)
75 * @TODO: what is this function supposed to do?
76 * - TRUE: index is one of the "user is available" statuses?
77 * - TRUE: index is a valid status?
79 return(statuses[index].name != NULL);
82 static GHashTable *get_contact_statuses(GObject *object,
83 const GArray *contacts,
84 SIPE_UNUSED_PARAMETER GError **error)
86 struct sipe_backend_private *telepathy_private = sipe_telepathy_connection_private(object);
87 TpBaseConnection *base = TP_BASE_CONNECTION(object);
88 GHashTable *status_table = g_hash_table_new(g_direct_hash,
89 g_direct_equal);
90 guint i;
92 for (i = 0; i < contacts->len; i++) {
93 TpHandle contact = g_array_index(contacts, guint, i);
94 guint activity;
95 GHashTable *parameters;
97 /* we get our own status from the connection, and everyone
98 * else's status from the contact lists */
99 if (contact == tp_base_connection_get_self_handle(base)) {
100 activity = telepathy_private->activity;
101 } else {
102 /* @TODO */
103 activity = sipe_telepathy_buddy_get_presence(telepathy_private->contact_list,
104 contact);
107 parameters = g_hash_table_new_full(g_str_hash,
108 g_str_equal,
109 NULL,
110 (GDestroyNotify) tp_g_value_slice_free);
111 g_hash_table_insert(status_table,
112 GUINT_TO_POINTER(contact),
113 tp_presence_status_new(activity,
114 parameters));
115 g_hash_table_unref(parameters);
118 return(status_table);
121 static void update_status(struct sipe_backend_private *telepathy_private,
122 guint activity,
123 const gchar *message,
124 const TpPresenceStatus *status,
125 gboolean outgoing)
127 GObject *connection = G_OBJECT(telepathy_private->connection);
128 GHashTable *presences;
130 /* update internal status */
131 telepathy_private->activity = activity;
132 g_free(telepathy_private->message);
133 telepathy_private->message = NULL;
134 if (message)
135 telepathy_private->message = g_strdup(message);
137 /* outgoing status update */
138 if (outgoing)
139 sipe_core_status_set(telepathy_private->public,
140 activity,
141 message);
143 /* emit status update signal */
144 presences = g_hash_table_new(g_direct_hash, g_direct_equal);
145 g_hash_table_insert(presences,
146 GUINT_TO_POINTER(tp_base_connection_get_self_handle(TP_BASE_CONNECTION(connection))),
147 (gpointer) status);
148 tp_presence_mixin_emit_presence_update(connection, presences);
149 g_hash_table_unref(presences);
152 static gboolean set_own_status(GObject *object,
153 const TpPresenceStatus *status,
154 SIPE_UNUSED_PARAMETER GError **error)
156 struct sipe_backend_private *telepathy_private = sipe_telepathy_connection_private(object);
157 guint activity = SIPE_ACTIVITY_AVAILABLE;
158 const gchar *message = NULL;
160 if (!telepathy_private)
161 return(FALSE);
163 if (status) {
164 activity = status->index;
166 if (status->optional_arguments)
167 message = tp_asv_get_string(status->optional_arguments,
168 "message");
171 SIPE_DEBUG_INFO("set_own_status: %d '%s'", activity,
172 message ? message : "(none)");
173 update_status(telepathy_private, activity, message, status, TRUE);
176 return(TRUE);
179 void sipe_telepathy_status_init(GObjectClass *object_class,
180 gsize struct_offset)
182 tp_presence_mixin_class_init(object_class,
183 struct_offset,
184 status_available,
185 get_contact_statuses,
186 set_own_status,
187 statuses);
192 * Backend adaptor functions
194 guint sipe_backend_status(struct sipe_core_public *sipe_public)
196 return(sipe_public->backend_private->activity);
199 gboolean sipe_backend_status_changed(struct sipe_core_public *sipe_public,
200 guint activity,
201 const gchar *message)
203 struct sipe_backend_private *telepathy_private = sipe_public->backend_private;
205 if ((activity == telepathy_private->activity) &&
206 sipe_strequal(message, telepathy_private->message))
207 return(FALSE);
209 return(TRUE);
213 * This is used by:
215 * - incoming status updates (roaming)
216 * - induced status updates (calendar)
218 void sipe_backend_status_and_note(struct sipe_core_public *sipe_public,
219 guint activity,
220 const gchar *message)
222 struct sipe_backend_private *telepathy_private = sipe_public->backend_private;
223 GHashTable *optional = NULL;
224 TpPresenceStatus *status;
226 if (message)
227 optional = tp_asv_new("message", G_TYPE_STRING, message,
228 NULL);
230 status = tp_presence_status_new(activity, optional);
231 if (optional)
232 g_hash_table_unref(optional);
234 update_status(telepathy_private, activity, message, status, FALSE);
235 tp_presence_status_free(status);
240 Local Variables:
241 mode: c
242 c-file-style: "bsd"
243 indent-tabs-mode: t
244 tab-width: 8
245 End: