purple: add support for latest appstreamcli
[siplcs.git] / src / telepathy / telepathy-status.c
bloba57c3c7e748273a43f6ff5e9ed8e7c0fc93a8ba9
1 /**
2 * @file telepathy-status.c
4 * pidgin-sipe
6 * Copyright (C) 2012-2019 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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include <glib-object.h>
28 #include <telepathy-glib/base-connection.h>
29 #include <telepathy-glib/telepathy-glib.h>
31 #include "sipe-backend.h"
32 #include "sipe-common.h"
33 #include "sipe-core.h"
35 #include "telepathy-private.h"
37 static const TpPresenceStatusOptionalArgumentSpec args[] = {
38 { .name = "message", .dtype = "s" },
39 { .name = NULL, .dtype = NULL }
42 /* Sipe core activity <-> Telepathy status mapping */
43 #define SIPE_TELEPATHY_STATUS(_name, _type, _self, _args) \
44 { \
45 .name = (_name), \
46 .presence_type = (_type), \
47 .self = (_self), \
48 .optional_arguments = (_args), \
50 #define SIPE_TELEPATHY_STATUS_NONE(_name, _type, _self) \
51 SIPE_TELEPATHY_STATUS(_name, _type, _self, NULL)
52 #define SIPE_TELEPATHY_STATUS_MESSAGE(_name, _type, _self) \
53 SIPE_TELEPATHY_STATUS(_name, _type, _self, args)
54 static const TpPresenceStatusSpec statuses[SIPE_ACTIVITY_NUM_TYPES + 1] = {
55 /* SIPE_ACTIVITY_UNSET */ SIPE_TELEPATHY_STATUS_NONE( "unset", TP_CONNECTION_PRESENCE_TYPE_UNSET, FALSE),
56 /* SIPE_ACTIVITY_AVAILABLE */ SIPE_TELEPATHY_STATUS_MESSAGE("available", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, TRUE),
57 /* SIPE_ACTIVITY_ONLINE */ SIPE_TELEPATHY_STATUS_MESSAGE("online", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, TRUE),
58 /* SIPE_ACTIVITY_INACTIVE */ SIPE_TELEPATHY_STATUS_MESSAGE("idle", TP_CONNECTION_PRESENCE_TYPE_AWAY, TRUE),
59 /* SIPE_ACTIVITY_BUSY */ SIPE_TELEPATHY_STATUS_MESSAGE("busy", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
60 /* SIPE_ACTIVITY_BUSYIDLE */ SIPE_TELEPATHY_STATUS_MESSAGE("busyidle", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
61 /* SIPE_ACTIVITY_DND */ SIPE_TELEPATHY_STATUS_MESSAGE("do-not-disturb", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
62 /* SIPE_ACTIVITY_BRB */ SIPE_TELEPATHY_STATUS_MESSAGE("be-right-back", TP_CONNECTION_PRESENCE_TYPE_AWAY, TRUE),
63 /* SIPE_ACTIVITY_AWAY */ SIPE_TELEPATHY_STATUS_MESSAGE("away", TP_CONNECTION_PRESENCE_TYPE_AWAY, TRUE),
64 /* SIPE_ACTIVITY_LUNCH */ SIPE_TELEPATHY_STATUS_MESSAGE("out-to-lunch", TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY, TRUE),
65 /* SIPE_ACTIVITY_INVISIBLE */ SIPE_TELEPATHY_STATUS_NONE( "invisible", TP_CONNECTION_PRESENCE_TYPE_HIDDEN, TRUE),
66 /* SIPE_ACTIVITY_OFFLINE */ SIPE_TELEPATHY_STATUS_NONE( "offline", TP_CONNECTION_PRESENCE_TYPE_OFFLINE, FALSE),
67 /* SIPE_ACTIVITY_ON_PHONE */ SIPE_TELEPATHY_STATUS_MESSAGE("on-the-phone", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
68 /* SIPE_ACTIVITY_IN_CONF */ SIPE_TELEPATHY_STATUS_MESSAGE("in-a-conference", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
69 /* SIPE_ACTIVITY_IN_MEETING */ SIPE_TELEPATHY_STATUS_MESSAGE("in-a-meeting", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
70 /* SIPE_ACTIVITY_OOF */ SIPE_TELEPATHY_STATUS_MESSAGE("out-of-office", TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY, TRUE),
71 /* SIPE_ACTIVITY_URGENT_ONLY */ SIPE_TELEPATHY_STATUS_MESSAGE("urgent-interruptions-only", TP_CONNECTION_PRESENCE_TYPE_BUSY, TRUE),
72 /* end-of-array indicator */ SIPE_TELEPATHY_STATUS_NONE( NULL, 0, FALSE)
75 static gboolean status_available(SIPE_UNUSED_PARAMETER GObject *object,
76 guint index)
79 * @TODO: what is this function supposed to do?
80 * - TRUE: index is one of the "user is available" statuses?
81 * - TRUE: index is a valid status?
83 return(statuses[index].name != NULL);
86 static GHashTable *get_contact_statuses(GObject *object,
87 const GArray *contacts,
88 SIPE_UNUSED_PARAMETER GError **error)
90 struct sipe_backend_private *telepathy_private = sipe_telepathy_connection_private(object);
91 TpBaseConnection *base = TP_BASE_CONNECTION(object);
92 GHashTable *status_table = g_hash_table_new(g_direct_hash,
93 g_direct_equal);
94 guint i;
96 for (i = 0; i < contacts->len; i++) {
97 TpHandle contact = g_array_index(contacts, guint, i);
98 guint activity;
99 GHashTable *parameters;
101 /* we get our own status from the connection, and everyone
102 * else's status from the contact lists */
103 if (contact == tp_base_connection_get_self_handle(base)) {
104 activity = telepathy_private->activity;
105 } else {
106 /* @TODO */
107 activity = sipe_telepathy_buddy_get_presence(telepathy_private->contact_list,
108 contact);
111 parameters = g_hash_table_new_full(g_str_hash,
112 g_str_equal,
113 NULL,
114 (GDestroyNotify) tp_g_value_slice_free);
115 g_hash_table_insert(status_table,
116 GUINT_TO_POINTER(contact),
117 tp_presence_status_new(activity,
118 parameters));
119 g_hash_table_unref(parameters);
122 return(status_table);
125 static void update_status(struct sipe_backend_private *telepathy_private,
126 guint activity,
127 const gchar *message,
128 const TpPresenceStatus *status,
129 gboolean outgoing)
131 GObject *connection = G_OBJECT(telepathy_private->connection);
132 GHashTable *presences;
134 /* update internal status */
135 telepathy_private->activity = activity;
136 g_free(telepathy_private->message);
137 telepathy_private->message = NULL;
138 if (message)
139 telepathy_private->message = g_strdup(message);
141 /* outgoing status update */
142 if (outgoing)
143 sipe_core_status_set(telepathy_private->public,
144 TRUE,
145 activity,
146 message);
148 /* emit status update signal */
149 presences = g_hash_table_new(g_direct_hash, g_direct_equal);
150 g_hash_table_insert(presences,
151 GUINT_TO_POINTER(tp_base_connection_get_self_handle(TP_BASE_CONNECTION(connection))),
152 (gpointer) status);
153 tp_presence_mixin_emit_presence_update(connection, presences);
154 g_hash_table_unref(presences);
157 static gboolean set_own_status(GObject *object,
158 const TpPresenceStatus *status,
159 SIPE_UNUSED_PARAMETER GError **error)
161 struct sipe_backend_private *telepathy_private = sipe_telepathy_connection_private(object);
162 guint activity = SIPE_ACTIVITY_AVAILABLE;
163 const gchar *message = NULL;
165 if (!telepathy_private)
166 return(FALSE);
168 if (status) {
169 activity = status->index;
171 if (status->optional_arguments)
172 message = tp_asv_get_string(status->optional_arguments,
173 "message");
176 SIPE_DEBUG_INFO("set_own_status: %d '%s'", activity,
177 message ? message : "(none)");
178 update_status(telepathy_private, activity, message, status, TRUE);
181 return(TRUE);
184 void sipe_telepathy_status_init(GObjectClass *object_class,
185 gsize struct_offset)
187 tp_presence_mixin_class_init(object_class,
188 struct_offset,
189 status_available,
190 get_contact_statuses,
191 set_own_status,
192 statuses);
197 * Backend adaptor functions
199 guint sipe_backend_status(struct sipe_core_public *sipe_public)
201 return(sipe_public->backend_private->activity);
204 gboolean sipe_backend_status_changed(struct sipe_core_public *sipe_public,
205 guint activity,
206 const gchar *message)
208 struct sipe_backend_private *telepathy_private = sipe_public->backend_private;
210 if ((activity == telepathy_private->activity) &&
211 sipe_strequal(message, telepathy_private->message))
212 return(FALSE);
214 return(TRUE);
218 * This is used by:
220 * - incoming status updates (roaming)
221 * - induced status updates (calendar)
223 void sipe_backend_status_and_note(struct sipe_core_public *sipe_public,
224 guint activity,
225 const gchar *message)
227 struct sipe_backend_private *telepathy_private = sipe_public->backend_private;
228 GHashTable *optional = NULL;
229 TpPresenceStatus *status;
231 if (message)
232 optional = tp_asv_new("message", G_TYPE_STRING, message,
233 NULL);
235 status = tp_presence_status_new(activity, optional);
236 if (optional)
237 g_hash_table_unref(optional);
239 update_status(telepathy_private, activity, message, status, FALSE);
240 tp_presence_status_free(status);
245 Local Variables:
246 mode: c
247 c-file-style: "bsd"
248 indent-tabs-mode: t
249 tab-width: 8
250 End: