[ekiga/ds-gtk-application: 3/4] Ekiga: Started the GtkApplication port.



commit 6c1d8df0554dde461ab6a3314fb12e3af3ee6eaf
Author: Damien Sandras <dsandras beip be>
Date:   Sun Feb 2 17:26:05 2014 +0100

    Ekiga: Started the GtkApplication port.
    
    The GtkFrontend class was removed. The old file now contains a new
    GtkApplication (GmApplication) GObject responsible of the whole
    application.
    
    Currently, the responsability is limited to creating Ekiga application
    windows and displaying the toplevel menu in GNOME Shell. (Other menus
    have not been ported to the new model, so you might be confronted to
    uncomplete menus if you are not using GNOME Shell at all. Please be
    patient!
    
    The new GmApplication holds a shared_ptr to the Ekiga::ServiceCore.
    
    As part of the move, the various windows API has been reorganized to:
     - Only take the GmApplication as argument
     - Register as a GtkApplicationWindow of the main GtkApplication
    
    Some code with FIXME has also been moved when it had to be moved.
    
    Most windows are now following the new "create" and "destroy" model
    instead of being kept in memory. The only window where it was not
    possible is the chat window. That's for later.
    
    The global gmcallbacks have also been removed and integrated into
    GtkApplication.

 lib/Makefile.am                                    |    8 -
 lib/engine/engine.cpp                              |    6 -
 lib/engine/gui/gtk-frontend/accounts-window.cpp    |   23 +-
 lib/engine/gui/gtk-frontend/accounts-window.h      |    9 +-
 lib/engine/gui/gtk-frontend/addressbook-window.cpp |   46 +-
 lib/engine/gui/gtk-frontend/addressbook-window.h   |    4 +-
 lib/engine/gui/gtk-frontend/assistant-window.cpp   |   12 +-
 lib/engine/gui/gtk-frontend/assistant-window.h     |    2 +-
 lib/engine/gui/gtk-frontend/call-window.cpp        |   20 +-
 lib/engine/gui/gtk-frontend/call-window.h          |    9 +-
 lib/engine/gui/gtk-frontend/chat-window.cpp        |   59 ++-
 lib/engine/gui/gtk-frontend/chat-window.h          |    4 +-
 lib/engine/gui/gtk-frontend/gtk-frontend.cpp       |  643 +++++++++++++++-----
 lib/engine/gui/gtk-frontend/gtk-frontend.h         |   84 ++-
 lib/engine/gui/gtk-frontend/main_window.cpp        |  263 +-------
 lib/engine/gui/gtk-frontend/main_window.h          |    6 +-
 lib/engine/gui/gtk-frontend/preferences-window.cpp |   21 +-
 lib/engine/gui/gtk-frontend/preferences-window.h   |    6 +-
 lib/engine/gui/gtk-frontend/statusicon.cpp         |   71 ++-
 lib/engine/gui/gtk-frontend/statusicon.h           |    4 +-
 lib/gui/gmcallbacks.c                              |  219 -------
 lib/gui/gmcallbacks.h                              |   74 ---
 src/dbus-helper/dbus.cpp                           |   26 +-
 src/dbus-helper/dbus.h                             |    4 +-
 src/main.cpp                                       |   37 +-
 25 files changed, 791 insertions(+), 869 deletions(-)
---
diff --git a/lib/Makefile.am b/lib/Makefile.am
index cc64ba3..afa6dd3 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -123,8 +123,6 @@ libekiga_la_SOURCES += \
        gui/gm-smileys.c \
        gui/gmwindow.c \
        gui/gmwindow.h \
-       gui/gmcallbacks.c \
-       gui/gmcallbacks.h \
        gui/gmentrydialog.c \
        gui/gmentrydialog.h \
        gui/gmmenuaddon.c \
@@ -152,12 +150,6 @@ libekiga_la_SOURCES += \
        gui/gm-smiley-chooser-button.c \
        gui/gm-smiley-chooser-button.h
 
-if !WIN32
-libekiga_la_SOURCES += \
-       gui/xwindow.cpp \
-       gui/xwindow.h
-endif
-
 ##
 # Sources of the main engine code
 ##
diff --git a/lib/engine/engine.cpp b/lib/engine/engine.cpp
index 4a03e70..4c61ecf 100644
--- a/lib/engine/engine.cpp
+++ b/lib/engine/engine.cpp
@@ -164,14 +164,8 @@ engine_init (Ekiga::ServiceCorePtr service_core,
 
   kickstart.kick (*service_core, &argc, &argv);
 
-  // FIXME: can't we have a single function for the whole gui?
   gtk_core_init (*service_core, &argc, &argv);
 
-  if (!gtk_frontend_init (*service_core, &argc, &argv)) {
-
-    return;
-  }
-
   kickstart.kick (*service_core, &argc, &argv);
 
   /* FIXME: everything that follows except the debug output shouldn't
diff --git a/lib/engine/gui/gtk-frontend/accounts-window.cpp b/lib/engine/gui/gtk-frontend/accounts-window.cpp
index a31833d..d48444c 100644
--- a/lib/engine/gui/gtk-frontend/accounts-window.cpp
+++ b/lib/engine/gui/gtk-frontend/accounts-window.cpp
@@ -43,8 +43,6 @@
 #include "bank.h"
 #include "opal-bank.h"
 
-#include "gmcallbacks.h"
-
 #include "services.h"
 #include "menu-builder-tools.h"
 #include "menu-builder-gtk.h"
@@ -522,12 +520,12 @@ accounts_window_class_init (AccountsWindowClass *klass)
 
 /* Public API */
 GtkWidget *
-accounts_window_new (boost::shared_ptr<Ekiga::AccountCore> account_core,
-                    boost::shared_ptr<Ekiga::PersonalDetails> details,
-                    const char* key)
+accounts_window_new (GmApplication *app)
 {
   AccountsWindow *self = NULL;
 
+  g_return_val_if_fail (GM_IS_APPLICATION (app), NULL);
+
   boost::signals2::connection conn;
 
   GtkWidget *vbox = NULL;
@@ -561,12 +559,18 @@ accounts_window_new (boost::shared_ptr<Ekiga::AccountCore> account_core,
     _("Status")
   };
 
+  Ekiga::ServiceCorePtr core = gm_application_get_core (app);
+
   /* The window */
-  self = (AccountsWindow *) g_object_new (ACCOUNTS_WINDOW_TYPE, "key", key, NULL);
+  self = (AccountsWindow *) g_object_new (ACCOUNTS_WINDOW_TYPE,
+                                          "application", GTK_APPLICATION (app),
+                                          "key", USER_INTERFACE ".accounts-window",
+                                          "hide_on_delete", false,
+                                          "hide_on_esc", false, NULL);
 
   self->priv = new AccountsWindowPrivate;
-  self->priv->details = details;
-  self->priv->account_core = account_core;
+  self->priv->details = core->get<Ekiga::PersonalDetails> ("personal-details");
+  self->priv->account_core = core->get<Ekiga::AccountCore> ("account-core");
 
   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
   gtk_window_set_title (GTK_WINDOW (self), _("Accounts"));
@@ -589,7 +593,8 @@ accounts_window_new (boost::shared_ptr<Ekiga::AccountCore> account_core,
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
   item = gtk_image_menu_item_new_from_stock (GTK_STOCK_HELP, NULL);
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-  g_signal_connect (item, "activate", G_CALLBACK (help_callback), NULL);
+  //g_signal_connect (item, "activate", G_CALLBACK (help_callback), NULL);
+  std::cout << "FIXME" << std::endl << std::flush;
 
   /* The accounts list store */
   list_store = gtk_list_store_new (COLUMN_ACCOUNT_NUMBER,
diff --git a/lib/engine/gui/gtk-frontend/accounts-window.h b/lib/engine/gui/gtk-frontend/accounts-window.h
index 13afbb7..415d120 100644
--- a/lib/engine/gui/gtk-frontend/accounts-window.h
+++ b/lib/engine/gui/gtk-frontend/accounts-window.h
@@ -42,11 +42,8 @@
 #include <glib.h>
 #include <gtk/gtk.h>
 
-#include "services.h"
-
 #include "gmwindow.h"
-#include "account-core.h"
-#include "personal-details.h"
+#include "gtk-frontend.h"
 
 typedef struct _AccountsWindow AccountsWindow;
 typedef struct _AccountsWindowPrivate AccountsWindowPrivate;
@@ -87,8 +84,6 @@ GType accounts_window_get_type ();
  * BEHAVIOR     : Builds the GMAccounts window GObject.
  * PRE          : /
  */
-GtkWidget* accounts_window_new (boost::shared_ptr<Ekiga::AccountCore> account_core,
-                               boost::shared_ptr<Ekiga::PersonalDetails> details,
-                               const char* key);
+GtkWidget* accounts_window_new (GmApplication *app);
 
 #endif
diff --git a/lib/engine/gui/gtk-frontend/addressbook-window.cpp 
b/lib/engine/gui/gtk-frontend/addressbook-window.cpp
index cc587a8..ea6f365 100644
--- a/lib/engine/gui/gtk-frontend/addressbook-window.cpp
+++ b/lib/engine/gui/gtk-frontend/addressbook-window.cpp
@@ -34,14 +34,16 @@
 
 #include <glib/gi18n.h>
 
+#include "ekiga-settings.h"
+
 #include "addressbook-window.h"
 #include "book-view-gtk.h"
 #include "menu-builder-gtk.h"
 #include "form-dialog-gtk.h"
 #include "scoped-connections.h"
 
-/* 
- * The Search Window 
+/*
+ * The Search Window
  */
 struct _AddressBookWindowPrivate
 {
@@ -597,11 +599,10 @@ addressbook_window_class_init (AddressBookWindowClass *klass)
 }
 
 /*
- * Public API 
+ * Public API
  */
 GtkWidget *
-addressbook_window_new (boost::shared_ptr<Ekiga::ContactCore> core,
-                       const char* key)
+addressbook_window_new (GmApplication *app)
 {
   AddressBookWindow *self = NULL;
 
@@ -616,8 +617,17 @@ addressbook_window_new (boost::shared_ptr<Ekiga::ContactCore> core,
   GtkTreeViewColumn *column = NULL;
   GtkTreeStore *store = NULL;
 
-  self = (AddressBookWindow *) g_object_new (ADDRESSBOOK_WINDOW_TYPE, "key", key, NULL);
-  self->priv = new AddressBookWindowPrivate (core);
+  Ekiga::ServiceCorePtr core = gm_application_get_core (app);
+
+  self = (AddressBookWindow *) g_object_new (ADDRESSBOOK_WINDOW_TYPE,
+                                             "application", GTK_APPLICATION (app),
+                                             "key", USER_INTERFACE ".addressbook-window",
+                                             "hide_on_delete", FALSE,
+                                             "hide_on_esc", FALSE,
+                                             NULL);
+  boost::shared_ptr<Ekiga::ContactCore> contact_core =
+    core->get<Ekiga::ContactCore> ("contact-core");
+  self->priv = new AddressBookWindowPrivate (contact_core);
 
   gtk_window_set_title (GTK_WINDOW (self), _("Address Book"));
   gtk_window_set_position (GTK_WINDOW (self), GTK_WIN_POS_CENTER);
@@ -639,8 +649,8 @@ addressbook_window_new (boost::shared_ptr<Ekiga::ContactCore> core,
   gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar),
                          self->priv->menu_item_core);
   g_object_ref (self->priv->menu_item_core);
-  conn = core->updated.connect (boost::bind (&on_core_updated,
-                                           (gpointer) self));
+  conn = contact_core->updated.connect (boost::bind (&on_core_updated,
+                                                     (gpointer) self));
   self->priv->connections.add (conn);
   on_core_updated (self); // This will add static and dynamic actions
 
@@ -714,24 +724,24 @@ addressbook_window_new (boost::shared_ptr<Ekiga::ContactCore> core,
                     G_CALLBACK (on_notebook_realize), self);
   gtk_paned_pack2 (GTK_PANED (hpaned), self->priv->notebook, TRUE, TRUE);
 
-  conn = core->source_added.connect (boost::bind (&on_source_added, _1, (gpointer) self));
+  conn = contact_core->source_added.connect (boost::bind (&on_source_added, _1, (gpointer) self));
   self->priv->connections.add (conn);
 
-  conn = core->book_updated.connect (boost::bind (&on_book_updated, _1, _2,
-                                                (gpointer) self));
+  conn = contact_core->book_updated.connect (boost::bind (&on_book_updated, _1, _2,
+                                                          (gpointer) self));
   self->priv->connections.add (conn);
-  conn = core->book_added.connect (boost::bind (&on_book_added, _1, _2,
-                                              (gpointer) self));
+  conn = contact_core->book_added.connect (boost::bind (&on_book_added, _1, _2,
+                                                        (gpointer) self));
   self->priv->connections.add (conn);
   conn =
-    core->book_removed.connect (boost::bind (&on_book_removed, _1, _2,
-                                           (gpointer) self));
+    contact_core->book_removed.connect (boost::bind (&on_book_removed, _1, _2,
+                                                     (gpointer) self));
   self->priv->connections.add (conn);
 
-  conn = core->questions.connect (boost::bind (&on_handle_questions, _1, (gpointer) self));
+  conn = contact_core->questions.connect (boost::bind (&on_handle_questions, _1, (gpointer) self));
   self->priv->connections.add (conn);
 
-  core->visit_sources (boost::bind (on_visit_sources, _1, (gpointer) self));
+  contact_core->visit_sources (boost::bind (on_visit_sources, _1, (gpointer) self));
 
   gtk_widget_show_all (vbox);
 
diff --git a/lib/engine/gui/gtk-frontend/addressbook-window.h 
b/lib/engine/gui/gtk-frontend/addressbook-window.h
index 6e81fb9..6ea9e0c 100644
--- a/lib/engine/gui/gtk-frontend/addressbook-window.h
+++ b/lib/engine/gui/gtk-frontend/addressbook-window.h
@@ -42,6 +42,7 @@
 #include "contact-core.h"
 
 #include "gmwindow.h"
+#include "gtk-frontend.h"
 
 
 typedef struct _AddressBookWindow AddressBookWindow;
@@ -78,6 +79,5 @@ GType addressbook_window_get_type ();
 
 
 /* public api */
-GtkWidget* addressbook_window_new (boost::shared_ptr<Ekiga::ContactCore> core,
-                                  const char* key);
+GtkWidget* addressbook_window_new (GmApplication *app);
 #endif
diff --git a/lib/engine/gui/gtk-frontend/assistant-window.cpp 
b/lib/engine/gui/gtk-frontend/assistant-window.cpp
index d525112..be84da1 100644
--- a/lib/engine/gui/gtk-frontend/assistant-window.cpp
+++ b/lib/engine/gui/gtk-frontend/assistant-window.cpp
@@ -56,7 +56,6 @@ G_DEFINE_TYPE (AssistantWindow, assistant_window, GTK_TYPE_ASSISTANT);
 
 struct _AssistantWindowPrivate
 {
-  Ekiga::ServiceCore* service_core; // FIXME: wrong memory management
   boost::shared_ptr<Opal::Bank> bank;
   GdkPixbuf *icon;
 
@@ -813,12 +812,7 @@ assistant_window_apply (GtkAssistant *gtkassistant)
 static void
 assistant_window_close (GtkAssistant *gtkassistant)
 {
-  AssistantWindow *assistant = ASSISTANT_WINDOW (gtkassistant);
-
   gtk_widget_destroy (GTK_WIDGET (gtkassistant));
-  boost::shared_ptr<GtkFrontend> gtk_frontend
-    = assistant->priv->service_core->get<GtkFrontend>("gtk-frontend");
-  gtk_widget_show (GTK_WIDGET (gtk_frontend->get_main_window ()));
 }
 
 
@@ -864,20 +858,18 @@ assistant_window_key_press_cb (GtkWidget *widget,
 
 
 GtkWidget *
-assistant_window_new (Ekiga::ServiceCore& service_core)
+assistant_window_new (Ekiga::ServiceCorePtr service_core)
 {
   AssistantWindow *assistant;
 
   assistant = ASSISTANT_WINDOW (g_object_new (ASSISTANT_WINDOW_TYPE, NULL));
 
-  assistant->priv->service_core = &service_core;
-
   /* FIXME: move this into the caller */
   g_signal_connect (assistant, "key-press-event",
                     G_CALLBACK (assistant_window_key_press_cb), NULL);
 
   boost::signals2::connection conn;
-  assistant->priv->bank = service_core.get<Opal::Bank> ("opal-account-store");
+  assistant->priv->bank = service_core->get<Opal::Bank> ("opal-account-store");
 
   return GTK_WIDGET (assistant);
 }
diff --git a/lib/engine/gui/gtk-frontend/assistant-window.h b/lib/engine/gui/gtk-frontend/assistant-window.h
index 1ff8bbb..567bbcc 100644
--- a/lib/engine/gui/gtk-frontend/assistant-window.h
+++ b/lib/engine/gui/gtk-frontend/assistant-window.h
@@ -70,7 +70,7 @@ struct _AssistantWindow {
 typedef GtkAssistantClass AssistantWindowClass;
 
 GType assistant_window_get_type   ();
-GtkWidget* assistant_window_new (Ekiga::ServiceCore& core);
+GtkWidget* assistant_window_new (Ekiga::ServiceCorePtr core);
 
 G_END_DECLS
 
diff --git a/lib/engine/gui/gtk-frontend/call-window.cpp b/lib/engine/gui/gtk-frontend/call-window.cpp
index 649ca26..e03697a 100644
--- a/lib/engine/gui/gtk-frontend/call-window.cpp
+++ b/lib/engine/gui/gtk-frontend/call-window.cpp
@@ -2356,21 +2356,25 @@ ekiga_call_window_class_init (EkigaCallWindowClass *klass)
 }
 
 GtkWidget *
-call_window_new (Ekiga::ServiceCore & core)
+call_window_new (GmApplication *app)
 {
   EkigaCallWindow *cw;
 
+  g_return_val_if_fail (GM_IS_APPLICATION (app), NULL);
+
   cw = EKIGA_CALL_WINDOW (g_object_new (EKIGA_TYPE_CALL_WINDOW,
+                                        "application", GTK_APPLICATION (app),
                                         "key", USER_INTERFACE ".call-window",
                                         "hide_on_delete", false,
                                         "hide_on_esc", false, NULL));
-
-  cw->priv->libnotify = core.get ("libnotify");
-  cw->priv->videoinput_core = core.get<Ekiga::VideoInputCore> ("videoinput-core");
-  cw->priv->videooutput_core = core.get<Ekiga::VideoOutputCore> ("videooutput-core");
-  cw->priv->audioinput_core = core.get<Ekiga::AudioInputCore> ("audioinput-core");
-  cw->priv->audiooutput_core = core.get<Ekiga::AudioOutputCore> ("audiooutput-core");
-  cw->priv->call_core = core.get<Ekiga::CallCore> ("call-core");
+  Ekiga::ServiceCorePtr core = gm_application_get_core (app);
+
+  cw->priv->libnotify = core->get ("libnotify");
+  cw->priv->videoinput_core = core->get<Ekiga::VideoInputCore> ("videoinput-core");
+  cw->priv->videooutput_core = core->get<Ekiga::VideoOutputCore> ("videooutput-core");
+  cw->priv->audioinput_core = core->get<Ekiga::AudioInputCore> ("audioinput-core");
+  cw->priv->audiooutput_core = core->get<Ekiga::AudioOutputCore> ("audiooutput-core");
+  cw->priv->call_core = core->get<Ekiga::CallCore> ("call-core");
 
   ekiga_call_window_connect_engine_signals (cw);
 
diff --git a/lib/engine/gui/gtk-frontend/call-window.h b/lib/engine/gui/gtk-frontend/call-window.h
index 3055536..76ed411 100644
--- a/lib/engine/gui/gtk-frontend/call-window.h
+++ b/lib/engine/gui/gtk-frontend/call-window.h
@@ -39,8 +39,8 @@
 #ifndef __CALL_WINDOW_H__
 #define __CALL_WINDOW_H__
 
-#include "services.h"
 #include "gmwindow.h"
+#include "gtk-frontend.h"
 
 G_BEGIN_DECLS
 
@@ -62,11 +62,8 @@ typedef GmWindowClass EkigaCallWindowClass;
 
 GType        ekiga_call_window_get_type   ();
 
-/* DESCRIPTION  :  /
- * BEHAVIOR     :  Builds the call window and adds the popup to the image.
- * PRE          :  Accels.
- */
-GtkWidget *call_window_new (Ekiga::ServiceCore & core);
+
+GtkWidget *call_window_new (GmApplication *app);
 
 G_END_DECLS
 #endif
diff --git a/lib/engine/gui/gtk-frontend/chat-window.cpp b/lib/engine/gui/gtk-frontend/chat-window.cpp
index ad71225..9d56063 100644
--- a/lib/engine/gui/gtk-frontend/chat-window.cpp
+++ b/lib/engine/gui/gtk-frontend/chat-window.cpp
@@ -39,7 +39,9 @@
 #include <glib/gi18n.h>
 
 #include "chat-core.h"
+#include "audiooutput-core.h"
 #include "notification-core.h"
+#include "ekiga-settings.h"
 
 #include "form-dialog-gtk.h"
 #include "scoped-connections.h"
@@ -51,9 +53,13 @@
 struct _ChatWindowPrivate
 {
   boost::shared_ptr<Ekiga::NotificationCore> notification_core;
+  boost::shared_ptr<Ekiga::AudioOutputCore> audiooutput_core;
   Ekiga::scoped_connections connections;
 
   GtkWidget* notebook;
+
+  /* GSettings */
+  boost::shared_ptr<Ekiga::Settings> sound_events_settings;
 };
 
 enum {
@@ -104,6 +110,15 @@ static void on_some_chat_user_requested (ChatWindow* self,
 
 static void show_chat_window_cb (ChatWindow *self);
 
+/* DESCRIPTION  :  This callback is called when the chat window alerts about
+ *                 unread messages
+ * BEHAVIOR     :  Plays a sound (if enabled)
+ * PRE          :  /
+ */
+static void on_chat_unread_alert (GtkWidget*,
+                                 gpointer);
+
+
 /* helper (implementation) */
 
 static void
@@ -390,9 +405,24 @@ show_chat_window_cb (ChatWindow *self)
   gtk_window_present (GTK_WINDOW (self));
 }
 
+static void
+on_chat_unread_alert (G_GNUC_UNUSED GtkWidget* widget,
+                     gpointer data)
+{
+  ChatWindow *self = CHAT_WINDOW (data);
+
+  g_return_if_fail (self != NULL);
+  if (!self->priv->sound_events_settings->get_bool ("enable-new-message-sound"))
+    return;
+
+  std::string file_name_string = self->priv->sound_events_settings->get_string ("new-message-sound");
+
+  if (!file_name_string.empty ())
+    self->priv->audiooutput_core->play_file (file_name_string);
+}
 
-/* GObject code */
 
+/* GObject code */
 static void
 chat_window_finalize (GObject* obj)
 {
@@ -438,26 +468,33 @@ chat_window_init (ChatWindow* self)
 {
   /* we can't do much here since we get the Chat as reference... */
   gtk_window_set_title (GTK_WINDOW (self), _("Chat Window"));
+
+  self->priv = new ChatWindowPrivate;
 }
 
-/* public api */
 
+/* Public API */
 GtkWidget*
-chat_window_new (Ekiga::ServiceCore& core,
-                const char* key)
+chat_window_new (GmApplication *app)
 {
   ChatWindow* self = NULL;
   GtkAccelGroup *accel = NULL;
 
+  g_return_val_if_fail (GM_IS_APPLICATION (app), NULL);
+
+  Ekiga::ServiceCorePtr core = gm_application_get_core (app);
+
   self = (ChatWindow*)g_object_new (CHAT_WINDOW_TYPE,
-                                   "key", key,
-                                    "hide_on_esc", FALSE,
+                                    "application", GTK_APPLICATION (app),
+                                    "key", USER_INTERFACE ".chat-window",
                                    NULL);
 
-  self->priv = new ChatWindowPrivate;
-
+  self->priv->sound_events_settings =
+    boost::shared_ptr<Ekiga::Settings> (new Ekiga::Settings (SOUND_EVENTS_SCHEMA));
   self->priv->notification_core =
-    core.get<Ekiga::NotificationCore>("notification-core");
+    core->get<Ekiga::NotificationCore>("notification-core");
+  self->priv->audiooutput_core =
+    core->get<Ekiga::AudioOutputCore>("audiooutput-core");
 
   self->priv->notebook = gtk_notebook_new ();
   gtk_container_add (GTK_CONTAINER (self), self->priv->notebook);
@@ -473,9 +510,11 @@ chat_window_new (Ekiga::ServiceCore& core,
                    G_CALLBACK (on_focus_in_event), self);
   g_signal_connect (self->priv->notebook, "switch-page",
                    G_CALLBACK (on_switch_page), self);
+  g_signal_connect (self, "unread-alert",
+                    G_CALLBACK (on_chat_unread_alert), self);
 
   boost::shared_ptr<Ekiga::ChatCore> chat_core =
-    core.get<Ekiga::ChatCore> ("chat-core");
+    core->get<Ekiga::ChatCore> ("chat-core");
   self->priv->connections.add (chat_core->dialect_added.connect (boost::bind (&on_dialect_added, self, _1)));
   self->priv->connections.add (chat_core->questions.connect (boost::bind (&on_handle_questions, self, _1)));
   chat_core->visit_dialects (boost::bind (&on_dialect_added, self, _1));
diff --git a/lib/engine/gui/gtk-frontend/chat-window.h b/lib/engine/gui/gtk-frontend/chat-window.h
index 1d7c3e1..82eb2b6 100644
--- a/lib/engine/gui/gtk-frontend/chat-window.h
+++ b/lib/engine/gui/gtk-frontend/chat-window.h
@@ -41,6 +41,7 @@
 
 #include "gmwindow.h"
 #include "services.h"
+#include "gtk-frontend.h"
 
 G_BEGIN_DECLS
 
@@ -69,8 +70,7 @@ struct _ChatWindowClass
 
 /* Public API */
 
-GtkWidget* chat_window_new (Ekiga::ServiceCore& core,
-                           const char* key);
+GtkWidget* chat_window_new (GmApplication *app);
 
 /* GObject's boilerplate */
 
diff --git a/lib/engine/gui/gtk-frontend/gtk-frontend.cpp b/lib/engine/gui/gtk-frontend/gtk-frontend.cpp
index 283573b..c429347 100644
--- a/lib/engine/gui/gtk-frontend/gtk-frontend.cpp
+++ b/lib/engine/gui/gtk-frontend/gtk-frontend.cpp
@@ -1,6 +1,6 @@
 
 /* Ekiga -- A VoIP and Video-Conferencing application
- * Copyright (C) 2000-2009 Damien Sandras <dsandras seconix com>
+ * Copyright (C) 2000-2014 Damien Sandras <dsandras seconix com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,10 +29,9 @@
 /*
  *                         gtk-frontend.cpp  -  description
  *                         ------------------------------------------
- *   begin                : written in 2007 by Julien Puydt
- *   copyright            : (c) 2007 by Julien Puydt
- *   description          : code to hook a gtk+ user interface to
- *                          the main program
+ *   begin                : written in 2014 by Damien Sandras
+ *   copyright            : (c) 2014 by Damien Sandras
+ *   description          : main Ekiga GtkApplication
  *
  */
 
@@ -70,214 +69,562 @@
 
 #include "gmwindow.h"
 
+#ifdef WIN32
+#include "platform/winpaths.h"
+#include <windows.h>
+#include <shellapi.h>
+#define WIN32_HELP_DIR "help"
+#define WIN32_HELP_FILE "index.html"
+#endif
+
+#ifdef HAVE_DBUS
+#include "../../../../src/dbus-helper/dbus.h"
+#endif
+
+
+#include <glib/gi18n.h>
+
+/*
+ * The GmApplication
+ */
+struct _GmApplicationPrivate
+{
+  Ekiga::ServiceCorePtr core;
+
+  GtkWidget *main_window;
+  GtkWidget *chat_window;
+
+  EkigaDBusComponent *dbus_component;
+};
+
+G_DEFINE_TYPE (GmApplication, gm_application, GTK_TYPE_APPLICATION);
+
+
 /* Private helpers */
+static void
+quit_activated (G_GNUC_UNUSED GSimpleAction *action,
+                G_GNUC_UNUSED GVariant *parameter,
+                gpointer app)
+{
+  g_application_quit (G_APPLICATION (app));
+}
+
 
-// when the status icon is clicked, we want to either show or hide the main window
 static void
-on_status_icon_clicked (G_GNUC_UNUSED GtkWidget* widget,
-                        gpointer data)
+about_activated (G_GNUC_UNUSED GSimpleAction *action,
+                 G_GNUC_UNUSED GVariant *parameter,
+                 gpointer app)
 {
-  GtkWidget *window = GTK_WIDGET (((GtkFrontend*)data)->get_main_window ());
+  gm_application_show_about (GM_APPLICATION (app));
+}
 
-  if (!gtk_widget_get_visible (window)
-      || (gdk_window_get_state (GDK_WINDOW (gtk_widget_get_window (window))) & GDK_WINDOW_STATE_ICONIFIED)) {
-    gtk_widget_show (window);
-  }
-  else {
 
-    if (gtk_window_has_toplevel_focus (GTK_WINDOW (window)))
-      gtk_widget_hide (window);
-    else
-      gtk_window_present (GTK_WINDOW (window));
+static void
+help_activated (G_GNUC_UNUSED GSimpleAction *action,
+                G_GNUC_UNUSED GVariant *parameter,
+                gpointer app)
+{
+  gm_application_show_help (GM_APPLICATION (app), NULL);
+}
+
+
+static void
+window_activated (GSimpleAction *action,
+                  G_GNUC_UNUSED GVariant *parameter,
+                  gpointer app)
+{
+  GmApplication *self = GM_APPLICATION (app);
+  GtkWindow *window = NULL;
+  GmWindow *parent = NULL;
+
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+
+  boost::shared_ptr<Ekiga::AudioInputCore> audio_input_core =
+    self->priv->core->get<Ekiga::AudioInputCore> ("audioinput-core");
+  boost::shared_ptr<Ekiga::AudioOutputCore> audio_output_core =
+    self->priv->core->get<Ekiga::AudioOutputCore> ("audiooutput-core");
+  boost::shared_ptr<Ekiga::VideoInputCore> video_input_core =
+    self->priv->core->get<Ekiga::VideoInputCore> ("videoinput-core");
+  boost::shared_ptr<Ekiga::ContactCore> contact_core =
+    self->priv->core->get<Ekiga::ContactCore> ("contact-core");
+
+  parent = GM_WINDOW (gtk_application_get_active_window (GTK_APPLICATION (self)));
+
+  if (!g_strcmp0 (g_action_get_name (G_ACTION (action)), "preferences"))
+    gm_application_show_preferences_window (self);
+
+  else if (!g_strcmp0 (g_action_get_name (G_ACTION (action)), "addressbook"))
+    gm_application_show_addressbook_window (self);
+
+  else if (!g_strcmp0 (g_action_get_name (G_ACTION (action)), "accounts"))
+    gm_application_show_accounts_window (self);
+
+  else if (!g_strcmp0 (g_action_get_name (G_ACTION (action)), "assistant")) {
+
+    window = GTK_WINDOW (assistant_window_new (self->priv->core));
+    gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (parent));
+    gtk_window_present (window);
   }
 }
 
-/* Public api */
+static GActionEntry app_entries[] =
+{
+    { "preferences", window_activated, NULL, NULL, NULL, 0 },
+    { "assistant", window_activated, NULL, NULL, NULL, 0 },
+    { "addressbook", window_activated, NULL, NULL, NULL, 0 },
+    { "accounts", window_activated, NULL, NULL, NULL, 0 },
+    { "help", help_activated, NULL, NULL, NULL, 0 },
+    { "about", about_activated, NULL, NULL, NULL, 0 },
+    { "quit", quit_activated, NULL, NULL, NULL, 0 }
+};
+
 
-bool
-gtk_frontend_init (Ekiga::ServiceCore &core,
-                  int * /*argc*/,
-                  char ** /*argv*/[])
+/* Public api */
+void
+ekiga_main (Ekiga::ServiceCorePtr core,
+            int argc,
+            char **argv)
 {
-  bool result = false;
-
-  boost::shared_ptr<Ekiga::PresenceCore> presence_core = core.get<Ekiga::PresenceCore> ("presence-core");
-  boost::shared_ptr<Ekiga::ContactCore> contact_core = core.get<Ekiga::ContactCore> ("contact-core");
-  boost::shared_ptr<Ekiga::ChatCore> chat_core = core.get<Ekiga::ChatCore> ("chat-core");
-  boost::shared_ptr<History::Source> history_source = core.get<History::Source> ("call-history-store");
-  boost::shared_ptr<Opal::Bank> opal_bank = core.get<Opal::Bank> ("opal-account-store");
-  boost::shared_ptr<Ekiga::Trigger> local_cluster_trigger = core.get<Ekiga::Trigger> ("local-cluster");
-  boost::shared_ptr<Ekiga::PersonalDetails> details = core.get<Ekiga::PersonalDetails> ("personal-details");
-  boost::shared_ptr<Ekiga::NotificationCore> notification_core = core.get<Ekiga::NotificationCore> 
("notification-core");
-  boost::shared_ptr<Ekiga::AccountCore> account_core = core.get<Ekiga::AccountCore> ("account-core");
-  boost::shared_ptr<Ekiga::VideoInputCore> videoinput_core = core.get<Ekiga::VideoInputCore> 
("videoinput-core");
-  boost::shared_ptr<Ekiga::VideoOutputCore> videooutput_core = core.get<Ekiga::VideoOutputCore> 
("videooutput-core");
-  boost::shared_ptr<Ekiga::AudioInputCore> audioinput_core = core.get<Ekiga::AudioInputCore> 
("audioinput-core");
-  boost::shared_ptr<Ekiga::AudioOutputCore> audioooutput_core = core.get<Ekiga::AudioOutputCore> 
("audiooutput-core");
-  boost::shared_ptr<Ekiga::CallCore> call_core = core.get<Ekiga::CallCore> ("call-core");
-
-  if (presence_core && contact_core && chat_core && history_source && opal_bank && local_cluster_trigger
-      && notification_core && details && account_core && audioooutput_core && audioinput_core
-      && videooutput_core && videoinput_core && call_core) {
-
-    // BEWARE: the GtkFrontend ctor could do everything, but the status
-    // icon ctor and the main window ctor use GtkFrontend, so we must
-    // keep the ctor+build setup
-    boost::shared_ptr<GtkFrontend> gtk_frontend (new GtkFrontend (core));
-    core.add (gtk_frontend);
-    gtk_frontend->build ();
-    result = true;
+  GmApplication *app = NULL;
+
+  app = gm_application_new (core);
+
+  if (g_application_get_is_remote (G_APPLICATION (app))) {
+    std::cout << "FIXME Remote" << std::endl << std::flush;
+    return;
   }
-  return result;
+
+  app->priv->main_window = gm_main_window_new (app);
+  gm_application_show_main_window (app);
+
+  app->priv->chat_window = chat_window_new (app);
+  status_icon_new (app);
+
+#ifdef HAVE_DBUS
+  app->priv->dbus_component = ekiga_dbus_component_new (app);
+#endif
+
+  g_application_run (G_APPLICATION (app), argc, argv);
+  g_object_unref (app);
 }
 
 
-GtkFrontend::GtkFrontend (Ekiga::ServiceCore & _core) : core(_core)
+/* GObject stuff */
+static void
+gm_application_activate (GApplication *self)
 {
+  GmApplication *app = GM_APPLICATION (self);
+  std::cout << "activate" << std::endl << std::flush;
 }
 
-GtkFrontend::~GtkFrontend ()
+static void
+gm_application_startup (GApplication *app)
 {
+  GmApplication *self = GM_APPLICATION (app);
+
+  GtkBuilder *builder = NULL;
+  GMenuModel *app_menu = NULL;
+
+  G_APPLICATION_CLASS (gm_application_parent_class)->startup (app);
+
+  const gchar *menu =
+    "<?xml version=\"1.0\"?>"
+    "<interface>"
+    "  <menu id=\"appmenu\">"
+    "    <section>"
+    "      <item>"
+    "        <attribute name=\"label\" translatable=\"yes\">Address _Book</attribute>"
+    "        <attribute name=\"action\">app.addressbook</attribute>"
+    "      </item>"
+    "      <item>"
+    "        <attribute name=\"label\" translatable=\"yes\">_Accounts</attribute>"
+    "        <attribute name=\"action\">app.accounts</attribute>"
+    "      </item>"
+    "    </section>"
+    "    <section>"
+    "      <item>"
+    "        <attribute name=\"label\" translatable=\"yes\">_Preferences</attribute>"
+    "        <attribute name=\"action\">app.preferences</attribute>"
+    "      </item>"
+    "      <item>"
+    "        <attribute name=\"label\" translatable=\"yes\">Configuration _Assistant</attribute>"
+    "        <attribute name=\"action\">app.assistant</attribute>"
+    "      </item>"
+    "    </section>"
+    "    <section>"
+    "      <item>"
+    "        <attribute name=\"label\" translatable=\"yes\">_Help</attribute>"
+    "        <attribute name=\"action\">app.help</attribute>"
+    "        <attribute name=\"accel\">F1</attribute>"
+    "      </item>"
+    "      <item>"
+    "        <attribute name=\"label\" translatable=\"yes\">_About</attribute>"
+    "        <attribute name=\"action\">app.about</attribute>"
+    "      </item>"
+    "    </section>"
+    "    <section>"
+    "      <item>"
+    "        <attribute name=\"label\" translatable=\"yes\">_Quit</attribute>"
+    "        <attribute name=\"action\">app.quit</attribute>"
+    "        <attribute name=\"accel\">&lt;Primary&gt;q</attribute>"
+    "      </item>"
+    "    </section>"
+    "  </menu>"
+    "</interface>";
+
+  g_action_map_add_action_entries (G_ACTION_MAP (self),
+                                   app_entries, G_N_ELEMENTS (app_entries),
+                                   self);
+
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_string (builder, menu, -1, NULL);
+  app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
+  gtk_application_set_app_menu (GTK_APPLICATION (self), app_menu);
+  g_object_unref (builder);
 }
 
 
-void
-GtkFrontend::build ()
+static void
+gm_application_dispose (GObject *obj)
 {
-  StatusIcon *s = NULL;
+  GmApplication *self = NULL;
 
-  boost::shared_ptr<Ekiga::ContactCore> contact_core =
-    core.get<Ekiga::ContactCore> ("contact-core");
-  boost::shared_ptr<Ekiga::PersonalDetails> details =
-    core.get<Ekiga::PersonalDetails> ("personal-details");
-  boost::shared_ptr<Ekiga::ChatCore> chat_core =
-    core.get<Ekiga::ChatCore> ("chat-core");
-  boost::shared_ptr<Ekiga::AccountCore> account_core =
-    core.get<Ekiga::AccountCore> ("account-core");
-  boost::shared_ptr<Ekiga::AudioInputCore> audio_input_core =
-    core.get<Ekiga::AudioInputCore> ("audioinput-core");
-  boost::shared_ptr<Ekiga::AudioOutputCore> audio_output_core =
-    core.get<Ekiga::AudioOutputCore> ("audiooutput-core");
-  boost::shared_ptr<Ekiga::VideoInputCore> video_input_core =
-    core.get<Ekiga::VideoInputCore> ("videoinput-core");
-
-  /* Init the stock icons */
-  gnomemeeting_stock_icons_init ();
-  gtk_window_set_default_icon_name (GM_ICON_LOGO);
-
-  accounts_window =
-    boost::shared_ptr<GtkWidget>(accounts_window_new (account_core,
-                                                     details,
-                                                     USER_INTERFACE ".accounts-window"),
-                                gtk_widget_destroy);
-
-  // BEWARE: uses the main window during runtime
-  call_window =
-    boost::shared_ptr<GtkWidget> (call_window_new (core), gtk_widget_destroy);
-
-  chat_window =
-    boost::shared_ptr<GtkWidget> (chat_window_new (core,
-                                                  USER_INTERFACE ".chat-window"),
-                                 gtk_widget_destroy);
-
-  // BEWARE: the status icon needs the chat window at startup
-  // FIXME: the above BEWARE is related to a FIXME in the main window code,
-  // FIXME: hence should disappear with it
-  s = status_icon_new (core);
-  if (s) {
-    status_icon =
-      boost::shared_ptr<StatusIcon> (status_icon_new (core), g_object_unref);
-    g_signal_connect (status_icon.get (), "clicked",
-                     G_CALLBACK (on_status_icon_clicked), this);
-  }
+  self = GM_APPLICATION (obj);
+
+#ifdef HAVE_DBUS
+  g_object_unref (self->priv->dbus_component);
+#endif
+
+
+  G_OBJECT_CLASS (gm_application_parent_class)->dispose (obj);
+}
+
+
+static void
+gm_application_class_init (GmApplicationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GApplicationClass *app_class = G_APPLICATION_CLASS (klass);
+
+  object_class->dispose = gm_application_dispose;
+//  object_class->get_property = gm_application_get_property;
+//  object_class->constructed = gm_application_constructed;
+
+  app_class->startup = gm_application_startup;
+  app_class->activate = gm_application_activate;
+//  app_class->command_line = gm_application_command_line;
+//  app_class->local_command_line = gm_application_local_command_line;
+//  app_class->shutdown = gm_application_shutdown;
 
-  // BEWARE: the main window uses the chat window at startup already,
-  // and later on needs the call window, addressbook window,
-  // assistant window
-  main_window =
-    boost::shared_ptr<GtkWidget> (gm_main_window_new (core),
-                                  gtk_widget_destroy);
+//  klass->show_help = gm_application_show_help_impl;
+//  klass->help_link_id = gm_application_help_link_id_impl;
+//  klass->set_window_title = gm_application_set_window_title_impl;
+//  klass->create_window = gm_application_create_window_impl;
+
+  g_type_class_add_private (object_class, sizeof (GmApplicationPrivate));
 }
 
 
-const std::string
-GtkFrontend::get_name () const
+static void
+gm_application_init (GmApplication *self)
 {
-  return "gtk-frontend";
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
 }
 
 
-const std::string
-GtkFrontend::get_description () const
+GmApplication *
+gm_application_new (Ekiga::ServiceCorePtr core)
 {
-  return "\tGtk+ frontend support";
+  GmApplication *self =
+    GM_APPLICATION (g_object_new (GM_TYPE_APPLICATION,
+                                  "application-id", "org.gnome.Ekiga",
+                                  "flags", G_APPLICATION_FLAGS_NONE,
+                                  NULL));
+  g_application_register (G_APPLICATION (self), NULL, NULL);
+
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+  self->priv->core = core;
+
+  return self;
 }
 
 
-const GtkWidget*
-GtkFrontend::get_main_window () const
+Ekiga::ServiceCorePtr
+gm_application_get_core (GmApplication *self)
 {
-  return main_window.get ();
+  g_return_val_if_fail (GM_IS_APPLICATION (self), boost::shared_ptr<Ekiga::ServiceCore> ());
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+
+  return self->priv->core;
 }
 
 
-const GtkWidget*
-GtkFrontend::get_accounts_window () const
+void
+gm_application_show_main_window (GmApplication *self)
 {
-  return accounts_window.get ();
+  g_return_if_fail (GM_IS_APPLICATION (self));
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+
+  gtk_window_present (GTK_WINDOW (self->priv->main_window));
 }
 
 
-const GtkWidget*
-GtkFrontend::get_call_window () const
+void
+gm_application_hide_main_window (GmApplication *self)
 {
-  return call_window.get ();
+  g_return_if_fail (GM_IS_APPLICATION (self));
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+
+  gtk_widget_hide (self->priv->main_window);
 }
 
 
-const GtkWidget*
-GtkFrontend::get_chat_window () const
+GtkWidget *
+gm_application_get_main_window (GmApplication *self)
 {
-  return chat_window.get ();
+  g_return_val_if_fail (GM_IS_APPLICATION (self), NULL);
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+
+  return self->priv->main_window;
 }
 
 
-const StatusIcon*
-GtkFrontend::get_status_icon () const
+gboolean
+gm_application_show_help (GmApplication *app,
+                          G_GNUC_UNUSED const gchar *link_id)
 {
-  return status_icon.get ();
+  g_return_val_if_fail (GM_IS_APPLICATION (app), FALSE);
+
+  GtkWindow *parent = gtk_application_get_active_window (GTK_APPLICATION (app));
+
+#ifdef WIN32
+  gchar *locale, *loc_ , *index_path;
+  int hinst = 0;
+
+  locale = g_win32_getlocale ();
+  if (strlen (locale) > 0) {
+
+    /* try returned locale first, it may be fully qualified e.g. zh_CN */
+    index_path = g_build_filename (WIN32_HELP_DIR, locale,
+                                  WIN32_HELP_FILE, NULL);
+    hinst = (int) ShellExecute (NULL, "open", index_path, NULL,
+                               DATA_DIR, SW_SHOWNORMAL);
+    g_free (index_path);
+  }
+
+  if (hinst <= 32 && (loc_ = g_strrstr (locale, "_"))) {
+    /* on error, try short locale */
+    *loc_ = 0;
+    index_path = g_build_filename (WIN32_HELP_DIR, locale,
+                                  WIN32_HELP_FILE, NULL);
+    hinst = (int) ShellExecute (NULL, "open", index_path, NULL,
+                               DATA_DIR, SW_SHOWNORMAL);
+    g_free (index_path);
+  }
+
+  g_free (locale);
+
+  if (hinst <= 32) {
+
+    /* on error or missing locale, try default locale */
+    index_path = g_build_filename (WIN32_HELP_DIR, "C", WIN32_HELP_FILE, NULL);
+    (void)ShellExecute (NULL, "open", index_path, NULL,
+                       DATA_DIR, SW_SHOWNORMAL);
+    g_free (index_path);
+  }
+#else /* !WIN32 */
+  GError *err = NULL;
+  gboolean success = FALSE;
+
+  success = gtk_show_uri (NULL, "ghelp:" PACKAGE_NAME, GDK_CURRENT_TIME, &err);
+
+  if (!success) {
+    GtkWidget *d;
+    d = gtk_message_dialog_new (NULL,
+                                (GtkDialogFlags) (GTK_DIALOG_MODAL),
+                                GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+                                "%s", _("Unable to open help file."));
+    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (d),
+                                              "%s", err->message);
+    g_signal_connect (d, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+    gtk_window_set_transient_for (GTK_WINDOW (d), GTK_WINDOW (parent));
+    gtk_window_present (GTK_WINDOW (d));
+    g_error_free (err);
+    return FALSE;
+  }
+#endif
+
+  return TRUE;
 }
 
 
-GtkWidget*
-GtkFrontend::build_preferences_window ()
+void
+gm_application_show_about (GmApplication *app)
 {
-  boost::shared_ptr<Ekiga::AudioInputCore> audio_input_core =
-    core.get<Ekiga::AudioInputCore> ("audioinput-core");
-  boost::shared_ptr<Ekiga::AudioOutputCore> audio_output_core =
-    core.get<Ekiga::AudioOutputCore> ("audiooutput-core");
-  boost::shared_ptr<Ekiga::VideoInputCore> video_input_core =
-    core.get<Ekiga::VideoInputCore> ("videoinput-core");
+  g_return_if_fail (GM_IS_APPLICATION (app));
+
+  GtkWidget *pixmap = NULL;
+  gchar *filename = NULL;
+
+  const gchar *authors [] = {
+      "Damien Sandras <dsandras seconix com>",
+      "",
+      N_("Contributors:"),
+      "Eugen Dedu <eugen dedu pu-pm univ-fcomte fr>",
+      "Julien Puydt <julien puydt laposte net>",
+      "Robert Jongbloed <rjongbloed postincrement com>",
+      "",
+      N_("Artwork:"),
+      "Fabian Deutsch <fabian deutsch gmx de>",
+      "Vinicius Depizzol <vdepizzol gmail com>",
+      "Andreas Kwiatkowski <post kwiat org>",
+      "Carlos Pardo <me m4de com>",
+      "Jakub Steiner <jimmac ximian com>",
+      "",
+      N_("See AUTHORS file for full credits"),
+      NULL
+  };
+
+  authors [2] = gettext (authors [2]);
+  authors [7] = gettext (authors [7]);
+  authors [14] = gettext (authors [14]);
+
+  const gchar *documenters [] = {
+    "Damien Sandras <dsandras seconix com>",
+    "Christopher Warner <zanee kernelcode com>",
+    "Matthias Redlich <m-redlich t-online de>",
+    NULL
+  };
+
+  const gchar *license[] = {
+N_("This program is free software; you can redistribute it and/or modify \
+it under the terms of the GNU General Public License as published by \
+the Free Software Foundation; either version 2 of the License, or \
+(at your option) any later version. "),
+N_("This program is distributed in the hope that it will be useful, \
+but WITHOUT ANY WARRANTY; without even the implied warranty of \
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \
+GNU General Public License for more details. \
+You should have received a copy of the GNU General Public License \
+along with this program; if not, write to the Free Software Foundation, \
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA."),
+N_("Ekiga is licensed under the GPL license and as a special exception, \
+you have permission to link or otherwise combine this program with the \
+programs OPAL, OpenH323 and PWLIB, and distribute the combination, \
+without applying the requirements of the GNU GPL to the OPAL, OpenH323 \
+and PWLIB programs, as long as you do follow the requirements of the \
+GNU GPL for all the rest of the software thus combined.")
+  };
+
+  gchar *license_trans;
+
+  /* Translators: Please write translator credits here, and
+   * separate names with \n */
+  const gchar *translator_credits = _("translator-credits");
+  if (g_strcmp0 (translator_credits, "translator-credits") == 0)
+    translator_credits = "No translators, English by\n"
+        "Damien Sandras <dsandras seconix com>";
+
+  const gchar *comments =  _("Ekiga is full-featured SIP and H.323 compatible VoIP, IP-Telephony and 
Videoconferencing application that allows you to make audio and video calls to remote users with SIP and 
H.323 hardware or software.");
+
+  license_trans = g_strconcat (_(license[0]), "\n\n", _(license[1]), "\n\n",
+                               _(license[2]), "\n\n", NULL);
+
+  filename = g_build_filename (DATA_DIR, "pixmaps", PACKAGE_NAME,
+                               PACKAGE_NAME "-logo.png", NULL);
+  pixmap =  gtk_image_new_from_file (filename);
+
+  gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (GTK_APPLICATION (app))),
+                         "name", "Ekiga",
+                         "version", VERSION,
+                         "copyright", "Copyright © 2000-2014 Damien Sandras",
+                         "authors", authors,
+                         "documenters", documenters,
+                         "translator-credits", translator_credits,
+                         "comments", comments,
+                         "logo", gtk_image_get_pixbuf (GTK_IMAGE (pixmap)),
+                         "license", license_trans,
+                         "wrap-license", TRUE,
+                         "website", "http://www.ekiga.org";,
+                         NULL);
+
+  g_free (license_trans);
+  g_free (filename);
+}
 
-  return preferences_window_new (audio_input_core,
-                                 audio_output_core,
-                                 video_input_core);
+
+GtkWidget *
+gm_application_show_call_window (GmApplication *self)
+{
+  GtkWidget *call_window = NULL;
+  g_return_val_if_fail (GM_IS_APPLICATION (self), NULL);
+
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+
+  call_window = call_window_new (self);
+  gtk_window_present (GTK_WINDOW (call_window));
+
+  return call_window;
 }
 
 
-GtkWidget*
-GtkFrontend::build_addressbook_window ()
+void
+gm_application_show_chat_window (GmApplication *self)
 {
-  boost::shared_ptr<Ekiga::ContactCore> contact_core =
-    core.get<Ekiga::ContactCore> ("contact-core");
+  g_return_if_fail (GM_IS_APPLICATION (self));
+
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
 
-  return addressbook_window_new (contact_core,
-                                 USER_INTERFACE ".addressbook-window");
+  // FIXME: We should move the chat window to a build & destroy scheme
+  // but unread-alert prevents this
+  std::cout << "FIXME" << std::endl << std::flush;
+  gtk_window_present (GTK_WINDOW (self->priv->chat_window));
 }
 
 
-GtkWidget*
-GtkFrontend::build_assistant_window ()
+GtkWidget *
+gm_application_get_chat_window (GmApplication *self)
 {
-  return assistant_window_new (core);
+  g_return_val_if_fail (GM_IS_APPLICATION (self), NULL);
+
+  return self->priv->chat_window;
+}
+
+
+void
+gm_application_show_preferences_window (GmApplication *self)
+{
+  GtkWindow *parent = NULL;
+  GtkWindow *window = NULL;
+
+  g_return_if_fail (GM_IS_APPLICATION (self));
+
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+  parent = gtk_application_get_active_window (GTK_APPLICATION (self));
+
+  window = GTK_WINDOW (preferences_window_new (self));
+  gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (parent));
+  gtk_dialog_run (GTK_DIALOG (window));
+}
+
+
+void
+gm_application_show_addressbook_window (GmApplication *self)
+{
+  g_return_if_fail (GM_IS_APPLICATION (self));
+
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+
+  gtk_window_present (GTK_WINDOW (addressbook_window_new (self)));
+}
+
+
+void
+gm_application_show_accounts_window (GmApplication *self)
+{
+  g_return_if_fail (GM_IS_APPLICATION (self));
+
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+
+  gtk_window_present (GTK_WINDOW (accounts_window_new (self)));
 }
diff --git a/lib/engine/gui/gtk-frontend/gtk-frontend.h b/lib/engine/gui/gtk-frontend/gtk-frontend.h
index b2d8099..9beac78 100644
--- a/lib/engine/gui/gtk-frontend/gtk-frontend.h
+++ b/lib/engine/gui/gtk-frontend/gtk-frontend.h
@@ -1,6 +1,6 @@
 
 /* Ekiga -- A VoIP and Video-Conferencing application
- * Copyright (C) 2000-2009 Damien Sandras <dsandras seconix com>
+ * Copyright (C) 2000-2014 Damien Sandras <dsandras seconix com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,10 +29,9 @@
 /*
  *                         gtk-frontend.h  -  description
  *                         ------------------------------------------
- *   begin                : written in 2007 by Julien Puydt
- *   copyright            : (c) 2007 by Julien Puydt
- *   description          : code to hook a gtk+ user interface to
- *                          the main program
+ *   begin                : written in 2014 by Damien Sandras
+ *   copyright            : (c) 2014 by Damien Sandras
+ *   description          : main Ekiga GtkApplication
  *
  */
 
@@ -41,59 +40,76 @@
 
 #include <gtk/gtk.h>
 
-#include "statusicon.h"
-
 #include "services.h"
 #include "contact-core.h"
 #include "presence-core.h"
 
+G_BEGIN_DECLS
+
+typedef struct _GmApplication GmApplication;
+typedef struct _GmApplicationPrivate GmApplicationPrivate;
+typedef struct _GmApplicationClass GmApplicationClass;
+
+
+/* GObject thingies */
+struct _GmApplication
+{
+  GtkApplication parent;
+  GmApplicationPrivate *priv;
+};
 
-class GtkFrontend: public Ekiga::Service
+struct _GmApplicationClass
 {
-public:
+  GtkApplicationClass parent;
+};
 
-  GtkFrontend (Ekiga::ServiceCore & _core);
 
-  ~GtkFrontend ();
+void ekiga_main (Ekiga::ServiceCorePtr core,
+                 int argc,
+                 char **argv);
 
-  void build ();
+GmApplication *gm_application_new (Ekiga::ServiceCorePtr core);
 
-  const std::string get_name () const;
+Ekiga::ServiceCorePtr gm_application_get_core (GmApplication *app);
 
-  const std::string get_description () const;
+void gm_application_show_main_window (GmApplication *app);
 
-  const GtkWidget* get_assistant_window () const;
+void gm_application_hide_main_window (GmApplication *app);
 
-  const GtkWidget* get_main_window () const;
+GtkWidget *gm_application_get_main_window (GmApplication *app);
 
-  const GtkWidget *get_accounts_window () const;
+gboolean gm_application_show_help (GmApplication *app,
+                                   const gchar *link_id);
 
-  const GtkWidget *get_call_window () const;
+void gm_application_show_about (GmApplication *app);
 
-  const GtkWidget *get_chat_window () const;
+GtkWidget *gm_application_show_call_window (GmApplication *app);
 
-  const StatusIcon *get_status_icon () const;
+void gm_application_show_chat_window (GmApplication *app);
 
-  GtkWidget* build_preferences_window ();
+GtkWidget *gm_application_get_chat_window (GmApplication *app);
 
-  GtkWidget* build_addressbook_window ();
+void gm_application_show_preferences_window (GmApplication *app);
 
-  GtkWidget* build_assistant_window ();
+void gm_application_show_addressbook_window (GmApplication *app);
 
-private :
+void gm_application_show_accounts_window (GmApplication *app);
 
-  boost::shared_ptr<GtkWidget> main_window;
-  boost::shared_ptr<GtkWidget> accounts_window;
-  boost::shared_ptr<GtkWidget> call_window;
-  boost::shared_ptr<GtkWidget> chat_window;
-  boost::shared_ptr<StatusIcon> status_icon;
+/* GObject boilerplate */
+#define GM_TYPE_APPLICATION (gm_application_get_type ())
 
-  Ekiga::ServiceCore & core;
-};
+#define GM_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GM_TYPE_APPLICATION, GmApplication))
+
+#define GM_IS_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GM_TYPE_APPLICATION))
+
+#define GM_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GM_TYPE_APPLICATION, 
GmApplicationClass))
+
+#define GM_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GM_TYPE_APPLICATION))
+
+#define GM_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GM_TYPE_APPLICATION, 
GmApplicationClass))
 
+GType gm_application_get_type (void) G_GNUC_CONST;
 
-bool gtk_frontend_init (Ekiga::ServiceCore &core,
-                       int *argc,
-                       char **argv[]);
+G_END_DECLS
 
 #endif
diff --git a/lib/engine/gui/gtk-frontend/main_window.cpp b/lib/engine/gui/gtk-frontend/main_window.cpp
index d098ef0..c99c5c2 100644
--- a/lib/engine/gui/gtk-frontend/main_window.cpp
+++ b/lib/engine/gui/gtk-frontend/main_window.cpp
@@ -44,7 +44,6 @@
 #include "dialpad.h"
 #include "statusmenu.h"
 
-#include "gmcallbacks.h"
 #include "gmentrydialog.h"
 #include "gmstatusbar.h"
 #include "gmmenuaddon.h"
@@ -93,7 +92,8 @@ G_DEFINE_TYPE (EkigaMainWindow, ekiga_main_window, GM_TYPE_WINDOW);
 
 struct _EkigaMainWindowPrivate
 {
-  Ekiga::ServiceCore* core;
+  GmApplication *app;
+  Ekiga::ServiceCorePtr core;
 
   boost::shared_ptr<Ekiga::AccountCore> account_core;
   boost::shared_ptr<Ekiga::AudioOutputCore> audiooutput_core;
@@ -104,9 +104,7 @@ struct _EkigaMainWindowPrivate
   boost::shared_ptr<Ekiga::Trigger> local_cluster_trigger;
   boost::shared_ptr<History::Source> history_source;
 
-  // this one is weak because otherwise we're sure to have a
-  // dependency loop
-  boost::weak_ptr<GtkFrontend> gtk_frontend;
+  GtkWidget *call_window;
 
   GtkAccelGroup *accel;
   GtkWidget *main_menu;
@@ -183,15 +181,6 @@ static void url_changed_cb (GtkEditable *e,
 static void show_dialpad_cb (GtkWidget *widget,
                              gpointer data);
 
-static void build_and_show_addressbook_window_cb (GtkWidget *widget,
-                                                  gpointer data);
-
-static void build_and_show_assistant_window_cb (GtkWidget *widget,
-                                                gpointer data);
-
-static void run_prefs_window_cb (G_GNUC_UNUSED GtkWidget *widget,
-                                 gpointer data);
-
 static gboolean on_delayed_hide_call_window_cb (gpointer data);
 
 static void ekiga_main_window_append_call_url (EkigaMainWindow *mw,
@@ -200,14 +189,6 @@ static void ekiga_main_window_append_call_url (EkigaMainWindow *mw,
 static const std::string ekiga_main_window_get_call_url (EkigaMainWindow *mw);
 
 
-/* DESCRIPTION  :  This callback is called when the chat window alerts about
- *                 unread messages
- * BEHAVIOR     :  Plays a sound (if enabled)
- * PRE          :  /
- */
-static void on_chat_unread_alert (GtkWidget*,
-                                 gpointer);
-
 
 /* DESCRIPTION  :  This callback is called when the control panel
  *                 section changes.
@@ -237,14 +218,6 @@ static void pull_trigger_cb (GtkWidget * /*widget*/,
                              gpointer data);
 
 
-/** Show the widget passed as parameter
- *
- * @param data is a pointer to the widget to show
- */
-static void  show_widget_cb (GtkWidget * /*widget*/,
-                             gpointer data);
-
-
 /* DESCRIPTION  :  This callback is called when the user
  *                 presses a key.
  * BEHAVIOR     :  Sends a DTMF if we are in a call.
@@ -448,62 +421,6 @@ show_dialpad_cb (G_GNUC_UNUSED GtkWidget *widget,
   mw->priv->user_interface_settings->set_int ("panel-section", DIALPAD);
 }
 
-
-static void
-build_and_show_addressbook_window_cb (G_GNUC_UNUSED GtkWidget *widget,
-                                      gpointer data)
-{
-  GtkWidget *window = NULL;
-
-  g_return_if_fail (EKIGA_IS_MAIN_WINDOW (data));
-  EkigaMainWindow *self = EKIGA_MAIN_WINDOW (data);
-  boost::shared_ptr<GtkFrontend> gtk_frontend = self->priv->gtk_frontend.lock ();
-
-  window = gtk_frontend->build_addressbook_window ();
-  gm_window_set_hide_on_delete (GM_WINDOW (window), FALSE);
-  gm_window_set_hide_on_escape (GM_WINDOW (window), FALSE);
-  gtk_widget_show (window);
-}
-
-//FIXME: Is there a better way than duplicating code here
-static void
-build_and_show_assistant_window_cb (G_GNUC_UNUSED GtkWidget *widget,
-                                    gpointer data)
-{
-  GtkWidget *window = NULL;
-
-  g_return_if_fail (EKIGA_IS_MAIN_WINDOW (data));
-  EkigaMainWindow *self = EKIGA_MAIN_WINDOW (data);
-  boost::shared_ptr<GtkFrontend> gtk_frontend = self->priv->gtk_frontend.lock ();
-
-  window = gtk_frontend->build_assistant_window ();
-  gtk_window_set_transient_for (GTK_WINDOW (window),
-                                GTK_WINDOW (self));
-  gtk_widget_show (window);
-}
-
-
-static void
-run_prefs_window_cb (G_GNUC_UNUSED GtkWidget *widget,
-                     gpointer data)
-{
-  GtkWidget *prefs_window = NULL;
-
-  g_return_if_fail (EKIGA_IS_MAIN_WINDOW (data));
-  EkigaMainWindow *self = EKIGA_MAIN_WINDOW (data);
-
-  boost::shared_ptr<GtkFrontend> gtk_frontend = self->priv->gtk_frontend.lock ();
-
-  g_return_if_fail (gtk_frontend);
-
-  /* This will build a new window */
-  prefs_window = GTK_WIDGET (gtk_frontend->build_preferences_window ());
-
-  gtk_window_set_transient_for (GTK_WINDOW (prefs_window),
-                                GTK_WINDOW (self));
-  gtk_dialog_run (GTK_DIALOG (prefs_window));
-}
-
 static void
 on_account_updated (Ekiga::BankPtr /*bank*/,
                    Ekiga::AccountPtr account,
@@ -533,7 +450,6 @@ static void on_setup_call_cb (boost::shared_ptr<Ekiga::CallManager> manager,
                               gpointer self)
 {
   EkigaMainWindow *mw = EKIGA_MAIN_WINDOW (self);
-  GtkWidget *call_window = NULL;
 
   if (!call->is_outgoing () && !manager->get_auto_answer ()) {
     if (mw->priv->current_call)
@@ -546,13 +462,7 @@ static void on_setup_call_cb (boost::shared_ptr<Ekiga::CallManager> manager,
   }
   else {
 
-    /* Show call window */
-    boost::shared_ptr<GtkFrontend> gtk_frontend = mw->priv->gtk_frontend.lock ();
-    if (gtk_frontend) {
-
-      call_window = GTK_WIDGET (gtk_frontend->get_call_window ());
-      gtk_widget_show (call_window);
-    }
+    gm_application_show_call_window (mw->priv->app);
 
     mw->priv->current_call = call;
     mw->priv->calling_state = Calling;
@@ -581,7 +491,6 @@ static void on_established_call_cb (boost::shared_ptr<Ekiga::CallManager>  /*man
                                     gpointer self)
 {
   EkigaMainWindow *mw = EKIGA_MAIN_WINDOW (self);
-  GtkWidget *call_window = NULL;
   gchar* info = NULL;
 
   /* Update calling state */
@@ -599,13 +508,7 @@ static void on_established_call_cb (boost::shared_ptr<Ekiga::CallManager>  /*man
   mw->priv->audiooutput_core->stop_play_event("incoming_call_sound");
   mw->priv->audiooutput_core->stop_play_event("ring_tone_sound");
 
-  /* Show call window */
-    boost::shared_ptr<GtkFrontend> gtk_frontend = mw->priv->gtk_frontend.lock ();
-    if (gtk_frontend) {
-
-      call_window = GTK_WIDGET (gtk_frontend->get_call_window ());
-      gtk_widget_show (call_window);
-    }
+  gm_application_show_call_window (mw->priv->app);
 }
 
 
@@ -706,15 +609,12 @@ on_delayed_hide_call_window_cb (gpointer data)
 
   EkigaMainWindow *mw = EKIGA_MAIN_WINDOW (data);
 
-    boost::shared_ptr<GtkFrontend> gtk_frontend = mw->priv->gtk_frontend.lock ();
-    if (gtk_frontend) {
-
-      GtkWidget* call_window = GTK_WIDGET (gtk_frontend->get_call_window ());
-
-      if (!mw->priv->current_call
-          && !mw->priv->video_devices_settings->get_bool ("enable-preview"))
-       gtk_widget_hide (GTK_WIDGET (call_window));
-    }
+  if (!mw->priv->current_call
+      && !mw->priv->video_devices_settings->get_bool ("enable-preview")
+      && mw->priv->call_window) {
+    gtk_widget_destroy (mw->priv->call_window);
+    mw->priv->call_window = NULL;
+  }
 
   return FALSE;
 }
@@ -789,23 +689,6 @@ on_roster_selection_changed (G_GNUC_UNUSED GtkWidget* view,
 
 
 static void
-on_chat_unread_alert (G_GNUC_UNUSED GtkWidget* widget,
-                     gpointer self)
-{
-  EkigaMainWindow *mw = EKIGA_MAIN_WINDOW (self);
-
-  g_return_if_fail (mw != NULL);
-  if (!mw->priv->sound_events_settings->get_bool ("enable-new-message-sound"))
-    return;
-
-  std::string file_name_string = mw->priv->sound_events_settings->get_string ("new-message-sound");
-
-  if (!file_name_string.empty ())
-    mw->priv->audiooutput_core->play_file (file_name_string);
-}
-
-
-static void
 panel_section_changed (G_GNUC_UNUSED GtkNotebook *notebook,
                        G_GNUC_UNUSED GtkWidget *page,
                        guint section,
@@ -837,15 +720,13 @@ video_preview_changed (GtkToggleToolButton *button,
   if (mw->priv->calling_state == Standby) {
 
     bool toggled = gtk_toggle_tool_button_get_active (button);
-    boost::shared_ptr<GtkFrontend> gtk_frontend = mw->priv->gtk_frontend.lock ();
-    if (gtk_frontend) {
-
-      GtkWidget *call_window = GTK_WIDGET (gtk_frontend->get_call_window ());
-      if (!toggled)
-        gtk_widget_hide (call_window);
-      else
-        gtk_widget_show (call_window);
+    if (!toggled) {
+      if (mw->priv->call_window)
+        gtk_widget_destroy (mw->priv->call_window);
+      mw->priv->call_window = NULL;
     }
+    else
+      mw->priv->call_window = gm_application_show_call_window (mw->priv->app);
   }
 }
 
@@ -863,16 +744,6 @@ pull_trigger_cb (GtkWidget * /*widget*/,
 
 
 static void
-show_widget_cb (GtkWidget * /*widget*/,
-                gpointer data)
-{
-  g_return_if_fail (data != NULL);
-
-  gtk_widget_show_all (GTK_WIDGET (data));
-}
-
-
-static void
 dialpad_button_clicked_cb (EkigaDialpad  * /* dialpad */,
                           const gchar *button_text,
                           EkigaMainWindow *mw)
@@ -1132,18 +1003,10 @@ ekiga_main_window_init_actions_toolbar (EkigaMainWindow *mw)
 static void
 ekiga_main_window_init_menu (EkigaMainWindow *mw)
 {
-  GtkWidget *accounts_window = NULL;
-
   mw->priv->main_menu = gtk_menu_bar_new ();
 
   g_return_if_fail (mw != NULL);
 
-  boost::shared_ptr<GtkFrontend> gtk_frontend = mw->priv->gtk_frontend.lock ();
-
-  g_return_if_fail (gtk_frontend);
-
-  accounts_window = GTK_WIDGET (gtk_frontend->get_accounts_window ());
-
   static MenuEntry gnomemeeting_menu [] =
     {
       GTK_MENU_NEW (_("_Chat")),
@@ -1164,12 +1027,6 @@ ekiga_main_window_init_menu (EkigaMainWindow *mw)
                     G_CALLBACK (pull_trigger_cb),
                     &*mw->priv->local_cluster_trigger, true),
 
-      GTK_MENU_THEME_ENTRY("address_book", _("Address _Book"),
-                          _("Find contacts"),
-                          "x-office-address-book", 'b',
-                          G_CALLBACK (build_and_show_addressbook_window_cb),
-                          (gpointer) mw, TRUE),
-
       GTK_MENU_SEPARATOR,
 
       GTK_MENU_ENTRY("close", NULL, _("Close the Ekiga window"),
@@ -1177,34 +1034,6 @@ ekiga_main_window_init_menu (EkigaMainWindow *mw)
                     G_CALLBACK (window_closed_from_menu_cb),
                     (gpointer) mw, TRUE),
 
-      GTK_MENU_SEPARATOR,
-
-      GTK_MENU_ENTRY("quit", NULL, _("Quit"),
-                    GTK_STOCK_QUIT, 'Q',
-                    G_CALLBACK (quit_callback), NULL, TRUE),
-
-      GTK_MENU_NEW (_("_Edit")),
-
-      GTK_MENU_ENTRY("configuration_assistant", _("_Configuration Assistant"),
-                    _("Run the configuration assistant"),
-                    NULL, 0,
-                    G_CALLBACK (build_and_show_assistant_window_cb),
-                    (gpointer) mw, TRUE),
-
-      GTK_MENU_SEPARATOR,
-
-      GTK_MENU_ENTRY("accounts", _("_Accounts"),
-                    _("Edit your accounts"),
-                    NULL, 'E',
-                    G_CALLBACK (show_widget_cb),
-                    (gpointer) accounts_window, TRUE),
-
-      GTK_MENU_ENTRY("preferences", NULL,
-                    _("Change your preferences"),
-                    GTK_STOCK_PREFERENCES, 0,
-                    G_CALLBACK (run_prefs_window_cb),
-                    (gpointer) mw, TRUE),
-
       GTK_MENU_NEW(_("_View")),
 
       GTK_MENU_TOGGLE_ENTRY("preview", _("_Video Preview"),
@@ -1241,19 +1070,6 @@ ekiga_main_window_init_menu (EkigaMainWindow *mw)
                              "show-offline-contacts",
                              TRUE),
 
-      GTK_MENU_NEW(_("_Help")),
-
-      GTK_MENU_ENTRY("help", NULL,
-                     _("Get help by reading the Ekiga manual"),
-                     GTK_STOCK_HELP, GDK_KEY_F1,
-                     G_CALLBACK (help_callback), NULL, TRUE),
-
-      GTK_MENU_ENTRY("about", NULL,
-                    _("View information about Ekiga"),
-                    GTK_STOCK_ABOUT, 0,
-                    G_CALLBACK (about_callback), (gpointer) mw,
-                    TRUE),
-
       GTK_MENU_END
     };
 
@@ -1435,6 +1251,7 @@ ekiga_main_window_init (EkigaMainWindow *mw)
 
   mw->priv->current_call = boost::shared_ptr<Ekiga::Call>();
   mw->priv->calling_state = Standby;
+  mw->priv->call_window = NULL;
 
   mw->priv->user_interface_settings =
     boost::shared_ptr<Ekiga::Settings> (new Ekiga::Settings (USER_INTERFACE ".main-window"));
@@ -1560,38 +1377,39 @@ ekiga_main_window_connect_engine_signals (EkigaMainWindow *mw)
 }
 
 GtkWidget *
-gm_main_window_new (Ekiga::ServiceCore & core)
+gm_main_window_new (GmApplication *app)
 {
   EkigaMainWindow *mw;
 
+  g_return_val_if_fail (GM_IS_APPLICATION (app), NULL);
+
   /* basic gtk+ setup  */
   mw = EKIGA_MAIN_WINDOW (g_object_new (EKIGA_TYPE_MAIN_WINDOW,
+                                        "application", GTK_APPLICATION (app),
                                        "key", USER_INTERFACE ".main-window",
                                        NULL));
+  Ekiga::ServiceCorePtr core = gm_application_get_core (app);
 
   /* fetching needed engine objects */
-
-  mw->priv->core = &core;
+  mw->priv->core = core;
+  mw->priv->app = app;
 
   mw->priv->account_core
-    = core.get<Ekiga::AccountCore> ("account-core");
+    = core->get<Ekiga::AccountCore> ("account-core");
   mw->priv->audiooutput_core
-    = core.get<Ekiga::AudioOutputCore>("audiooutput-core");
+    = core->get<Ekiga::AudioOutputCore>("audiooutput-core");
   mw->priv->call_core
-    = core.get<Ekiga::CallCore> ("call-core");
+    = core->get<Ekiga::CallCore> ("call-core");
   mw->priv->contact_core
-    = core.get<Ekiga::ContactCore> ("contact-core");
+    = core->get<Ekiga::ContactCore> ("contact-core");
   mw->priv->presence_core
-    = core.get<Ekiga::PresenceCore> ("presence-core");
+    = core->get<Ekiga::PresenceCore> ("presence-core");
   mw->priv->bank
-    = core.get<Opal::Bank> ("opal-account-store");
+    = core->get<Opal::Bank> ("opal-account-store");
   mw->priv->local_cluster_trigger
-    = core.get<Ekiga::Trigger> ("local-cluster");
+    = core->get<Ekiga::Trigger> ("local-cluster");
   mw->priv->history_source
-    = core.get<History::Source> ("call-history-store");
-
-  mw->priv->gtk_frontend
-    = core.get<GtkFrontend> ("gtk-frontend");
+    = core->get<History::Source> ("call-history-store");
 
   ekiga_main_window_connect_engine_signals (mw);
 
@@ -1600,21 +1418,6 @@ gm_main_window_new (Ekiga::ServiceCore & core)
   // initial population
   on_some_core_updated (mw);
 
-  // FIXME: what does it do inside the main window if it's all about
-  // FIXME: the chat window and the audio output core!?
-  // FIXME: I don't like this either (damien).
-
-  /* initialize the callback to play IM message sound */
-  boost::shared_ptr<GtkFrontend> gtk_frontend = mw->priv->gtk_frontend.lock ();
-
-  if (gtk_frontend) {
-
-    GtkWidget *chat_window = GTK_WIDGET (gtk_frontend->get_chat_window ());
-
-    g_signal_connect (chat_window, "unread-alert",
-                     G_CALLBACK (on_chat_unread_alert), mw);
-  }
-
   return GTK_WIDGET(mw);
 }
 
diff --git a/lib/engine/gui/gtk-frontend/main_window.h b/lib/engine/gui/gtk-frontend/main_window.h
index 45eddca..1488c9c 100644
--- a/lib/engine/gui/gtk-frontend/main_window.h
+++ b/lib/engine/gui/gtk-frontend/main_window.h
@@ -39,8 +39,8 @@
 #ifndef __MAIN_WINDOW_H__
 #define __MAIN_WINDOW_H__
 
-#include "services.h"
 #include "gmwindow.h"
+#include "gtk-frontend.h"
 
 G_BEGIN_DECLS
 
@@ -67,7 +67,7 @@ G_END_DECLS
 
 /* DESCRIPTION  :  /
  * BEHAVIOR     :  Builds the main window and adds the popup to the image.
- * PRE          :  Accels.
+ * PRE          :  /
  */
-GtkWidget *gm_main_window_new (Ekiga::ServiceCore & core);
+GtkWidget *gm_main_window_new (GmApplication *app);
 #endif
diff --git a/lib/engine/gui/gtk-frontend/preferences-window.cpp 
b/lib/engine/gui/gtk-frontend/preferences-window.cpp
index 02d8e91..5561bd1 100644
--- a/lib/engine/gui/gtk-frontend/preferences-window.cpp
+++ b/lib/engine/gui/gtk-frontend/preferences-window.cpp
@@ -49,7 +49,6 @@
 
 #include "scoped-connections.h"
 
-#include "gmcallbacks.h"
 #include "codecsbox.h"
 
 #ifdef WIN32
@@ -73,6 +72,8 @@ struct _PreferencesWindowPrivate
   GtkWidget *fsbutton;
   GtkWidget *notebook;
 
+  GmApplication *app;
+
   boost::shared_ptr<Ekiga::VideoInputCore> videoinput_core;
   boost::shared_ptr<Ekiga::AudioInputCore> audioinput_core;
   boost::shared_ptr<Ekiga::AudioOutputCore> audiooutput_core;
@@ -1439,7 +1440,8 @@ dialog_response_cb (GtkDialog *dialog,
 {
   switch (response_id) {
   case GTK_RESPONSE_HELP:
-    help_callback (NULL, NULL);
+    //help_callback (NULL, NULL);
+    std::cout << "FIXME" << std::endl << std::flush;
     g_signal_stop_emission_by_name (dialog, "response");
     break;
   default:
@@ -1734,22 +1736,25 @@ preferences_window_class_init (PreferencesWindowClass *klass)
 
 /* Public functions */
 GtkWidget *
-preferences_window_new (boost::shared_ptr<Ekiga::AudioInputCore> audio_input_core,
-                        boost::shared_ptr<Ekiga::AudioOutputCore> audio_output_core,
-                        boost::shared_ptr<Ekiga::VideoInputCore> video_input_core)
+preferences_window_new (GmApplication *app)
 {
   PreferencesWindow *self = NULL;
 
+  g_return_val_if_fail (GM_IS_APPLICATION (app), NULL);
+
   GdkPixbuf *pixbuf = NULL;
   GtkWidget *container = NULL;
   boost::signals2::connection conn;
 
+  Ekiga::ServiceCorePtr core = gm_application_get_core (app);
+
   /* The window */
   self = (PreferencesWindow *) g_object_new (PREFERENCES_WINDOW_TYPE, NULL);
   self->priv = new PreferencesWindowPrivate ();
-  self->priv->audioinput_core = audio_input_core;
-  self->priv->audiooutput_core = audio_output_core;
-  self->priv->videoinput_core = video_input_core;
+  self->priv->audioinput_core = core->get<Ekiga::AudioInputCore> ("audioinput-core");
+  self->priv->audiooutput_core = core->get<Ekiga::AudioOutputCore> ("audiooutput-core");
+  self->priv->videoinput_core = core->get<Ekiga::VideoInputCore> ("videoinput-core");
+  self->priv->app = app;
 
   gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL);
   gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_HELP, GTK_RESPONSE_HELP);
diff --git a/lib/engine/gui/gtk-frontend/preferences-window.h 
b/lib/engine/gui/gtk-frontend/preferences-window.h
index bf2eaf6..959a2c4 100644
--- a/lib/engine/gui/gtk-frontend/preferences-window.h
+++ b/lib/engine/gui/gtk-frontend/preferences-window.h
@@ -48,6 +48,8 @@
 #include "audiooutput-core.h"
 #include "videoinput-core.h"
 
+#include "gtk-frontend.h"
+
 typedef struct _PreferencesWindow PreferencesWindow;
 typedef struct _PreferencesWindowPrivate PreferencesWindowPrivate;
 typedef struct _PreferencesWindowClass PreferencesWindowClass;
@@ -87,8 +89,6 @@ GType preferences_window_get_type ();
  * BEHAVIOR     :  It builds the preferences window.
  * PRE          :  /
  */
-GtkWidget *preferences_window_new (boost::shared_ptr<Ekiga::AudioInputCore> audio_input_core,
-                                   boost::shared_ptr<Ekiga::AudioOutputCore> audio_output_core,
-                                   boost::shared_ptr<Ekiga::VideoInputCore> video_input_core);
+GtkWidget *preferences_window_new (GmApplication *app);
 
 #endif
diff --git a/lib/engine/gui/gtk-frontend/statusicon.cpp b/lib/engine/gui/gtk-frontend/statusicon.cpp
index 2b3a718..1cb71a8 100644
--- a/lib/engine/gui/gtk-frontend/statusicon.cpp
+++ b/lib/engine/gui/gtk-frontend/statusicon.cpp
@@ -42,7 +42,6 @@
 
 #include "gmstockicons.h"
 #include "gmmenuaddon.h"
-#include "gmcallbacks.h"
 
 #include "services.h"
 #include "gtk-frontend.h"
@@ -60,6 +59,8 @@
  */
 struct _StatusIconPrivate
 {
+  GmApplication *app;
+
   GtkWidget *popup_menu;
   gboolean has_message;
 
@@ -99,6 +100,10 @@ statusicon_activated_cb (GtkStatusIcon *icon,
                          gpointer data);
 
 static void
+status_icon_clicked_cb (G_GNUC_UNUSED GtkWidget* widget,
+                        gpointer data);
+
+static void
 unread_count_cb (GtkWidget *widget,
                 guint messages,
                 gpointer data);
@@ -297,6 +302,26 @@ statusicon_activated_cb (G_GNUC_UNUSED GtkStatusIcon *icon,
   gtk_status_icon_set_tooltip_text (GTK_STATUS_ICON (self), NULL);
 }
 
+static void
+status_icon_clicked_cb (G_GNUC_UNUSED GtkWidget* widget,
+                        gpointer data)
+{
+  StatusIcon *self = STATUSICON (data);
+  GtkWidget *window = gm_application_get_main_window (GM_APPLICATION (self->priv->app));
+
+  if (!gtk_widget_get_visible (window)
+      || (gdk_window_get_state (GDK_WINDOW (gtk_widget_get_window (window)))
+          & GDK_WINDOW_STATE_ICONIFIED)) {
+    gtk_widget_show (window);
+  }
+  else {
+
+    if (gtk_window_has_toplevel_focus (GTK_WINDOW (window)))
+      gtk_widget_hide (window);
+    else
+      gtk_window_present (GTK_WINDOW (window));
+  }
+}
 
 static void
 unread_count_cb (G_GNUC_UNUSED GtkWidget *widget,
@@ -378,6 +403,9 @@ cleared_call_cb (boost::shared_ptr<Ekiga::CallManager>  /*manager*/,
 static GtkWidget *
 statusicon_build_menu ()
 {
+  std::cout << "FIXME" << std::endl << std::flush;
+
+  /*
   static MenuEntry menu [] =
     {
       GTK_MENU_ENTRY("help", NULL,
@@ -400,8 +428,9 @@ statusicon_build_menu ()
 
       GTK_MENU_END
     };
-
   return GTK_WIDGET (gtk_build_popup_menu (NULL, menu, NULL));
+*/
+  return NULL;
 }
 
 
@@ -546,13 +575,17 @@ statusicon_should_run (void)
  * Public API
  */
 StatusIcon *
-status_icon_new (Ekiga::ServiceCore & core)
+status_icon_new (GmApplication *app)
 {
   StatusIcon *self = NULL;
 
+  g_return_val_if_fail (GM_IS_APPLICATION (app), NULL);
+
   if (!statusicon_should_run ())
     return self;
 
+  Ekiga::ServiceCorePtr core = gm_application_get_core (app);
+
   boost::signals2::connection conn;
 
   self = STATUSICON (g_object_new (STATUSICON_TYPE, NULL));
@@ -565,29 +598,36 @@ status_icon_new (Ekiga::ServiceCore & core)
   self->priv->blinking = false;
   self->priv->blink_image = NULL;
   self->priv->unread_messages = false;
+  self->priv->app = app;
 
-  boost::shared_ptr<Ekiga::PersonalDetails> details = core.get<Ekiga::PersonalDetails> ("personal-details");
-  boost::shared_ptr<Ekiga::CallCore> call_core = core.get<Ekiga::CallCore> ("call-core");
-  boost::shared_ptr<Ekiga::NotificationCore> notification_core = core.get<Ekiga::NotificationCore> 
("notification-core");
-  boost::shared_ptr<GtkFrontend> frontend = core.get<GtkFrontend> ("gtk-frontend");
+  boost::shared_ptr<Ekiga::PersonalDetails> details =
+    core->get<Ekiga::PersonalDetails> ("personal-details");
+  boost::shared_ptr<Ekiga::CallCore> call_core =
+    core->get<Ekiga::CallCore> ("call-core");
+  boost::shared_ptr<Ekiga::NotificationCore> notification_core =
+    core->get<Ekiga::NotificationCore> ("notification-core");
 
-
-  self->priv->chat_window = GTK_WIDGET (frontend->get_chat_window ());
+  self->priv->chat_window = gm_application_get_chat_window (app);
 
   statusicon_set_status (self, details->get_presence ());
-  notification_core->notification_added.connect (boost::bind (statusicon_on_notification_added, _1, 
(gpointer) self));
+  notification_core->notification_added.connect (boost::bind (statusicon_on_notification_added,
+                                                              _1, (gpointer) self));
 
-  conn = details->updated.connect (boost::bind (&personal_details_updated_cb, self, details));
+  conn = details->updated.connect (boost::bind (&personal_details_updated_cb,
+                                                self, details));
   self->priv->connections.add (conn);
 
-  conn = call_core->established_call.connect (boost::bind (&established_call_cb, _1, _2, (gpointer) self));
+  conn = call_core->established_call.connect (boost::bind (&established_call_cb,
+                                                           _1, _2, (gpointer) self));
   self->priv->connections.add (conn);
 
-  conn = call_core->cleared_call.connect (boost::bind (&cleared_call_cb, _1, _2, _3, (gpointer) self));
+  conn = call_core->cleared_call.connect (boost::bind (&cleared_call_cb,
+                                                       _1, _2, _3, (gpointer) self));
   self->priv->connections.add (conn);
 
   g_signal_connect (self, "popup-menu",
-                    G_CALLBACK (show_popup_menu_cb), self->priv->popup_menu);
+                    G_CALLBACK (show_popup_menu_cb),
+                    self->priv->popup_menu);
 
 #ifdef WIN32
   // hide the popup menu when right-click on the icon
@@ -602,5 +642,8 @@ status_icon_new (Ekiga::ServiceCore & core)
   g_signal_connect (self->priv->chat_window, "unread-count",
                     G_CALLBACK (unread_count_cb), self);
 
+  g_signal_connect (self, "clicked",
+                    G_CALLBACK (status_icon_clicked_cb), self);
+
   return self;
 }
diff --git a/lib/engine/gui/gtk-frontend/statusicon.h b/lib/engine/gui/gtk-frontend/statusicon.h
index ac78bab..38c49dc 100644
--- a/lib/engine/gui/gtk-frontend/statusicon.h
+++ b/lib/engine/gui/gtk-frontend/statusicon.h
@@ -45,6 +45,8 @@
 #include <boost/signals2.hpp>
 #include <boost/bind.hpp>
 
+#include "gtk-frontend.h"
+
 G_BEGIN_DECLS
 
 typedef struct _StatusIcon StatusIcon;
@@ -84,7 +86,7 @@ GType statusicon_get_type ();
 /* DESCRIPTION  : /
  * BEHAVIOR     : Returns a new statusicon, with the default icon and menu
  */
-StatusIcon *status_icon_new (Ekiga::ServiceCore & core);
+StatusIcon *status_icon_new (GmApplication *app);
 
 G_END_DECLS
 
diff --git a/src/dbus-helper/dbus.cpp b/src/dbus-helper/dbus.cpp
index b52b578..bb266c9 100644
--- a/src/dbus-helper/dbus.cpp
+++ b/src/dbus-helper/dbus.cpp
@@ -42,7 +42,6 @@
 
 #include "dbus.h"
 #include "ekiga-settings.h"
-#include "gmcallbacks.h"
 #include "gtk-frontend.h"
 #include "call-core.h"
 
@@ -55,8 +54,9 @@ G_DEFINE_TYPE(EkigaDBusComponent, ekiga_dbus_component, G_TYPE_OBJECT);
 
 struct _EkigaDBusComponentPrivate
 {
+  GmApplication *app;
+
   boost::weak_ptr<Ekiga::CallCore> call_core;
-  boost::weak_ptr<GtkFrontend> gtk_frontend;
   boost::shared_ptr<Ekiga::Settings> personal_data_settings;
 };
 
@@ -102,24 +102,18 @@ ekiga_dbus_component_show (EkigaDBusComponent *self,
                            G_GNUC_UNUSED GError **error)
 {
   PTRACE (1, "DBus\tShow");
-  boost::shared_ptr<GtkFrontend> gtk_frontend = self->priv->gtk_frontend.lock ();
-
-  g_return_val_if_fail (gtk_frontend, FALSE);
 
-  const GtkWidget *window = gtk_frontend->get_main_window ();
-  if (gtk_widget_get_visible (GTK_WIDGET (window)))
-    gtk_window_set_urgency_hint (GTK_WINDOW (window), TRUE);
-  else
-    gtk_window_present (GTK_WINDOW (window));
+  g_return_val_if_fail (self, FALSE);
+  gm_application_show_main_window (self->priv->app);
 
   return TRUE;
 }
 
 static gboolean
-ekiga_dbus_component_shutdown (G_GNUC_UNUSED EkigaDBusComponent *self,
+ekiga_dbus_component_shutdown (EkigaDBusComponent *self,
                                G_GNUC_UNUSED GError **error)
 {
-  quit_callback (NULL, NULL);
+  g_application_quit (G_APPLICATION (self->priv->app));
 
   return TRUE;
 }
@@ -207,12 +201,14 @@ ekiga_dbus_claim_ownership ()
  *       the manager and other key components are running.
  */
 EkigaDBusComponent *
-ekiga_dbus_component_new (Ekiga::ServiceCore& service_core)
+ekiga_dbus_component_new (GmApplication *app)
 {
   DBusGConnection *bus;
   GError *error = NULL;
   EkigaDBusComponent *obj;
 
+  Ekiga::ServiceCorePtr core = gm_application_get_core (app);
+
   bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
   if (!bus) {
     PTRACE (1, "Couldn't connect to session bus : " << error->message);
@@ -221,10 +217,10 @@ ekiga_dbus_component_new (Ekiga::ServiceCore& service_core)
   }
 
   obj = EKIGA_DBUS_COMPONENT (g_object_new (EKIGA_TYPE_DBUS_COMPONENT, NULL));
-  obj->priv->gtk_frontend = service_core.get<GtkFrontend> ("gtk-frontend");
-  obj->priv->call_core = service_core.get<Ekiga::CallCore> ("call-core");
+  obj->priv->call_core = core->get<Ekiga::CallCore> ("call-core");
   obj->priv->personal_data_settings =
     boost::shared_ptr<Ekiga::Settings> (new Ekiga::Settings (PERSONAL_DATA_SCHEMA));
+  obj->priv->app = app;
   dbus_g_connection_register_g_object (bus, EKIGA_DBUS_PATH, G_OBJECT (obj));
 
   return obj;
diff --git a/src/dbus-helper/dbus.h b/src/dbus-helper/dbus.h
index 1480628..0181301 100644
--- a/src/dbus-helper/dbus.h
+++ b/src/dbus-helper/dbus.h
@@ -41,6 +41,8 @@
 #define __DBUS_COMPONENT_H
 
 #include <glib-object.h>
+#include "gtk-frontend.h"
+
 #include "framework/services.h"
 
 G_BEGIN_DECLS
@@ -62,7 +64,7 @@ struct _EkigaDBusComponent {
 typedef GObjectClass EkigaDBusComponentClass;
 
 GType                ekiga_dbus_component_get_type ();
-EkigaDBusComponent  *ekiga_dbus_component_new (Ekiga::ServiceCore& core);
+EkigaDBusComponent  *ekiga_dbus_component_new (GmApplication *app);
 
 gboolean             ekiga_dbus_claim_ownership ();
 
diff --git a/src/main.cpp b/src/main.cpp
index 8ea6409..79651c5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -43,9 +43,6 @@
 
 #include <opal/buildopts.h> // only for OPAL_VERSION!
 
-#ifdef HAVE_DBUS
-#include "dbus-helper/dbus.h"
-#endif
 
 #ifndef WIN32
 #include <signal.h>
@@ -94,8 +91,6 @@ main (int argc,
   g_thread_init();
 #endif
 
-  /* GTK+ initialization */
-  gtk_init (&argc, &argv);
 #ifndef WIN32
   signal (SIGPIPE, SIG_IGN);
 #endif
@@ -169,17 +164,7 @@ main (int argc,
                        | PTrace::Blocks | PTrace::DateAndTime);
 #endif
 
-#ifdef HAVE_DBUS
-  if (!ekiga_dbus_claim_ownership ()) {
-    ekiga_dbus_client_show ();
-    if (url != NULL)
-      ekiga_dbus_client_connect (url);
-    exit (0);
-  }
-#endif
-
   /* Ekiga initialisation */
-  // should come *after* ptrace initialisation, to track codec loading for ex.
   GnomeMeeting instance;
 
   Ekiga::Runtime::init ();
@@ -198,12 +183,10 @@ main (int argc,
   PTRACE (1, "DBUS support disabled");
 #endif
 
-  boost::shared_ptr<GtkFrontend> gtk_frontend
-    = service_core->get<GtkFrontend>("gtk-frontend");
+  std::cout << "FIXME" << std::endl << std::flush;
+  /*
   boost::shared_ptr<Ekiga::Settings> general_settings (new Ekiga::Settings (GENERAL_SCHEMA));
 
-  GtkWidget *main_window = GTK_WIDGET (gtk_frontend->get_main_window ());
-
   const int schema_version = MAJOR_VERSION * 1000
                              + MINOR_VERSION * 10
                              + BUILD_NUMBER;
@@ -212,12 +195,9 @@ main (int argc,
 
     gtk_widget_show_all (GTK_WIDGET (gtk_frontend->build_assistant_window ()));
 
-    /* Update the version number */
     general_settings->set_int ("version", schema_version);
   }
-
-  /* Show the main window */
-  gtk_widget_show (main_window);
+*/
 
   /* Call the given host if needed */
   if (url) {
@@ -226,19 +206,12 @@ main (int argc,
     call_core->dial (url);
   }
 
-#ifdef HAVE_DBUS
-  EkigaDBusComponent *dbus_component = ekiga_dbus_component_new (*service_core);
-#endif
-
   // from now on, things should have taken their final place
   service_core->close ();
 
   /* The GTK loop */
-  gtk_main ();
-
-#ifdef HAVE_DBUS
-  g_object_unref (dbus_component);
-#endif
+  ekiga_main (service_core, argc, argv);
+//  gtk_main ();
 
   /* Exit Ekiga */
   GnomeMeeting::Process ()->Exit ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]