]> git.0d.be Git - empathy.git/blob - src/empathy.c
Merge branch 'master' into mc5
[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., 51 Franklin St, Fifth Floor,
18  * Boston, MA  02110-1301  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 #include <string.h>
28
29 #include <glib.h>
30 #include <glib/gi18n.h>
31 #include <gtk/gtk.h>
32 #include <gdk/gdkx.h>
33
34 #if HAVE_LIBCHAMPLAIN
35 #include <clutter-gtk/gtk-clutter-embed.h>
36 #endif
37
38 #include <libebook/e-book.h>
39 #include <libnotify/notify.h>
40
41 #include <telepathy-glib/dbus.h>
42 #include <telepathy-glib/util.h>
43 #include <telepathy-glib/connection-manager.h>
44 #include <telepathy-glib/interfaces.h>
45
46 #include <libempathy/empathy-idle.h>
47 #include <libempathy/empathy-utils.h>
48 #include <libempathy/empathy-call-factory.h>
49 #include <libempathy/empathy-chatroom-manager.h>
50 #include <libempathy/empathy-account-settings.h>
51 #include <libempathy/empathy-account-manager.h>
52 #include <libempathy/empathy-connection-managers.h>
53 #include <libempathy/empathy-debugger.h>
54 #include <libempathy/empathy-dispatcher.h>
55 #include <libempathy/empathy-dispatch-operation.h>
56 #include <libempathy/empathy-log-manager.h>
57 #include <libempathy/empathy-ft-factory.h>
58 #include <libempathy/empathy-tp-chat.h>
59 #include <libempathy/empathy-tp-call.h>
60
61 #include <libempathy-gtk/empathy-conf.h>
62 #include <libempathy-gtk/empathy-ui-utils.h>
63 #include <libempathy-gtk/empathy-location-manager.h>
64
65 #include "empathy-accounts-dialog.h"
66 #include "empathy-main-window.h"
67 #include "empathy-status-icon.h"
68 #include "empathy-call-window.h"
69 #include "empathy-chat-window.h"
70 #include "empathy-ft-manager.h"
71 #include "bacon-message-connection.h"
72
73 #include "extensions/extensions.h"
74
75 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
76 #include <libempathy/empathy-debug.h>
77
78 #include <gst/gst.h>
79
80 static BaconMessageConnection *connection = NULL;
81
82 static void
83 dispatch_cb (EmpathyDispatcher *dispatcher,
84              EmpathyDispatchOperation *operation,
85              gpointer           user_data)
86 {
87         GQuark channel_type;
88
89         channel_type = empathy_dispatch_operation_get_channel_type_id (operation);
90
91         if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT) {
92                 EmpathyTpChat *tp_chat;
93                 EmpathyChat   *chat = NULL;
94                 const gchar   *id;
95
96                 tp_chat = EMPATHY_TP_CHAT (
97                         empathy_dispatch_operation_get_channel_wrapper (operation));
98
99                 id = empathy_tp_chat_get_id (tp_chat);
100                 if (!id) {
101                         EmpathyContact *contact;
102
103                         contact = empathy_tp_chat_get_remote_contact (tp_chat);
104                         if (contact) {
105                                 id = empathy_contact_get_id (contact);
106                         }
107                 }
108
109                 if (id) {
110                         EmpathyAccountManager *manager;
111                         TpConnection *connection;
112                         EmpathyAccount *account;
113
114                         manager = empathy_account_manager_dup_singleton ();
115                         connection = empathy_tp_chat_get_connection (tp_chat);
116                         account = empathy_account_manager_get_account_for_connection (manager,
117                                                                        connection);
118                         chat = empathy_chat_window_find_chat (account, id);
119                         g_object_unref (manager);
120                 }
121
122                 if (chat) {
123                         empathy_chat_set_tp_chat (chat, tp_chat);
124                 } else {
125                         chat = empathy_chat_new (tp_chat);
126                 }
127
128                 empathy_chat_window_present_chat (chat);
129
130                 empathy_dispatch_operation_claim (operation);
131         } else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA) {
132                 EmpathyCallFactory *factory;
133
134                 factory = empathy_call_factory_get ();
135                 empathy_call_factory_claim_channel (factory, operation);
136         } else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER) {
137                 EmpathyFTFactory *factory;
138
139                 factory = empathy_ft_factory_dup_singleton ();
140
141                 /* if the operation is not incoming, don't claim it,
142                  * as it might have been triggered by another client, and
143                  * we are observing it.
144                  */
145                 if (empathy_dispatch_operation_is_incoming (operation)) {
146                         empathy_ft_factory_claim_channel (factory, operation);
147                 }
148         }
149 }
150
151 static void
152 use_nm_notify_cb (EmpathyConf *conf,
153                   const gchar *key,
154                   gpointer     user_data)
155 {
156         EmpathyIdle *idle = user_data;
157         gboolean     use_nm;
158
159         if (empathy_conf_get_bool (conf, key, &use_nm)) {
160                 empathy_idle_set_use_nm (idle, use_nm);
161         }
162 }
163
164 /* Salut account creation */
165 static gboolean
166 should_create_salut_account (void)
167 {
168         EmpathyAccountManager *manager;
169         gboolean salut_created = FALSE;
170         GList *accounts, *l;
171
172         /* Check if we already created a salut account */
173         empathy_conf_get_bool (empathy_conf_get (),
174                                EMPATHY_PREFS_SALUT_ACCOUNT_CREATED,
175                                &salut_created);
176
177         if (salut_created)
178                 {
179                         DEBUG ("Gconf says we already created a salut account once");
180                         return FALSE;
181                 }
182
183         manager = empathy_account_manager_dup_singleton ();
184         accounts = empathy_account_manager_dup_accounts (manager);
185
186         for (l = accounts; l != NULL;  l = g_list_next (l)) {
187                 EmpathyAccount *account = EMPATHY_ACCOUNT (l->data);
188
189                 if (!tp_strdiff (empathy_account_get_protocol (account), "local-xmpp"))
190                         salut_created = TRUE;
191
192                 g_object_unref (account);
193         }
194
195         g_object_unref (manager);
196
197         if (salut_created)
198                 {
199                         DEBUG ("Existing salut account already exists, flagging so in gconf");
200                         empathy_conf_set_bool (empathy_conf_get (),
201                                 EMPATHY_PREFS_SALUT_ACCOUNT_CREATED,
202                                 TRUE);
203                 }
204
205         return !salut_created;
206 }
207
208 static void
209 salut_account_created (GObject *source,
210         GAsyncResult *result, gpointer user_data)
211 {
212         EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (source);
213         EmpathyAccount *account;
214         GError *error = NULL;
215
216         if (!empathy_account_settings_apply_finish (settings, result, &error))
217                 {
218                         DEBUG ("Failed to create salut account: %s", error->message);
219                         g_error_free (error);
220                         return;
221                 }
222
223         account = empathy_account_settings_get_account (settings);
224
225         empathy_account_set_enabled (account, TRUE);
226         empathy_conf_set_bool (empathy_conf_get (),
227                                EMPATHY_PREFS_SALUT_ACCOUNT_CREATED,
228                                TRUE);
229 }
230
231 static void
232 create_salut_account_if_needed (EmpathyConnectionManagers *managers)
233 {
234         EmpathyAccountSettings  *settings;
235         TpConnectionManager *manager;
236         const TpConnectionManagerProtocol *protocol;
237         EBook      *book;
238         EContact   *contact;
239         gchar      *nickname = NULL;
240         gchar      *first_name = NULL;
241         gchar      *last_name = NULL;
242         gchar      *email = NULL;
243         gchar      *jid = NULL;
244         GError     *error = NULL;
245
246
247         if (!should_create_salut_account ())
248                 return;
249
250         manager = empathy_connection_managers_get_cm (managers, "salut");
251         if (manager == NULL)
252                 {
253                         DEBUG ("Salut not installed, not making a salut account");
254                         return;
255                 }
256
257         protocol = tp_connection_manager_get_protocol (manager, "local-xmpp");
258         if (protocol == NULL)
259                 {
260                         DEBUG ("Salut doesn't support local-xmpp!!");
261                         return;
262                 }
263
264         DEBUG ("Trying to add a salut account...");
265
266         /* Get self EContact from EDS */
267         if (!e_book_get_self (&contact, &book, &error)) {
268                 DEBUG ("Failed to get self econtact: %s",
269                         error ? error->message : "No error given");
270                 g_clear_error (&error);
271                 return;
272         }
273
274         settings = empathy_account_settings_new ("salut", "local-xmpp",
275                 _("People nearby"));
276
277         nickname = e_contact_get (contact, E_CONTACT_NICKNAME);
278         first_name = e_contact_get (contact, E_CONTACT_GIVEN_NAME);
279         last_name = e_contact_get (contact, E_CONTACT_FAMILY_NAME);
280         email = e_contact_get (contact, E_CONTACT_EMAIL_1);
281         jid = e_contact_get (contact, E_CONTACT_IM_JABBER_HOME_1);
282
283         if (!tp_strdiff (nickname, "nickname")) {
284                 g_free (nickname);
285                 nickname = NULL;
286         }
287
288         DEBUG ("Salut account created:\nnickname=%s\nfirst-name=%s\n"
289                 "last-name=%s\nemail=%s\njid=%s\n",
290                 nickname, first_name, last_name, email, jid);
291
292         empathy_account_settings_set_string (settings, "nickname", nickname ? nickname : "");
293         empathy_account_settings_set_string (settings, "first-name", first_name ? first_name : "");
294         empathy_account_settings_set_string (settings, "last-name", last_name ? last_name : "");
295         empathy_account_settings_set_string (settings, "email", email ? email : "");
296         empathy_account_settings_set_string (settings, "jid", jid ? jid : "");
297
298         empathy_account_settings_apply_async (settings,
299                 salut_account_created, NULL);
300
301         g_free (nickname);
302         g_free (first_name);
303         g_free (last_name);
304         g_free (email);
305         g_free (jid);
306         g_object_unref (settings);
307         g_object_unref (contact);
308         g_object_unref (book);
309 }
310
311 static void
312 connection_managers_ready_cb (EmpathyConnectionManagers *managers,
313         GParamSpec *spec, gpointer user_data)
314 {
315         if (empathy_connection_managers_is_ready (managers))
316                 {
317                         create_salut_account_if_needed (managers);
318                         g_object_unref (managers);
319                         managers = NULL;
320                 }
321 }
322
323 static void
324 create_salut_account (void)
325 {
326         EmpathyConnectionManagers *managers;
327
328         if (!should_create_salut_account ())
329                 return;
330
331         managers = empathy_connection_managers_dup_singleton ();
332
333         if (empathy_connection_managers_is_ready (managers))
334                 {
335                         create_salut_account_if_needed (managers);
336                         g_object_unref (managers);
337                 }
338         else
339                 {
340                         g_signal_connect (managers, "notify::ready",
341                                 G_CALLBACK (connection_managers_ready_cb), NULL);
342                 }
343 }
344
345 static void
346 migrate_config_to_xdg_dir (void)
347 {
348         gchar *xdg_dir, *old_dir, *xdg_filename, *old_filename;
349         int i;
350         GFile *xdg_file, *old_file;
351         static const gchar* filenames[] = {
352                 "geometry.ini",
353                 "irc-networks.xml",
354                 "chatrooms.xml",
355                 "contact-groups.xml",
356                 "status-presets.xml",
357                 "accels.txt",
358                 NULL
359         };
360
361         xdg_dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
362         if (g_file_test (xdg_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
363                 /* xdg config dir already exists */
364                 g_free (xdg_dir);
365                 return;
366         }
367
368         old_dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
369         if (!g_file_test (old_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
370                 /* old config dir didn't exist */
371                 g_free (xdg_dir);
372                 g_free (old_dir);
373                 return;
374         }
375
376         if (g_mkdir_with_parents (xdg_dir, (S_IRUSR | S_IWUSR | S_IXUSR)) == -1) {
377                 DEBUG ("Failed to create configuration directory; aborting migration");
378                 g_free (xdg_dir);
379                 g_free (old_dir);
380                 return;
381         }
382
383         for (i = 0; filenames[i]; i++) {
384                 old_filename = g_build_filename (old_dir, filenames[i], NULL);
385                 if (!g_file_test (old_filename, G_FILE_TEST_EXISTS)) {
386                         g_free (old_filename);
387                         continue;
388                 }
389                 xdg_filename = g_build_filename (xdg_dir, filenames[i], NULL);
390                 old_file = g_file_new_for_path (old_filename);
391                 xdg_file = g_file_new_for_path (xdg_filename);
392                 if (!g_file_move (old_file, xdg_file, G_FILE_COPY_NONE,
393                                   NULL, NULL, NULL, NULL)) {
394                         DEBUG ("Failed to migrate %s", filenames[i]);
395                 }
396                 g_free (old_filename);
397                 g_free (xdg_filename);
398                 g_object_unref (old_file);
399                 g_object_unref (xdg_file);
400         }
401
402         g_free (xdg_dir);
403         g_free (old_dir);
404 }
405
406 /* The code that handles single-instance and startup notification is
407  * copied from gedit.
408  *
409  * Copyright (C) 2005 - Paolo Maggi
410  */
411 static void
412 on_bacon_message_received (const char *message,
413                            gpointer    data)
414 {
415         GtkWidget *window = data;
416         guint32    startup_timestamp;
417
418         g_return_if_fail (message != NULL);
419
420         DEBUG ("Other instance launched, presenting the main window. message='%s'",
421                 message);
422
423         if (strcmp (message, "accounts") == 0) {
424                 /* accounts dialog requested */
425                 empathy_accounts_dialog_show (GTK_WINDOW (window), NULL);
426         } else {
427                 startup_timestamp = atoi (message);
428
429                 /* Set the proper interaction time on the window.
430                  * Fall back to roundtripping to the X server when we
431                  * don't have the timestamp, e.g. when launched from
432                  * terminal. We also need to make sure that the window
433                  * has been realized otherwise it will not work. lame. */
434                 if (startup_timestamp == 0) {
435                         /* Work if launched from the terminal */
436                         DEBUG ("Using X server timestamp as a fallback");
437
438                         if (!GTK_WIDGET_REALIZED (window)) {
439                                 gtk_widget_realize (GTK_WIDGET (window));
440                         }
441
442                         startup_timestamp = gdk_x11_get_server_time (gtk_widget_get_window (window));
443                 }
444
445                 gtk_window_present_with_time (GTK_WINDOW (window), startup_timestamp);
446         }
447 }
448
449 static guint32
450 get_startup_timestamp ()
451 {
452         const gchar *startup_id_env;
453         gchar       *startup_id = NULL;
454         gchar       *time_str;
455         gchar       *end;
456         gulong       retval = 0;
457
458         /* we don't unset the env, since startup-notification
459          * may still need it */
460         startup_id_env = g_getenv ("DESKTOP_STARTUP_ID");
461         if (startup_id_env == NULL) {
462                 goto out;
463         }
464
465         startup_id = g_strdup (startup_id_env);
466
467         time_str = g_strrstr (startup_id, "_TIME");
468         if (time_str == NULL) {
469                 goto out;
470         }
471
472         errno = 0;
473
474         /* Skip past the "_TIME" part */
475         time_str += 5;
476
477         retval = strtoul (time_str, &end, 0);
478         if (end == time_str || errno != 0)
479                 retval = 0;
480
481  out:
482         g_free (startup_id);
483
484         return (retval > 0) ? retval : 0;
485 }
486
487 static gboolean
488 show_version_cb (const char *option_name,
489                  const char *value,
490                  gpointer data,
491                  GError **error)
492 {
493         g_print ("%s\n", PACKAGE_STRING);
494
495         exit (EXIT_SUCCESS);
496
497         return FALSE;
498 }
499
500 static void
501 new_incoming_transfer_cb (EmpathyFTFactory *factory,
502                           EmpathyFTHandler *handler,
503                           GError *error,
504                           gpointer user_data)
505 {
506         if (error) {
507                 empathy_ft_manager_display_error (handler, error);
508         } else {
509                 empathy_receive_file_with_file_chooser (handler);
510         }
511 }
512
513 static void
514 new_ft_handler_cb (EmpathyFTFactory *factory,
515                    EmpathyFTHandler *handler,
516                    GError *error,
517                    gpointer user_data)
518 {
519         if (error) {
520                 empathy_ft_manager_display_error (handler, error);
521         } else {
522                 empathy_ft_manager_add_handler (handler);
523         }
524
525         g_object_unref (handler);
526 }
527
528 static void
529 new_call_handler_cb (EmpathyCallFactory *factory, EmpathyCallHandler *handler,
530         gboolean outgoing, gpointer user_data)
531 {
532         EmpathyCallWindow *window;
533
534         window = empathy_call_window_new (handler);
535         gtk_widget_show (GTK_WIDGET (window));
536 }
537
538 #ifdef ENABLE_DEBUG
539 static void
540 default_log_handler (const gchar *log_domain,
541     GLogLevelFlags log_level,
542     const gchar *message,
543     gpointer user_data)
544 {
545         g_log_default_handler (log_domain, log_level, message, NULL);
546
547         /* G_LOG_DOMAIN = "empathy". No need to send empathy messages to the
548          * debugger as they already have in empathy_debug. */
549         if (log_level != G_LOG_LEVEL_DEBUG
550             || tp_strdiff (log_domain, G_LOG_DOMAIN)) {
551                 EmpathyDebugger *dbg;
552                 GTimeVal now;
553
554                 dbg = empathy_debugger_get_singleton ();
555                 g_get_current_time (&now);
556
557                 empathy_debugger_add_message (dbg, &now, log_domain,
558                                               log_level, message);
559         }
560 }
561 #endif /* ENABLE_DEBUG */
562
563 static void
564 account_manager_ready_cb (EmpathyAccountManager *manager,
565         GParamSpec *spec,
566         gpointer user_data)
567 {
568         if (!empathy_account_manager_is_ready (manager))
569                 return;
570
571         if (empathy_account_manager_get_count (manager) == 0)
572                 {
573                         empathy_accounts_dialog_show (GTK_WINDOW (empathy_main_window_get ()),
574                                 NULL);
575                 }
576         create_salut_account ();
577 }
578
579 int
580 main (int argc, char *argv[])
581 {
582         guint32            startup_timestamp;
583 #if HAVE_GEOCLUE
584         EmpathyLocationManager *location_manager = NULL;
585 #endif
586         EmpathyStatusIcon *icon;
587         EmpathyDispatcher *dispatcher;
588         EmpathyAccountManager *account_manager;
589         EmpathyLogManager *log_manager;
590         EmpathyChatroomManager *chatroom_manager;
591         EmpathyCallFactory *call_factory;
592         EmpathyFTFactory  *ft_factory;
593         GtkWidget         *window;
594         EmpathyIdle       *idle;
595         gboolean           autoconnect = TRUE;
596         gboolean           no_connect = FALSE;
597         gboolean           hide_contact_list = FALSE;
598         gboolean           accounts_dialog = FALSE;
599         GError            *error = NULL;
600         TpDBusDaemon      *dbus_daemon;
601         GOptionEntry       options[] = {
602                 { "no-connect", 'n',
603                   0, G_OPTION_ARG_NONE, &no_connect,
604                   N_("Don't connect on startup"),
605                   NULL },
606                 { "hide-contact-list", 'h',
607                   0, G_OPTION_ARG_NONE, &hide_contact_list,
608                   N_("Don't show the contact list on startup"),
609                   NULL },
610                 { "accounts", 'a',
611                   0, G_OPTION_ARG_NONE, &accounts_dialog,
612                   N_("Show the accounts dialog"),
613                   NULL },
614                 { "version", 'v',
615                   G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, show_version_cb, NULL, NULL },
616                 { NULL }
617         };
618
619         /* Init */
620         g_thread_init (NULL);
621         empathy_init ();
622
623         if (!gtk_init_with_args (&argc, &argv,
624                                  N_("- Empathy IM Client"),
625                                  options, GETTEXT_PACKAGE, &error)) {
626                 g_warning ("Error in empathy init: %s", error->message);
627                 return EXIT_FAILURE;
628         }
629
630         empathy_gtk_init ();
631         g_set_application_name (_(PACKAGE_NAME));
632         g_setenv ("PULSE_PROP_media.role", "phone", TRUE);
633
634         gst_init (&argc, &argv);
635
636 #if HAVE_LIBCHAMPLAIN
637         gtk_clutter_init (&argc, &argv);
638 #endif
639
640         gtk_window_set_default_icon_name ("empathy");
641         textdomain (GETTEXT_PACKAGE);
642
643 #ifdef ENABLE_DEBUG
644         /* Set up debugger */
645         g_log_set_default_handler (default_log_handler, NULL);
646 #endif
647
648         /* Setting up the bacon connection */
649         startup_timestamp = get_startup_timestamp ();
650         connection = bacon_message_connection_new ("empathy");
651         if (connection != NULL) {
652                 if (!bacon_message_connection_get_is_server (connection)) {
653                         gchar *message;
654
655                         if (accounts_dialog) {
656                                 DEBUG ("Showing accounts dialog from existing Empathy instance");
657
658                                 message = g_strdup ("accounts");
659
660                         } else {
661
662                                 DEBUG ("Activating existing instance");
663
664                                 message = g_strdup_printf ("%" G_GUINT32_FORMAT,
665                                                            startup_timestamp);
666                         }
667
668                         bacon_message_connection_send (connection, message);
669
670                         /* We never popup a window, so tell startup-notification
671                          * that we are done. */
672                         gdk_notify_startup_complete ();
673
674                         g_free (message);
675                         bacon_message_connection_free (connection);
676
677                         return EXIT_SUCCESS;
678                 }
679         } else {
680                 g_warning ("Cannot create the 'empathy' bacon connection.");
681         }
682
683         /* Take well-known name */
684         dbus_daemon = tp_dbus_daemon_dup (&error);
685         if (error == NULL) {
686                 if (!tp_dbus_daemon_request_name (dbus_daemon,
687                                                   "org.gnome.Empathy",
688                                                   TRUE, &error)) {
689                         DEBUG ("Failed to request well-known name: %s",
690                                error ? error->message : "no message");
691                         g_clear_error (&error);
692                 }
693                 g_object_unref (dbus_daemon);
694         } else {
695                 DEBUG ("Failed to dup dbus daemon: %s",
696                        error ? error->message : "no message");
697                 g_clear_error (&error);
698         }
699
700         if (accounts_dialog) {
701                 GtkWidget *dialog;
702
703                 dialog = empathy_accounts_dialog_show (NULL, NULL);
704                 g_signal_connect (dialog, "destroy",
705                                   G_CALLBACK (gtk_main_quit),
706                                   NULL);
707
708                 gtk_main ();
709                 return 0;
710         }
711
712         /* Setting up Idle */
713         idle = empathy_idle_dup_singleton ();
714         empathy_idle_set_auto_away (idle, TRUE);
715         use_nm_notify_cb (empathy_conf_get (), EMPATHY_PREFS_USE_NM, idle);
716         empathy_conf_notify_add (empathy_conf_get (), EMPATHY_PREFS_USE_NM,
717                                  use_nm_notify_cb, idle);
718
719         /* Autoconnect */
720         empathy_conf_get_bool (empathy_conf_get (),
721                                EMPATHY_PREFS_AUTOCONNECT,
722                                &autoconnect);
723         if (autoconnect && ! no_connect &&
724                 tp_connection_presence_type_cmp_availability (empathy_idle_get_state
725                         (idle), TP_CONNECTION_PRESENCE_TYPE_OFFLINE) <= 0) {
726                 empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE);
727         }
728
729         /* account management */
730         account_manager = empathy_account_manager_dup_singleton ();
731         g_signal_connect (account_manager, "notify::ready",
732                 G_CALLBACK (account_manager_ready_cb), NULL);
733
734         migrate_config_to_xdg_dir ();
735
736         /* Setting up UI */
737         window = empathy_main_window_show ();
738         icon = empathy_status_icon_new (GTK_WINDOW (window), hide_contact_list);
739
740         if (connection) {
741                 /* We se the callback here because we need window */
742                 bacon_message_connection_set_callback (connection,
743                                                        on_bacon_message_received,
744                                                        window);
745         }
746
747         /* Handle channels */
748         dispatcher = empathy_dispatcher_dup_singleton ();
749         g_signal_connect (dispatcher, "dispatch", G_CALLBACK (dispatch_cb), NULL);
750
751         /* Logging */
752         log_manager = empathy_log_manager_dup_singleton ();
753         empathy_log_manager_observe (log_manager, dispatcher);
754
755         chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
756         empathy_chatroom_manager_observe (chatroom_manager, dispatcher);
757
758         notify_init (_(PACKAGE_NAME));
759         /* Create the call factory */
760         call_factory = empathy_call_factory_initialise ();
761         g_signal_connect (G_OBJECT (call_factory), "new-call-handler",
762                 G_CALLBACK (new_call_handler_cb), NULL);
763         /* Create the FT factory */
764         ft_factory = empathy_ft_factory_dup_singleton ();
765         g_signal_connect (ft_factory, "new-ft-handler",
766                 G_CALLBACK (new_ft_handler_cb), NULL);
767         g_signal_connect (ft_factory, "new-incoming-transfer",
768                 G_CALLBACK (new_incoming_transfer_cb), NULL);
769
770         /* Location mananger */
771 #if HAVE_GEOCLUE
772         location_manager = empathy_location_manager_dup_singleton ();
773 #endif
774
775         gtk_main ();
776
777         empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_OFFLINE);
778
779         g_object_unref (idle);
780         g_object_unref (icon);
781         g_object_unref (account_manager);
782         g_object_unref (log_manager);
783         g_object_unref (dispatcher);
784         g_object_unref (chatroom_manager);
785 #if HAVE_GEOCLUE
786         g_object_unref (location_manager);
787 #endif
788         g_object_unref (ft_factory);
789
790         notify_uninit ();
791
792         return EXIT_SUCCESS;
793 }