[ekiga/ds-gtk-application] Ekiga: Modified startup sequence and option parsing.
- From: Damien Sandras <dsandras src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ekiga/ds-gtk-application] Ekiga: Modified startup sequence and option parsing.
- Date: Sun, 9 Feb 2014 12:38:15 +0000 (UTC)
commit 286f3fe33e0ec946582fa850b628ae86e6bbd81b
Author: Damien Sandras <dsandras beip be>
Date: Sun Feb 9 13:17:50 2014 +0100
Ekiga: Modified startup sequence and option parsing.
Much of the startup code has been moved to GtkApplication. Options
parsing has been moved there too. --version and --hangup are two new
possible options that can be invoked locally or through a remote
instance.
lib/engine/gui/gtk-frontend/ekiga-app.cpp | 211 +++++++++++++++++++++++++---
lib/engine/gui/gtk-frontend/ekiga-app.h | 8 +-
src/main.cpp | 50 +-------
3 files changed, 194 insertions(+), 75 deletions(-)
---
diff --git a/lib/engine/gui/gtk-frontend/ekiga-app.cpp b/lib/engine/gui/gtk-frontend/ekiga-app.cpp
index b40923d..79face8 100644
--- a/lib/engine/gui/gtk-frontend/ekiga-app.cpp
+++ b/lib/engine/gui/gtk-frontend/ekiga-app.cpp
@@ -66,6 +66,8 @@
#include "videoinput-core.h"
#include "videooutput-core.h"
#include "call-core.h"
+#include "engine.h"
+#include "runtime.h"
#include "gmwindow.h"
@@ -99,8 +101,32 @@ struct _GmApplicationPrivate
G_DEFINE_TYPE (GmApplication, gm_application, GTK_TYPE_APPLICATION);
-
/* Private helpers */
+static gboolean
+option_context_parse (GOptionContext *context,
+ gchar **arguments,
+ GError **error)
+{
+ gint argc;
+ gchar **argv;
+ gint i;
+ gboolean ret;
+
+ /* 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.
+ */
+ argc = g_strv_length (arguments);
+ argv = g_new (gchar *, argc);
+ for (i = 0; i < argc; i++)
+ argv[i] = arguments[i];
+
+ ret = g_option_context_parse (context, &argc, &argv, error);
+
+ g_free (argv);
+
+ return ret;
+}
+
static void
quit_activated (G_GNUC_UNUSED GSimpleAction *action,
G_GNUC_UNUSED GVariant *parameter,
@@ -137,6 +163,8 @@ window_activated (GSimpleAction *action,
GtkWindow *window = NULL;
GmWindow *parent = NULL;
+ g_return_if_fail (self && self->priv->core);
+
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
boost::shared_ptr<Ekiga::AudioInputCore> audio_input_core =
@@ -181,19 +209,24 @@ static GActionEntry app_entries[] =
/* Public api */
void
-ekiga_main (Ekiga::ServiceCorePtr core,
- int argc,
+ekiga_main (int argc,
char **argv)
{
- GmApplication *app = NULL;
-
- app = gm_application_new (core);
+ GmApplication *app = gm_application_new ();
+ g_application_set_inactivity_timeout (G_APPLICATION (app), 10000);
if (g_application_get_is_remote (G_APPLICATION (app))) {
- std::cout << "FIXME Remote" << std::endl << std::flush;
+ g_application_run (G_APPLICATION (app), argc, argv);
return;
}
+ Ekiga::ServiceCorePtr core(new Ekiga::ServiceCore);
+
+ Ekiga::Runtime::init ();
+ engine_init (core, argc, argv);
+
+ gm_application_set_core (app, core);
+
app->priv->main_window = gm_main_window_new (app);
gm_application_show_main_window (app);
@@ -204,7 +237,9 @@ ekiga_main (Ekiga::ServiceCorePtr core,
app->priv->dbus_component = ekiga_dbus_component_new (app);
#endif
+ core->close ();
g_application_run (G_APPLICATION (app), argc, argv);
+
g_object_unref (app);
}
@@ -214,7 +249,8 @@ static void
gm_application_activate (GApplication *self)
{
GmApplication *app = GM_APPLICATION (self);
- std::cout << "activate" << std::endl << std::flush;
+
+ gm_application_show_main_window (app);
}
static void
@@ -301,25 +337,147 @@ gm_application_dispose (GObject *obj)
static void
+gm_application_shutdown (GApplication *app)
+{
+ GmApplication *self = GM_APPLICATION (app);
+
+ g_return_if_fail (self);
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
+ PThread::Current()->Sleep (2000); // FIXME, This allows all threads to start and quit. Sucks.
+
+ gtk_widget_hide (GTK_WIDGET (self->priv->main_window));
+
+ self->priv->core.reset ();
+ Ekiga::Runtime::quit ();
+
+ G_APPLICATION_CLASS (gm_application_parent_class)->shutdown (app);
+}
+
+static gint
+gm_application_command_line (GApplication *app,
+ GApplicationCommandLine *cl)
+{
+ gchar **arguments = NULL;
+ GOptionContext *context = NULL;
+ GError *error = NULL;
+
+ GmApplication *self = GM_APPLICATION (app);
+
+ g_return_val_if_fail (self && self->priv->core, -1);
+
+ static gchar *url = NULL;
+ static int debug_level = 0;
+ static gboolean hangup = FALSE;
+ static gboolean help = FALSE;
+ static gboolean version = FALSE;
+
+ static GOptionEntry options [] =
+ {
+ {
+ "help", '?', 0, G_OPTION_ARG_NONE, &help,
+ N_("Show the application's help"), NULL
+ },
+
+ /* Version */
+ {
+ "version", 'V', 0, G_OPTION_ARG_NONE, &version,
+ N_("Show the application's version"), NULL
+ },
+ {
+ "debug", 'd', 0, G_OPTION_ARG_INT, &debug_level,
+ N_("Prints debug messages in the console (level between 1 and 8)"),
+ NULL
+ },
+ {
+ "call", 'c', 0, G_OPTION_ARG_STRING, &url,
+ N_("Makes Ekiga call the given URI"),
+ NULL
+ },
+ {
+ "hangup", '\0', 0, G_OPTION_ARG_NONE, &hangup,
+ N_("Hangup the current call (if any)"),
+ NULL
+ },
+ {
+ NULL, 0, 0, (GOptionArg)0, NULL,
+ NULL,
+ NULL
+ }
+ };
+
+ self->priv =
+ G_TYPE_INSTANCE_GET_PRIVATE (self,
+ GM_TYPE_APPLICATION,
+ GmApplicationPrivate);
+
+ context = g_option_context_new (NULL);
+ g_option_context_add_main_entries (context, options, PACKAGE_NAME);
+ g_option_context_add_group (context, gtk_get_option_group (FALSE));
+
+ arguments = g_application_command_line_get_arguments (cl, NULL);
+
+ /* Avoid exit() on the main instance */
+ g_option_context_set_help_enabled (context, FALSE);
+
+ if (!option_context_parse (context, arguments, &error)) {
+ /* We should never get here since parsing would have
+ * failed on the client side... */
+ g_application_command_line_printerr (cl,
+ _("%s\nRun '%s --help' to see a full list of available command line
options.\n"),
+ error->message, arguments[0]);
+
+ g_error_free (error);
+ g_application_command_line_set_exit_status (cl, 1);
+ g_application_quit (app);
+ }
+ else if (url) {
+ boost::shared_ptr<Ekiga::CallCore> call_core =
+ self->priv->core->get<Ekiga::CallCore> ("call-core");
+ call_core->dial (url);
+ }
+ else if (hangup) {
+ boost::shared_ptr<Ekiga::CallCore> call_core =
+ self->priv->core->get<Ekiga::CallCore> ("call-core");
+ call_core->hang_up ();
+ }
+ else if (version) {
+ g_print ("%s - Version %d.%d.%d\n",
+ g_get_application_name (),
+ MAJOR_VERSION, MINOR_VERSION, BUILD_NUMBER);
+ g_application_quit (app);
+ }
+ else if (help) {
+ g_print (g_option_context_get_help (context, TRUE, NULL));
+ g_application_quit (app);
+ }
+
+ g_strfreev (arguments);
+ g_option_context_free (context);
+
+ g_application_activate (app);
+
+ g_free (url);
+ url = NULL;
+ hangup = FALSE;
+ version = FALSE;
+ help = FALSE;
+
+ return 0;
+}
+
+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;
-
-// 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;
+ app_class->command_line = gm_application_command_line;
+ app_class->shutdown = gm_application_shutdown;
g_type_class_add_private (object_class, sizeof (GmApplicationPrivate));
}
@@ -333,19 +491,27 @@ gm_application_init (GmApplication *self)
GmApplication *
-gm_application_new (Ekiga::ServiceCorePtr core)
+gm_application_new ()
{
GmApplication *self =
GM_APPLICATION (g_object_new (GM_TYPE_APPLICATION,
"application-id", "org.gnome.Ekiga",
- "flags", G_APPLICATION_FLAGS_NONE,
+ "flags", G_APPLICATION_HANDLES_COMMAND_LINE,
NULL));
g_application_register (G_APPLICATION (self), NULL, NULL);
+ return self;
+}
+
+
+void
+gm_application_set_core (GmApplication *self,
+ Ekiga::ServiceCorePtr core)
+{
+ g_return_if_fail (GM_IS_APPLICATION (self));
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GM_TYPE_APPLICATION, GmApplicationPrivate);
- self->priv->core = core;
- return self;
+ self->priv->core = core;
}
@@ -577,7 +743,6 @@ gm_application_show_chat_window (GmApplication *self)
// 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));
}
diff --git a/lib/engine/gui/gtk-frontend/ekiga-app.h b/lib/engine/gui/gtk-frontend/ekiga-app.h
index 21f0cc2..a38393c 100644
--- a/lib/engine/gui/gtk-frontend/ekiga-app.h
+++ b/lib/engine/gui/gtk-frontend/ekiga-app.h
@@ -64,11 +64,13 @@ struct _GmApplicationClass
};
-void ekiga_main (Ekiga::ServiceCorePtr core,
- int argc,
+void ekiga_main (int argc,
char **argv);
-GmApplication *gm_application_new (Ekiga::ServiceCorePtr core);
+GmApplication *gm_application_new ();
+
+void gm_application_set_core (GmApplication *app,
+ Ekiga::ServiceCorePtr core);
Ekiga::ServiceCorePtr gm_application_get_core (GmApplication *app);
diff --git a/src/main.cpp b/src/main.cpp
index 0c6e95b..b54ee96 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -74,10 +74,6 @@ main (int argc,
char ** argv,
char ** /*envp*/)
{
- GOptionContext *context = NULL;
-
- Ekiga::ServiceCorePtr service_core(new Ekiga::ServiceCore);
-
gchar *path = NULL;
gchar *url = NULL;
@@ -116,32 +112,6 @@ main (int argc,
setenv ("PA_PROP_MEDIA_ROLE", "phone", true);
#endif
- /* Arguments initialization */
- GOptionEntry arguments [] =
- {
- {
- "debug", 'd', 0, G_OPTION_ARG_INT, &debug_level,
- N_("Prints debug messages in the console (level between 1 and 8)"),
- NULL
- },
- {
- "call", 'c', 0, G_OPTION_ARG_STRING, &url,
- N_("Makes Ekiga call the given URI"),
- NULL
- },
- {
- NULL, 0, 0, (GOptionArg)0, NULL,
- NULL,
- NULL
- }
- };
- context = g_option_context_new (NULL);
- g_option_context_add_main_entries (context, arguments, PACKAGE_NAME);
- g_option_context_set_help_enabled (context, TRUE);
-
- g_option_context_add_group (context, gtk_get_option_group (TRUE));
- g_option_context_parse (context, &argc, &argv, NULL);
- g_option_context_free (context);
#ifndef WIN32
char* text_label = g_strdup_printf ("%d", debug_level);
@@ -165,8 +135,6 @@ main (int argc,
| PTrace::Blocks | PTrace::DateAndTime);
#endif
- Ekiga::Runtime::init ();
- engine_init (service_core, argc, argv);
PTRACE (1, "Ekiga version "
<< MAJOR_VERSION << "." << MINOR_VERSION << "." << BUILD_NUMBER);
@@ -197,23 +165,7 @@ main (int argc,
}
*/
- /* Call the given host if needed */
- if (url) {
-
- boost::shared_ptr<Ekiga::CallCore> call_core = service_core->get<Ekiga::CallCore> ("call-core");
- call_core->dial (url);
- }
-
- // from now on, things should have taken their final place
- service_core->close ();
-
- /* The GTK loop */
- ekiga_main (service_core, argc, argv);
-// gtk_main ();
-
- /* Exit Ekiga */
- service_core.reset ();
- Ekiga::Runtime::quit ();
+ ekiga_main (argc, argv);
/* deinitialize platform-specific code */
gm_platform_shutdown ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]