]> git.0d.be Git - empathy.git/blobdiff - src/empathy.c
Merge remote-tracking branch 'glassrose/add-All-service-selection-in-debug-window'
[empathy.git] / src / empathy.c
index b2005f19c520e11c2acc39f62daaa1bfa9fb0da5..f59a54f17f7c559ec41512f87077c5a5b95e5ee4 100644 (file)
 #include <telepathy-glib/connection-manager.h>
 #include <telepathy-glib/interfaces.h>
 
+#include <telepathy-yell/telepathy-yell.h>
+
 #include <telepathy-logger/log-manager.h>
 
-#include <libempathy/empathy-idle.h>
+#include <libempathy/empathy-client-factory.h>
+#include <libempathy/empathy-connection-aggregator.h>
+#include <libempathy/empathy-presence-manager.h>
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-chatroom-manager.h>
 #include <libempathy/empathy-account-settings.h>
 #include <libempathy/empathy-connectivity.h>
 #include <libempathy/empathy-connection-managers.h>
-#include <libempathy/empathy-dispatcher.h>
+#include <libempathy/empathy-request-util.h>
 #include <libempathy/empathy-ft-factory.h>
 #include <libempathy/empathy-gsettings.h>
 #include <libempathy/empathy-tp-chat.h>
 
 #include <libempathy-gtk/empathy-ui-utils.h>
 #include <libempathy-gtk/empathy-location-manager.h>
+#include <libempathy-gtk/empathy-notify-manager.h>
 
-#include "empathy-main-window.h"
+#include "empathy-roster-window.h"
 #include "empathy-accounts-common.h"
 #include "empathy-accounts-dialog.h"
 #include "empathy-status-icon.h"
 #include "empathy-ft-manager.h"
+#include "empathy-notifications-approver.h"
 
 #include "extensions/extensions.h"
 
@@ -103,23 +109,30 @@ struct _EmpathyApp
   /* Properties */
   gboolean no_connect;
   gboolean start_hidden;
+  gboolean show_preferences;
+  gchar *preferences_tab;
+
+  gboolean activated;
 
   GtkWidget *window;
   EmpathyStatusIcon *icon;
-  EmpathyDispatcher *dispatcher;
   TpAccountManager *account_manager;
   TplLogManager *log_manager;
   EmpathyChatroomManager *chatroom_manager;
   EmpathyFTFactory  *ft_factory;
-  EmpathyIdle *idle;
+  EmpathyPresenceManager *presence_mgr;
   EmpathyConnectivity *connectivity;
   GSettings *gsettings;
+  EmpathyNotificationsApprover *notifications_approver;
+  EmpathyConnectionAggregator *conn_aggregator;
 #ifdef HAVE_GEOCLUE
   EmpathyLocationManager *location_manager;
 #endif
 #ifdef ENABLE_DEBUG
   TpDebugSender *debug_sender;
 #endif
+
+  gboolean shell_running;
 };
 
 
@@ -132,27 +145,32 @@ empathy_app_dispose (GObject *object)
   void (*dispose) (GObject *) =
     G_OBJECT_CLASS (empathy_app_parent_class)->dispose;
 
-  if (self->idle != NULL)
+  /* Only set our presence to offline when exiting if GNOME Shell is not
+   * running */
+  if (self->presence_mgr != NULL &&
+      !self->shell_running)
     {
-      empathy_idle_set_state (self->idle, TP_CONNECTION_PRESENCE_TYPE_OFFLINE);
+      empathy_presence_manager_set_state (self->presence_mgr,
+          TP_CONNECTION_PRESENCE_TYPE_OFFLINE);
     }
 
 #ifdef ENABLE_DEBUG
   tp_clear_object (&self->debug_sender);
 #endif
 
-  tp_clear_object (&self->idle);
+  tp_clear_object (&self->presence_mgr);
   tp_clear_object (&self->connectivity);
   tp_clear_object (&self->icon);
   tp_clear_object (&self->account_manager);
   tp_clear_object (&self->log_manager);
-  tp_clear_object (&self->dispatcher);
   tp_clear_object (&self->chatroom_manager);
 #ifdef HAVE_GEOCLUE
   tp_clear_object (&self->location_manager);
 #endif
   tp_clear_object (&self->ft_factory);
   tp_clear_object (&self->gsettings);
+  tp_clear_object (&self->notifications_approver);
+  tp_clear_object (&self->conn_aggregator);
 
   if (dispose != NULL)
     dispose (object);
@@ -165,7 +183,7 @@ empathy_app_finalize (GObject *object)
   void (*finalize) (GObject *) =
     G_OBJECT_CLASS (empathy_app_parent_class)->finalize;
 
-  gtk_widget_destroy (self->window);
+  g_free (self->preferences_tab);
 
   if (finalize != NULL)
     finalize (object);
@@ -198,22 +216,276 @@ empathy_app_set_property (GObject *object,
 }
 
 static void
-empathy_app_activate (GApplication *app)
+new_incoming_transfer_cb (EmpathyFTFactory *factory,
+    EmpathyFTHandler *handler,
+    GError *error,
+    gpointer user_data)
+{
+  if (error)
+    empathy_ft_manager_display_error (handler, error);
+  else
+    empathy_receive_file_with_file_chooser (handler);
+}
+
+static void
+new_ft_handler_cb (EmpathyFTFactory *factory,
+    EmpathyFTHandler *handler,
+    GError *error,
+    gpointer user_data)
+{
+  if (error)
+    empathy_ft_manager_display_error (handler, error);
+  else
+    empathy_ft_manager_add_handler (handler);
+
+  g_object_unref (handler);
+}
+
+static gboolean
+empathy_app_local_command_line (GApplication *app,
+    gchar ***arguments,
+    gint *exit_status);
+
+static void
+empathy_presence_manager_set_auto_away_cb (GSettings *gsettings,
+    const gchar *key,
+    gpointer user_data)
+{
+  EmpathyPresenceManager *presence_mgr = user_data;
+
+  empathy_presence_manager_set_auto_away (presence_mgr,
+      g_settings_get_boolean (gsettings, key));
+}
+
+#define GNOME_SHELL_BUS_NAME "org.gnome.Shell"
+
+static void
+list_names_cb (TpDBusDaemon *bus_daemon,
+        const gchar * const *names,
+        const GError *error,
+        gpointer user_data,
+        GObject *weak_object)
+{
+  EmpathyApp *self = (EmpathyApp *) weak_object;
+  guint i;
+
+  if (error != NULL)
+      goto out;
+
+  for (i = 0; names[i] != NULL; i++)
+    {
+      if (!tp_strdiff (names[i], GNOME_SHELL_BUS_NAME))
+        {
+          self->shell_running = TRUE;
+          break;
+        }
+    }
+
+out:
+  if (self->shell_running)
+    {
+      DEBUG ("GNOME Shell is running, don't create status icon");
+
+      /* Rely on GNOME Shell to watch session state */
+      empathy_presence_manager_set_auto_away (self->presence_mgr, FALSE);
+
+      empathy_roster_window_set_shell_running (
+          EMPATHY_ROSTER_WINDOW (self->window), TRUE);
+    }
+  else
+    {
+      gboolean autoaway;
+
+      self->icon = empathy_status_icon_new (GTK_WINDOW (self->window),
+          self->start_hidden);
+
+      /* Allow Empathy to watch session state */
+      autoaway = g_settings_get_boolean (self->gsettings,
+          EMPATHY_PREFS_AUTOAWAY);
+
+      g_signal_connect (self->gsettings,
+          "changed::" EMPATHY_PREFS_AUTOAWAY,
+          G_CALLBACK (empathy_presence_manager_set_auto_away_cb),
+          self->presence_mgr);
+
+      empathy_presence_manager_set_auto_away (self->presence_mgr, autoaway);
+    }
+}
+
+static int
+empathy_app_command_line (GApplication *app,
+    GApplicationCommandLine *cmdline)
 {
   EmpathyApp *self = (EmpathyApp *) app;
+  gchar **args, **argv;
+  gint argc, exit_status, i;
+
+  args = g_application_command_line_get_arguments (cmdline, &argc);
+  /* We have to make an extra copy of the array, since g_option_context_parse()
+   * assumes that it can remove strings from the array without freeing them. */
+  argv = g_new (gchar*, argc + 1);
+  for (i = 0; i <= argc; i++)
+    argv[i] = args[i];
+
+  if (empathy_app_local_command_line (app, &argv, &exit_status))
+    DEBUG ("failed to parse command line!");
+
+  g_free (argv);
+  g_strfreev (args);
+
+  if (!self->activated)
+    {
+      GError *error = NULL;
+      TpDBusDaemon *dbus;
+
+      /* Create the FT factory */
+      self->ft_factory = empathy_ft_factory_dup_singleton ();
+      g_signal_connect (self->ft_factory, "new-ft-handler",
+          G_CALLBACK (new_ft_handler_cb), NULL);
+      g_signal_connect (self->ft_factory, "new-incoming-transfer",
+          G_CALLBACK (new_incoming_transfer_cb), NULL);
+
+      if (!empathy_ft_factory_register (self->ft_factory, &error))
+        {
+          g_warning ("Failed to register FileTransfer handler: %s",
+              error->message);
+          g_error_free (error);
+        }
+
+      self->activated = TRUE;
+
+      /* Setting up UI */
+      self->window = empathy_roster_window_dup ();
+
+      gtk_application_add_window (GTK_APPLICATION (app),
+          GTK_WINDOW (self->window));
 
-  /* We're requested to show stuff again, disable the start hidden global
-   * in case the accounts wizard wants to pop up.
-   */
-  self->start_hidden = FALSE;
+      /* check if Shell is running */
+      dbus = tp_dbus_daemon_dup (&error);
+      g_assert_no_error (error);
 
-  g_application_hold (G_APPLICATION (app));
+      tp_dbus_daemon_list_names (dbus, -1, list_names_cb,
+              self, NULL, G_OBJECT (self));
 
-  empathy_window_present (GTK_WINDOW (self->window));
+      g_object_unref (dbus);
+
+      self->notifications_approver =
+        empathy_notifications_approver_dup_singleton ();
+    }
+  else
+    {
+      /* We're requested to show stuff again, disable the start hidden global in
+       * case the accounts wizard wants to pop up.
+       */
+      self->start_hidden = FALSE;
+    }
+
+  if (self->show_preferences)
+    empathy_roster_window_show_preferences (
+        EMPATHY_ROSTER_WINDOW (self->window), self->preferences_tab);
+
+  if (!self->start_hidden)
+    empathy_window_present (GTK_WINDOW (self->window));
 
   /* Display the accounts dialog if needed */
-  tp_account_manager_prepare_async (self->account_manager, NULL,
+  tp_proxy_prepare_async (self->account_manager, NULL,
       account_manager_ready_cb, self);
+
+  return 0;
+}
+
+static gboolean
+preferences_cb (const char *option_name,
+    const char *value,
+    gpointer data,
+    GError **error)
+{
+  EmpathyApp *self = data;
+
+  self->show_preferences = TRUE;
+
+  g_free (self->preferences_tab);
+  self->preferences_tab = g_strdup (value);
+
+  return TRUE;
+}
+
+static gboolean
+show_version_cb (const char *option_name,
+    const char *value,
+    gpointer data,
+    GError **error);
+
+static gboolean
+empathy_app_local_command_line (GApplication *app,
+    gchar ***arguments,
+    gint *exit_status)
+{
+  EmpathyApp *self = (EmpathyApp *) app;
+  gint i;
+  gchar **argv;
+  gint argc = 0;
+  gboolean retval = FALSE;
+  GError *error = NULL;
+  gboolean no_connect = FALSE, start_hidden = FALSE;
+
+  GOptionContext *optcontext;
+  GOptionGroup *group;
+  GOptionEntry options[] = {
+      { "no-connect", 'n',
+        0, G_OPTION_ARG_NONE, &no_connect,
+        N_("Don't connect on startup"),
+        NULL },
+      { "start-hidden", 'h',
+        0, G_OPTION_ARG_NONE, &start_hidden,
+        N_("Don't display the contact list or any other dialogs on startup"),
+        NULL },
+      { "show-preferences", 'p',
+        G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, &preferences_cb,
+        NULL, NULL },
+      { "version", 'v',
+        G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, show_version_cb,
+        NULL, NULL },
+      { NULL }
+  };
+
+  /* We create a group so that GOptionArgFuncs get the user data */
+  group = g_option_group_new ("empathy", NULL, NULL, app, NULL);
+  g_option_group_add_entries (group, options);
+
+  optcontext = g_option_context_new (N_("- Empathy IM Client"));
+  g_option_context_add_group (optcontext, gtk_get_option_group (TRUE));
+  g_option_context_set_main_group (optcontext, group);
+  g_option_context_set_translation_domain (optcontext, GETTEXT_PACKAGE);
+
+  argc = g_strv_length (*arguments);
+
+  /* We dup the args because g_option_context_parse() sets things to NULL,
+   * but we want to parse all the command line to the primary instance
+   * if necessary. */
+  argv = g_new (gchar*, argc + 1);
+  for (i = 0; i <= argc; i++)
+    argv[i] = (*arguments)[i];
+
+  if (!g_option_context_parse (optcontext, &argc, &argv, &error))
+    {
+      g_print ("%s\nRun '%s --help' to see a full list of available command "
+          "line options.\n",
+          error->message, argv[0]);
+      g_warning ("Error in empathy init: %s", error->message);
+
+      *exit_status = EXIT_FAILURE;
+      retval = TRUE;
+    }
+
+  g_free (argv);
+
+  g_option_context_free (optcontext);
+
+  self->no_connect = no_connect;
+  self->start_hidden = start_hidden;
+
+  return retval;
 }
 
 static void empathy_app_constructed (GObject *object);
@@ -230,7 +502,8 @@ empathy_app_class_init (EmpathyAppClass *klass)
   gobject_class->dispose = empathy_app_dispose;
   gobject_class->finalize = empathy_app_finalize;
 
-  g_app_class->activate = empathy_app_activate;
+  g_app_class->command_line = empathy_app_command_line;
+  g_app_class->local_command_line = empathy_app_local_command_line;
 
   spec = g_param_spec_boolean ("no-connect", "no connect",
       "Don't connect on startup",
@@ -349,32 +622,6 @@ show_version_cb (const char *option_name,
   exit (EXIT_SUCCESS);
 }
 
-static void
-new_incoming_transfer_cb (EmpathyFTFactory *factory,
-    EmpathyFTHandler *handler,
-    GError *error,
-    gpointer user_data)
-{
-  if (error)
-    empathy_ft_manager_display_error (handler, error);
-  else
-    empathy_receive_file_with_file_chooser (handler);
-}
-
-static void
-new_ft_handler_cb (EmpathyFTFactory *factory,
-    EmpathyFTHandler *handler,
-    GError *error,
-    gpointer user_data)
-{
-  if (error)
-    empathy_ft_manager_display_error (handler, error);
-  else
-    empathy_ft_manager_add_handler (handler);
-
-  g_object_unref (handler);
-}
-
 static void
 account_manager_ready_cb (GObject *source_object,
     GAsyncResult *result,
@@ -385,7 +632,7 @@ account_manager_ready_cb (GObject *source_object,
   GError *error = NULL;
   TpConnectionPresenceType presence;
 
-  if (!tp_account_manager_prepare_finish (manager, result, &error))
+  if (!tp_proxy_prepare_finish (manager, result, &error))
     {
       GtkWidget *dialog;
 
@@ -416,7 +663,7 @@ account_manager_ready_cb (GObject *source_object,
           (presence, TP_CONNECTION_PRESENCE_TYPE_OFFLINE)
             <= 0)
       /* if current state is Offline, then put it online */
-      empathy_idle_set_state (self->idle,
+      empathy_presence_manager_set_state (self->presence_mgr,
           TP_CONNECTION_PRESENCE_TYPE_AVAILABLE);
 
   /* Pop up the accounts dialog if we don't have any account */
@@ -425,19 +672,39 @@ account_manager_ready_cb (GObject *source_object,
 }
 
 static void
-account_status_changed_cb (TpAccount *account,
-    guint old_status,
-    guint new_status,
-    guint reason,
-    gchar *dbus_error_name,
-    GHashTable *details,
-    EmpathyChatroom *room)
+account_join_chatrooms (TpAccount *account,
+  EmpathyChatroomManager *chatroom_manager)
 {
-  if (new_status != TP_CONNECTION_STATUS_CONNECTED)
+  TpConnection *conn;
+  GList *chatrooms, *p;
+
+  /* Wait if we are not connected or the TpConnection is not prepared yet */
+  conn = tp_account_get_connection (account);
+  if (conn == NULL)
     return;
 
-  empathy_dispatcher_join_muc (account,
-      empathy_chatroom_get_room (room), TP_USER_ACTION_TIME_NOT_USER_ACTION);
+  chatrooms = empathy_chatroom_manager_get_chatrooms (
+          chatroom_manager, account);
+
+  for (p = chatrooms; p != NULL; p = p->next)
+    {
+      EmpathyChatroom *room = EMPATHY_CHATROOM (p->data);
+
+      if (!empathy_chatroom_get_auto_connect (room))
+        continue;
+
+      empathy_join_muc (account, empathy_chatroom_get_room (room),
+        TP_USER_ACTION_TIME_NOT_USER_ACTION);
+    }
+  g_list_free (chatrooms);
+}
+
+static void
+account_connection_changed_cb (TpAccount *account,
+    GParamSpec *spec,
+    EmpathyChatroomManager *manager)
+{
+  account_join_chatrooms (account, manager);
 }
 
 static void
@@ -450,7 +717,7 @@ account_manager_chatroom_ready_cb (GObject *source_object,
   GList *accounts, *l;
   GError *error = NULL;
 
-  if (!tp_account_manager_prepare_finish (account_manager, result, &error))
+  if (!tp_proxy_prepare_finish (account_manager, result, &error))
     {
       DEBUG ("Failed to prepare account manager: %s", error->message);
       g_error_free (error);
@@ -462,37 +729,14 @@ account_manager_chatroom_ready_cb (GObject *source_object,
   for (l = accounts; l != NULL; l = g_list_next (l))
     {
       TpAccount *account = TP_ACCOUNT (l->data);
-      TpConnection *conn;
-      GList *chatrooms, *p;
 
-      conn = tp_account_get_connection (account);
+      /* Try to join all rooms if we're connected */
+      account_join_chatrooms (account, chatroom_manager);
 
-      chatrooms = empathy_chatroom_manager_get_chatrooms (
-          chatroom_manager, account);
-
-      for (p = chatrooms; p != NULL; p = p->next)
-        {
-          EmpathyChatroom *room = EMPATHY_CHATROOM (p->data);
-
-          if (!empathy_chatroom_get_auto_connect (room))
-            continue;
-
-          if (conn == NULL)
-            {
-              g_signal_connect (G_OBJECT (account), "status-changed",
-                  G_CALLBACK (account_status_changed_cb), room);
-            }
-          else
-            {
-              empathy_dispatcher_join_muc (account,
-                  empathy_chatroom_get_room (room),
-                  TP_USER_ACTION_TIME_NOT_USER_ACTION);
-            }
-        }
-
-      g_list_free (chatrooms);
+      /* And/or join them on (re)connection */
+      tp_g_signal_connect_object (account, "notify::connection",
+        G_CALLBACK (account_connection_changed_cb), chatroom_manager, 0);
     }
-
   g_list_free (accounts);
 }
 
@@ -503,28 +747,15 @@ chatroom_manager_ready_cb (EmpathyChatroomManager *chatroom_manager,
 {
   TpAccountManager *account_manager = user_data;
 
-  tp_account_manager_prepare_async (account_manager, NULL,
+  tp_proxy_prepare_async (account_manager, NULL,
       account_manager_chatroom_ready_cb, chatroom_manager);
 }
 
-static void
-empathy_idle_set_auto_away_cb (GSettings *gsettings,
-                               const gchar *key,
-                               gpointer user_data)
-{
-       EmpathyIdle *idle = user_data;
-
-       empathy_idle_set_auto_away (idle,
-      g_settings_get_boolean (gsettings, key));
-}
-
 static void
 empathy_app_constructed (GObject *object)
 {
   EmpathyApp *self = (EmpathyApp *) object;
-  GError *error = NULL;
   gboolean chatroom_manager_ready;
-  gboolean autoaway;
 
   g_set_application_name (_(PACKAGE_NAME));
 
@@ -540,16 +771,9 @@ empathy_app_constructed (GObject *object)
   notify_init (_(PACKAGE_NAME));
 
   /* Setting up Idle */
-  self->idle = empathy_idle_dup_singleton ();
+  self->presence_mgr = empathy_presence_manager_dup_singleton ();
 
   self->gsettings = g_settings_new (EMPATHY_PREFS_SCHEMA);
-  autoaway = g_settings_get_boolean (self->gsettings, EMPATHY_PREFS_AUTOAWAY);
-
-  g_signal_connect (self->gsettings,
-      "changed::" EMPATHY_PREFS_AUTOAWAY,
-      G_CALLBACK (empathy_idle_set_auto_away_cb), self->idle);
-
-  empathy_idle_set_auto_away (self->idle, autoaway);
 
   /* Setting up Connectivity */
   self->connectivity = empathy_connectivity_dup_singleton ();
@@ -561,21 +785,11 @@ empathy_app_constructed (GObject *object)
 
   /* account management */
   self->account_manager = tp_account_manager_dup ();
-  tp_account_manager_prepare_async (self->account_manager, NULL,
+  tp_proxy_prepare_async (self->account_manager, NULL,
       account_manager_ready_cb, self);
 
-  /* The EmpathyDispatcher doesn't dispatch anything any more but we have to
-   * keep it around as we still use it to request channels */
-  self->dispatcher = empathy_dispatcher_dup_singleton ();
-
   migrate_config_to_xdg_dir ();
 
-  /* Setting up UI */
-  self->window = empathy_main_window_dup ();
-  gtk_widget_show (self->window);
-  self->icon = empathy_status_icon_new (GTK_WINDOW (self->window),
-      self->start_hidden);
-
   /* Logging */
   self->log_manager = tpl_log_manager_dup_singleton ();
 
@@ -593,46 +807,44 @@ empathy_app_constructed (GObject *object)
           self->account_manager);
     }
 
-  /* Create the FT factory */
-  self->ft_factory = empathy_ft_factory_dup_singleton ();
-  g_signal_connect (self->ft_factory, "new-ft-handler",
-      G_CALLBACK (new_ft_handler_cb), NULL);
-  g_signal_connect (self->ft_factory, "new-incoming-transfer",
-      G_CALLBACK (new_incoming_transfer_cb), NULL);
-
-  if (!empathy_ft_factory_register (self->ft_factory, &error))
-    {
-      g_warning ("Failed to register FileTransfer handler: %s", error->message);
-      g_error_free (error);
-    }
-
   /* Location mananger */
 #ifdef HAVE_GEOCLUE
   self->location_manager = empathy_location_manager_dup_singleton ();
 #endif
+
+  self->conn_aggregator = empathy_connection_aggregator_dup_singleton ();
+
+  self->activated = FALSE;
+  self->ft_factory = NULL;
+  self->window = NULL;
+}
+
+static void
+add_empathy_features (void)
+{
+  /* Add 'empathy' specific feature before doing any preparation */
+  EmpathyClientFactory *factory;
+
+  factory = empathy_client_factory_dup ();
+
+  tp_simple_client_factory_add_connection_features_varargs (
+      TP_SIMPLE_CLIENT_FACTORY (factory),
+      /* empathy_connection_aggregator_get_all_groups(), used by
+       * EmpathyGroupsWidget relies on it */
+      TP_CONNECTION_FEATURE_CONTACT_GROUPS,
+      /* empathy_connection_aggregator_dup_all_contacts(), used by
+       * EmpathyEventManager relies on it */
+      TP_CONNECTION_FEATURE_CONTACT_LIST,
+      NULL);
+
+  g_object_unref (factory);
 }
 
 int
 main (int argc, char *argv[])
 {
   EmpathyApp *app;
-  GError *error = NULL;
-  GOptionContext *optcontext;
-  gboolean no_connect = FALSE, start_hidden = FALSE;
-  GOptionEntry options[] = {
-      { "no-connect", 'n',
-        0, G_OPTION_ARG_NONE, &no_connect,
-        N_("Don't connect on startup"),
-        NULL },
-      { "start-hidden", 'h',
-        0, G_OPTION_ARG_NONE, &start_hidden,
-        N_("Don't display the contact list or any other dialogs on startup"),
-        NULL },
-      { "version", 'v',
-        G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, show_version_cb,
-        NULL, NULL },
-      { NULL }
-  };
+  gint retval;
 
   g_thread_init (NULL);
   g_type_init ();
@@ -641,32 +853,25 @@ main (int argc, char *argv[])
   gtk_clutter_init (&argc, &argv);
 #endif
 
+  g_type_init ();
+  tpy_cli_init ();
   empathy_init ();
-
-  optcontext = g_option_context_new (N_("- Empathy IM Client"));
-  g_option_context_add_group (optcontext, gtk_get_option_group (TRUE));
-  g_option_context_add_main_entries (optcontext, options, GETTEXT_PACKAGE);
-
-  if (!g_option_context_parse (optcontext, &argc, &argv, &error)) {
-    g_print ("%s\nRun '%s --help' to see a full list of available command line options.\n",
-        error->message, argv[0]);
-    g_warning ("Error in empathy init: %s", error->message);
-    return EXIT_FAILURE;
-  }
-
-  g_option_context_free (optcontext);
-
+  gtk_init (&argc, &argv);
   empathy_gtk_init ();
 
+  add_empathy_features ();
+
   app = g_object_new (EMPATHY_TYPE_APP,
       "application-id", EMPATHY_DBUS_NAME,
+      "flags", G_APPLICATION_HANDLES_COMMAND_LINE,
       NULL);
 
-  g_application_run (G_APPLICATION (app), argc, argv);
+  retval = g_application_run (G_APPLICATION (app), argc, argv);
 
   notify_uninit ();
   xmlCleanupParser ();
 
   g_object_unref (app);
-  return EXIT_SUCCESS;
+
+  return retval;
 }