]> git.0d.be Git - empathy.git/blob - src/empathy.c
Drop gnome-vfs dependency and use gio instead. Fixes bug #514380 (Cosimo Cecchi).
[empathy.git] / src / empathy.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007-2008 Collabora Ltd.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
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 GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  * 
20  * Authors: Xavier Claessens <xclaesse@gmail.com>
21  */
22
23 #include <config.h>
24
25 #include <stdlib.h>
26 #include <errno.h>
27
28 #include <glib.h>
29 #include <glib/gi18n.h>
30 #include <gtk/gtk.h>
31 #include <gdk/gdkx.h>
32
33 #include <libebook/e-book.h>
34
35 #include <telepathy-glib/util.h>
36 #include <libmissioncontrol/mc-account.h>
37 #include <libmissioncontrol/mc-account-monitor.h>
38 #include <libmissioncontrol/mission-control.h>
39
40 #include <libempathy/empathy-idle.h>
41 #include <libempathy/empathy-utils.h>
42 #include <libempathy/empathy-debug.h>
43
44 #include <libempathy-gtk/empathy-conf.h>
45 #include <libempathy-gtk/empathy-preferences.h>
46 #include <libempathy-gtk/empathy-main-window.h>
47 #include <libempathy-gtk/empathy-status-icon.h>
48
49 #include "bacon-message-connection.h"
50
51 #define DEBUG_DOMAIN "EmpathyMain"
52
53 static BaconMessageConnection *connection = NULL;
54
55 static void
56 service_ended_cb (MissionControl *mc,
57                   gpointer        user_data)
58 {
59         empathy_debug (DEBUG_DOMAIN, "Mission Control stopped");
60 }
61
62 static void
63 operation_error_cb (MissionControl *mc,
64                     guint           operation_id,
65                     guint           error_code,
66                     gpointer        user_data)
67 {
68         empathy_debug (DEBUG_DOMAIN, "Error code %d during operation %d",
69                       error_code,
70                       operation_id);
71 }
72
73 static void
74 start_mission_control (EmpathyIdle *idle)
75 {
76         McPresence presence;
77
78         presence = empathy_idle_get_state (idle);
79
80         if (presence > MC_PRESENCE_OFFLINE) {
81                 /* MC is already running and online, nothing to do */
82                 return;
83         }
84
85         empathy_idle_set_state (idle, MC_PRESENCE_AVAILABLE);
86 }
87
88 static void
89 account_enabled_cb (McAccountMonitor *monitor,
90                     gchar            *unique_name,
91                     EmpathyIdle      *idle)
92 {
93         empathy_debug (DEBUG_DOMAIN, "Account enabled: %s", unique_name);
94         start_mission_control (idle);
95 }
96
97 static void
98 create_salut_account (void)
99 {
100         McProfile  *profile;
101         McProtocol *protocol;
102         gboolean    salut_created = FALSE;
103         McAccount  *account;
104         GList      *accounts;
105         EBook      *book;
106         EContact   *contact;
107         gchar      *nickname = NULL;
108         gchar      *first_name = NULL;
109         gchar      *last_name = NULL;
110         gchar      *email = NULL;
111         gchar      *jid = NULL;
112
113         /* Check if we already created a salut account */
114         empathy_conf_get_bool (empathy_conf_get(),
115                                EMPATHY_PREFS_SALUT_ACCOUNT_CREATED,
116                                &salut_created);
117         if (salut_created) {
118                 return;
119         }
120
121         empathy_debug (DEBUG_DOMAIN, "Try to add a salut account...");
122
123         /* Check if the salut CM is installed */
124         profile = mc_profile_lookup ("salut");
125         protocol = mc_profile_get_protocol (profile);
126         if (!protocol) {
127                 empathy_debug (DEBUG_DOMAIN, "Salut not installed");
128                 g_object_unref (profile);
129                 return;
130         }
131         g_object_unref (protocol);
132
133         /* Get self EContact from EDS */
134         if (!e_book_get_self (&contact, &book, NULL)) {
135                 empathy_debug (DEBUG_DOMAIN, "Failed to get self econtact");
136                 g_object_unref (profile);
137                 return;
138         }
139
140         empathy_conf_set_bool (empathy_conf_get (),
141                                EMPATHY_PREFS_SALUT_ACCOUNT_CREATED,
142                                TRUE);
143
144         /* Check if there is already a salut account */
145         accounts = mc_accounts_list_by_profile (profile);
146         if (accounts) {
147                 empathy_debug (DEBUG_DOMAIN, "There is already a salut account");
148                 mc_accounts_list_free (accounts);
149                 g_object_unref (profile);
150                 return;
151         }
152
153         account = mc_account_create (profile);
154         mc_account_set_display_name (account, _("People nearby"));
155         
156         nickname = e_contact_get (contact, E_CONTACT_NICKNAME);
157         first_name = e_contact_get (contact, E_CONTACT_GIVEN_NAME);
158         last_name = e_contact_get (contact, E_CONTACT_FAMILY_NAME);
159         email = e_contact_get (contact, E_CONTACT_EMAIL_1);
160         jid = e_contact_get (contact, E_CONTACT_IM_JABBER_HOME_1);
161         
162         if (!tp_strdiff (nickname, "nickname")) {
163                 g_free (nickname);
164                 nickname = NULL;
165         }
166
167         empathy_debug (DEBUG_DOMAIN, "Salut account created:\n"
168                                      "  nickname=%s\n"
169                                      "  first-name=%s\n"
170                                      "  last-name=%s\n"
171                                      "  email=%s\n"
172                                      "  jid=%s\n",
173                        nickname, first_name, last_name, email, jid);
174
175         mc_account_set_param_string (account, "nickname", nickname ? nickname : "");
176         mc_account_set_param_string (account, "first-name", first_name ? first_name : "");
177         mc_account_set_param_string (account, "last-name", last_name ? last_name : "");
178         mc_account_set_param_string (account, "email", email ? email : "");
179         mc_account_set_param_string (account, "jid", jid ? jid : "");
180
181         g_free (nickname);
182         g_free (first_name);
183         g_free (last_name);
184         g_free (email);
185         g_free (jid);
186         g_object_unref (account);
187         g_object_unref (profile);
188         g_object_unref (contact);
189         g_object_unref (book);
190 }
191
192 /* The code that handles single-instance and startup notification is
193  * copied from gedit.
194  *
195  * Copyright (C) 2005 - Paolo Maggi 
196  */
197 static void
198 on_bacon_message_received (const char *message,
199                            gpointer    data)
200 {
201         GtkWidget *window = data;
202         guint32    startup_timestamp;
203
204         g_return_if_fail (message != NULL);
205
206         empathy_debug (DEBUG_DOMAIN,
207                        "Other instance launched, presenting the main window "
208                        "(message is '%s')", message);
209
210         startup_timestamp = atoi (message);
211
212         /* Set the proper interaction time on the window.
213          * Fall back to roundtripping to the X server when we
214          * don't have the timestamp, e.g. when launched from
215          * terminal. We also need to make sure that the window
216          * has been realized otherwise it will not work. lame. */
217         if (startup_timestamp == 0) {
218                 /* Work if launched from the terminal */
219                 empathy_debug (DEBUG_DOMAIN, "Using X server timestamp as a fallback");
220
221                 if (!GTK_WIDGET_REALIZED (window)) {
222                         gtk_widget_realize (GTK_WIDGET (window));
223                 }
224
225                 startup_timestamp = gdk_x11_get_server_time (window->window);
226         }
227
228         gtk_window_present_with_time (GTK_WINDOW (window), startup_timestamp);
229 }
230
231 static guint32
232 get_startup_timestamp ()
233 {
234         const gchar *startup_id_env;
235         gchar       *startup_id = NULL;
236         gchar       *time_str;
237         gchar       *end;
238         gulong       retval = 0;
239
240         /* we don't unset the env, since startup-notification
241          * may still need it */
242         startup_id_env = g_getenv ("DESKTOP_STARTUP_ID");
243         if (startup_id_env == NULL) {
244                 goto out;
245         }
246
247         startup_id = g_strdup (startup_id_env);
248
249         time_str = g_strrstr (startup_id, "_TIME");
250         if (time_str == NULL) {
251                 goto out;
252         }
253
254         errno = 0;
255
256         /* Skip past the "_TIME" part */
257         time_str += 5;
258
259         retval = strtoul (time_str, &end, 0);
260         if (end == time_str || errno != 0)
261                 retval = 0;
262
263  out:
264         g_free (startup_id);
265
266         return (retval > 0) ? retval : 0;
267 }
268
269 int
270 main (int argc, char *argv[])
271 {
272         guint32            startup_timestamp;
273         EmpathyStatusIcon *icon;
274         GtkWidget         *window;
275         MissionControl    *mc;
276         McAccountMonitor  *monitor;
277         EmpathyIdle       *idle;
278         gboolean           autoconnect = TRUE;
279         GError            *error = NULL;
280
281         empathy_debug_set_log_file_from_env ();
282
283         bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
284         bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
285         textdomain (GETTEXT_PACKAGE);
286
287         startup_timestamp = get_startup_timestamp ();
288
289         if (!gtk_init_with_args (&argc, &argv,
290                                  _("- Empathy Instant Messenger"),
291                                  NULL, GETTEXT_PACKAGE, &error)) {
292                 empathy_debug (DEBUG_DOMAIN, error->message);
293                 return EXIT_FAILURE;
294         }
295
296         g_set_application_name (PACKAGE_NAME);
297
298         gtk_window_set_default_icon_name ("empathy");
299         gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
300                                            PKGDATADIR G_DIR_SEPARATOR_S "icons");
301
302         /* Setting up the bacon connection */
303         connection = bacon_message_connection_new ("empathy");
304         if (connection != NULL) {
305                 if (!bacon_message_connection_get_is_server (connection)) {
306                         gchar *message;
307
308                         empathy_debug (DEBUG_DOMAIN, "Activating existing instance");
309
310                         message = g_strdup_printf ("%" G_GUINT32_FORMAT,
311                                                    startup_timestamp);
312                         bacon_message_connection_send (connection, message);
313
314                         /* We never popup a window, so tell startup-notification
315                          * that we are done. */
316                         gdk_notify_startup_complete ();
317
318                         g_free (message);
319                         bacon_message_connection_free (connection);
320
321                         return EXIT_SUCCESS;
322                 }
323         } else {
324                 g_warning ("Cannot create the 'empathy' bacon connection.");
325         }
326
327         /* Setting up MC */
328         monitor = mc_account_monitor_new ();
329         mc = empathy_mission_control_new ();
330         idle = empathy_idle_new ();
331         g_signal_connect (monitor, "account-enabled",
332                           G_CALLBACK (account_enabled_cb),
333                           idle);
334         g_signal_connect (mc, "ServiceEnded",
335                           G_CALLBACK (service_ended_cb),
336                           NULL);
337         g_signal_connect (mc, "Error",
338                           G_CALLBACK (operation_error_cb),
339                           NULL);
340
341         empathy_conf_get_bool (empathy_conf_get(),
342                                EMPATHY_PREFS_AUTOCONNECT,
343                                &autoconnect);
344                                
345         if (autoconnect) {
346                 start_mission_control (idle);
347         }
348         
349         create_salut_account ();
350
351         /* Setting up UI */
352         window = empathy_main_window_show ();
353         icon = empathy_status_icon_new (GTK_WINDOW (window));
354
355         if (connection) {
356                 /* We se the callback here because we need window */
357                 bacon_message_connection_set_callback (connection,
358                                                        on_bacon_message_received,
359                                                        window);
360         }
361
362         gtk_main ();
363
364         empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);
365
366         g_object_unref (monitor);
367         g_object_unref (mc);
368         g_object_unref (idle);
369         g_object_unref (icon);
370
371         return EXIT_SUCCESS;
372 }
373