]> git.0d.be Git - empathy.git/blob - libempathy/empathy-utils.c
Use proper display names in the chooser
[empathy.git] / libempathy / empathy-utils.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2003-2007 Imendio AB
4  * Copyright (C) 2007-2008 Collabora Ltd.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (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 GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA  02110-1301  USA
20  *
21  * Authors: Richard Hult <richard@imendio.com>
22  *          Martyn Russell <martyn@imendio.com>
23  *          Xavier Claessens <xclaesse@gmail.com>
24  */
25
26 #include "config.h"
27
28 #include <string.h>
29 #include <time.h>
30 #include <sys/types.h>
31
32 #include <glib/gi18n-lib.h>
33
34 #include <libxml/uri.h>
35 #include <telepathy-glib/connection.h>
36 #include <telepathy-glib/channel.h>
37 #include <telepathy-glib/dbus.h>
38 #include <telepathy-glib/util.h>
39
40 #include "empathy-utils.h"
41 #include "empathy-contact-manager.h"
42 #include "empathy-dispatcher.h"
43 #include "empathy-dispatch-operation.h"
44 #include "empathy-idle.h"
45 #include "empathy-tp-call.h"
46
47 #include <extensions/extensions.h>
48
49 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
50 #include "empathy-debug.h"
51
52 /* Translation between presence types and string */
53 static struct {
54         gchar *name;
55         TpConnectionPresenceType type;
56 } presence_types[] = {
57         { "available", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE },
58         { "busy",      TP_CONNECTION_PRESENCE_TYPE_BUSY },
59         { "away",      TP_CONNECTION_PRESENCE_TYPE_AWAY },
60         { "ext_away",  TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY },
61         { "hidden",    TP_CONNECTION_PRESENCE_TYPE_HIDDEN },
62         { "offline",   TP_CONNECTION_PRESENCE_TYPE_OFFLINE },
63         { "unset",     TP_CONNECTION_PRESENCE_TYPE_UNSET },
64         { "unknown",   TP_CONNECTION_PRESENCE_TYPE_UNKNOWN },
65         { "error",     TP_CONNECTION_PRESENCE_TYPE_ERROR },
66         /* alternative names */
67         { "dnd",      TP_CONNECTION_PRESENCE_TYPE_BUSY },
68         { "brb",      TP_CONNECTION_PRESENCE_TYPE_AWAY },
69         { "xa",       TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY },
70         { NULL, },
71 };
72
73
74
75 void
76 empathy_init (void)
77 {
78         static gboolean initialized = FALSE;
79
80         if (initialized)
81                 return;
82
83         g_type_init ();
84
85         /* Setup gettext */
86         bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
87         bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
88
89         /* Setup debug output for empathy and telepathy-glib */
90         if (g_getenv ("EMPATHY_TIMING") != NULL) {
91                 g_log_set_default_handler (tp_debug_timestamped_log_handler, NULL);
92         }
93         empathy_debug_set_flags (g_getenv ("EMPATHY_DEBUG"));
94         tp_debug_divert_messages (g_getenv ("EMPATHY_LOGFILE"));
95
96         emp_cli_init ();
97
98         initialized = TRUE;
99 }
100
101 gchar *
102 empathy_substring (const gchar *str,
103                   gint         start,
104                   gint         end)
105 {
106         return g_strndup (str + start, end - start);
107 }
108
109 gint
110 empathy_strcasecmp (const gchar *s1,
111                    const gchar *s2)
112 {
113         return empathy_strncasecmp (s1, s2, -1);
114 }
115
116 gint
117 empathy_strncasecmp (const gchar *s1,
118                     const gchar *s2,
119                     gsize        n)
120 {
121         gchar *u1, *u2;
122         gint   ret_val;
123
124         u1 = g_utf8_casefold (s1, n);
125         u2 = g_utf8_casefold (s2, n);
126
127         ret_val = g_utf8_collate (u1, u2);
128         g_free (u1);
129         g_free (u2);
130
131         return ret_val;
132 }
133
134 gboolean
135 empathy_xml_validate (xmlDoc      *doc,
136                      const gchar *dtd_filename)
137 {
138         gchar        *path, *escaped;
139         xmlValidCtxt  cvp;
140         xmlDtd       *dtd;
141         gboolean      ret;
142
143         path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"), "libempathy",
144                                  dtd_filename, NULL);
145         if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
146                 g_free (path);
147                 path = g_build_filename (DATADIR, "empathy", dtd_filename, NULL);
148         }
149         DEBUG ("Loading dtd file %s", path);
150
151         /* The list of valid chars is taken from libxml. */
152         escaped = xmlURIEscapeStr (path, ":@&=+$,/?;");
153         g_free (path);
154
155         memset (&cvp, 0, sizeof (cvp));
156         dtd = xmlParseDTD (NULL, escaped);
157         ret = xmlValidateDtd (&cvp, doc, dtd);
158
159         xmlFree (escaped);
160         xmlFreeDtd (dtd);
161
162         return ret;
163 }
164
165 xmlNodePtr
166 empathy_xml_node_get_child (xmlNodePtr   node,
167                            const gchar *child_name)
168 {
169         xmlNodePtr l;
170
171         g_return_val_if_fail (node != NULL, NULL);
172         g_return_val_if_fail (child_name != NULL, NULL);
173
174         for (l = node->children; l; l = l->next) {
175                 if (l->name && strcmp (l->name, child_name) == 0) {
176                         return l;
177                 }
178         }
179
180         return NULL;
181 }
182
183 xmlChar *
184 empathy_xml_node_get_child_content (xmlNodePtr   node,
185                                    const gchar *child_name)
186 {
187         xmlNodePtr l;
188
189         g_return_val_if_fail (node != NULL, NULL);
190         g_return_val_if_fail (child_name != NULL, NULL);
191
192         l = empathy_xml_node_get_child (node, child_name);
193         if (l) {
194                 return xmlNodeGetContent (l);
195         }
196
197         return NULL;
198 }
199
200 xmlNodePtr
201 empathy_xml_node_find_child_prop_value (xmlNodePtr   node,
202                                        const gchar *prop_name,
203                                        const gchar *prop_value)
204 {
205         xmlNodePtr l;
206         xmlNodePtr found = NULL;
207
208         g_return_val_if_fail (node != NULL, NULL);
209         g_return_val_if_fail (prop_name != NULL, NULL);
210         g_return_val_if_fail (prop_value != NULL, NULL);
211
212         for (l = node->children; l && !found; l = l->next) {
213                 xmlChar *prop;
214
215                 if (!xmlHasProp (l, prop_name)) {
216                         continue;
217                 }
218
219                 prop = xmlGetProp (l, prop_name);
220                 if (prop && strcmp (prop, prop_value) == 0) {
221                         found = l;
222                 }
223
224                 xmlFree (prop);
225         }
226
227         return found;
228 }
229
230 guint
231 empathy_account_hash (gconstpointer key)
232 {
233         g_return_val_if_fail (EMPATHY_IS_ACCOUNT (key), 0);
234
235         return g_str_hash (empathy_account_get_unique_name (EMPATHY_ACCOUNT (key)));
236 }
237
238 gboolean
239 empathy_account_equal (gconstpointer a,
240                        gconstpointer b)
241 {
242   return a == b;
243 }
244
245 const gchar *
246 empathy_presence_get_default_message (TpConnectionPresenceType presence)
247 {
248         switch (presence) {
249         case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE:
250                 return _("Available");
251         case TP_CONNECTION_PRESENCE_TYPE_BUSY:
252                 return _("Busy");
253         case TP_CONNECTION_PRESENCE_TYPE_AWAY:
254         case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY:
255                 return _("Away");
256         case TP_CONNECTION_PRESENCE_TYPE_HIDDEN:
257                 return _("Hidden");
258         case TP_CONNECTION_PRESENCE_TYPE_OFFLINE:
259                 return _("Offline");
260         case TP_CONNECTION_PRESENCE_TYPE_UNSET:
261         case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN:
262         case TP_CONNECTION_PRESENCE_TYPE_ERROR:
263                 return NULL;
264         }
265
266         return NULL;
267 }
268
269 const gchar *
270 empathy_presence_to_str (TpConnectionPresenceType presence)
271 {
272         int i;
273
274         for (i = 0 ; presence_types[i].name != NULL; i++)
275                 if (presence == presence_types[i].type)
276                         return presence_types[i].name;
277
278         return NULL;
279 }
280
281 TpConnectionPresenceType
282 empathy_presence_from_str (const gchar *str)
283 {
284         int i;
285
286         for (i = 0 ; presence_types[i].name != NULL; i++)
287                 if (!tp_strdiff (str, presence_types[i].name))
288                         return presence_types[i].type;
289
290         return TP_CONNECTION_PRESENCE_TYPE_UNSET;
291 }
292
293 gchar *
294 empathy_file_lookup (const gchar *filename, const gchar *subdir)
295 {
296         gchar *path;
297
298         if (!subdir) {
299                 subdir = ".";
300         }
301
302         path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"), subdir, filename, NULL);
303         if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
304                 g_free (path);
305                 path = g_build_filename (DATADIR, "empathy", filename, NULL);
306         }
307
308         return path;
309 }
310
311 guint
312 empathy_proxy_hash (gconstpointer key)
313 {
314         TpProxy      *proxy = TP_PROXY (key);
315         TpProxyClass *proxy_class = TP_PROXY_GET_CLASS (key);
316
317         g_return_val_if_fail (TP_IS_PROXY (proxy), 0);
318         g_return_val_if_fail (proxy_class->must_have_unique_name, 0);
319
320         return g_str_hash (proxy->object_path) ^ g_str_hash (proxy->bus_name);
321 }
322
323 gboolean
324 empathy_proxy_equal (gconstpointer a,
325                      gconstpointer b)
326 {
327         TpProxy *proxy_a = TP_PROXY (a);
328         TpProxy *proxy_b = TP_PROXY (b);
329         TpProxyClass *proxy_a_class = TP_PROXY_GET_CLASS (a);
330         TpProxyClass *proxy_b_class = TP_PROXY_GET_CLASS (b);
331
332         g_return_val_if_fail (TP_IS_PROXY (proxy_a), FALSE);
333         g_return_val_if_fail (TP_IS_PROXY (proxy_b), FALSE);
334         g_return_val_if_fail (proxy_a_class->must_have_unique_name, 0);
335         g_return_val_if_fail (proxy_b_class->must_have_unique_name, 0);
336
337         return g_str_equal (proxy_a->object_path, proxy_b->object_path) &&
338                g_str_equal (proxy_a->bus_name, proxy_b->bus_name);
339 }
340
341 gboolean
342 empathy_check_available_state (void)
343 {
344         TpConnectionPresenceType presence;
345         EmpathyIdle *idle;
346
347         idle = empathy_idle_dup_singleton ();
348         presence = empathy_idle_get_state (idle);
349         g_object_unref (idle);
350
351         if (presence != TP_CONNECTION_PRESENCE_TYPE_AVAILABLE &&
352                 presence != TP_CONNECTION_PRESENCE_TYPE_UNSET) {
353                 return FALSE;
354         }
355
356         return TRUE;
357 }
358
359 gint
360 empathy_uint_compare (gconstpointer a,
361                       gconstpointer b)
362 {
363         return *(guint *) a - *(guint *) b;
364 }
365
366 GType
367 empathy_type_dbus_ao (void)
368 {
369   static GType t = 0;
370
371   if (G_UNLIKELY (t == 0))
372      t = dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH);
373
374   return t;
375 }