[gnac/libunique] Added libunique support (trac ticket #39)



commit 21bc3673527ab75dc913123f7de198dbb92418d4
Author: Benoît Dupasquier <bdupasqu src gnome org>
Date:   Fri May 28 14:11:41 2010 +0100

    Added libunique support (trac ticket #39)

 configure.ac       |    6 +++
 src/Makefile.am    |    2 +
 src/gnac-main.c    |    2 +
 src/gnac-options.c |   56 +++++++++++++++--------
 src/gnac-options.h |    9 ++++
 src/gnac-ui.c      |  126 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/gnac-ui.h      |    5 ++
 src/gnac-utils.c   |   32 +++++++++++++
 src/gnac-utils.h   |    4 ++
 9 files changed, 219 insertions(+), 23 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 5e67311..47ef420 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,6 +91,12 @@ PKG_CHECK_MODULES(UI, [
 AC_SUBST(UI_CFLAGS)
 AC_SUBST(UI_LIBS)
 
+PKG_CHECK_MODULES(UNIQUE, [
+  unique-1.0
+])
+AC_SUBST(UNIQUE_CFLAGS)
+AC_SUBST(UNIQUE_LIBS)
+
 dnl Find the Gstreamer libraries
 PKG_CHECK_MODULES(GSTREAMER, [
   gstreamer-0.10 >= 0.10.20
diff --git a/src/Makefile.am b/src/Makefile.am
index 1d1b127..92c5c14 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -70,6 +70,7 @@ gnac_CPPFLAGS = \
 gnac_CFLAGS = \
 	$(GLIB_CFLAGS) \
 	$(UI_CFLAGS) \
+	$(UNIQUE_CFLAGS) \
 	$(GSTREAMER_CFLAGS) \
 	$(WARN_CFLAGS) \
 	$(AM_CFLAGS) \
@@ -79,6 +80,7 @@ gnac_LDADD = \
 	$(top_builddir)/libgnac/libgnac.la \
 	$(GLIB_LIBS) \
 	$(UI_LIBS) \
+	$(UNIQUE_LIBS) \
 	$(GSTREAMER_LIBS)
 
 gnac_LDFLAGS = \
diff --git a/src/gnac-main.c b/src/gnac-main.c
index ce0d211..d8e625d 100644
--- a/src/gnac-main.c
+++ b/src/gnac-main.c
@@ -1213,6 +1213,8 @@ main(gint    argc,
   /* Initialisation of libraries */
   gdk_threads_init();
 
+  gnac_ui_init_unique(&options);
+
   conversion_errors = FALSE;
   prev_time_left = -1;
   gnac_utils_moving_avg_init();
diff --git a/src/gnac-options.c b/src/gnac-options.c
index 334d2fd..a8793d4 100644
--- a/src/gnac-options.c
+++ b/src/gnac-options.c
@@ -52,10 +52,6 @@ gnac_options_version_cb(const gchar  *option_name,
                         gpointer      data,
                         GError      **error);
 
-static void
-gnac_options_process_filenames(void);
-
-
 GnacCmdLineOptions options;
 
 const GOptionEntry all_options[] = {
@@ -85,8 +81,7 @@ gnac_options_debug_cb(const gchar  *option_name,
                       gpointer      data,
                       GError      **error)
 {
-  LIBGNAC_DEBUG = TRUE;
-  return gnac_options_verbose_cb(option_name, value, data, error);
+  return gnac_options_enable_debug();
 }
 
 
@@ -96,8 +91,7 @@ gnac_options_verbose_cb(const gchar  *option_name,
                         gpointer      data,
                         GError      **error)
 {
-  LIBGNAC_VERBOSE = TRUE;
-  return TRUE;
+  return gnac_options_enable_verbose();
 }
 
 
@@ -112,22 +106,23 @@ gnac_options_version_cb(const gchar  *option_name,
 }
 
 
-static void
-gnac_options_process_filenames(void)
+void
+gnac_options_process_filenames(gchar **filenames)
 {
   GSList *list_files = NULL; 
-  if (options.filenames)
-  {
-    gint i, len;
-    GFile  *uri;
-    len = g_strv_length(options.filenames);
-    for (i = 0; i < len; i++)
-    {
-      uri = g_file_new_for_commandline_arg(options.filenames[i]);
+
+  if (filenames) {
+    gint   i, len;
+    GFile *uri;
+
+    len = g_strv_length(filenames);
+
+    for (i = 0; i < len; i++) {
+      uri = g_file_new_for_commandline_arg(filenames[i]);
       list_files = g_slist_append(list_files, uri);
     }
+
     gnac_add_files(list_files);
-    g_strfreev(options.filenames);
   }
 }
 
@@ -163,5 +158,26 @@ gnac_options_init(gint    argc,
 void
 gnac_options_process_late(void)
 {
-  gnac_options_process_filenames();
+  gnac_options_process_filenames(options.filenames);
+  g_strfreev(options.filenames);
+}
+
+
+gboolean
+gnac_options_enable_verbose(void)
+{
+  gboolean enable = TRUE;
+  LIBGNAC_VERBOSE = enable;
+  options.verbose = enable;
+  return enable;
+}
+
+
+gboolean
+gnac_options_enable_debug(void)
+{
+  gboolean enable = TRUE;
+  LIBGNAC_DEBUG = enable;
+  options.debug = enable;
+  return gnac_options_enable_verbose();
 }
diff --git a/src/gnac-options.h b/src/gnac-options.h
index 0fc99f3..2d61a62 100644
--- a/src/gnac-options.h
+++ b/src/gnac-options.h
@@ -48,6 +48,15 @@ gnac_options_init(gint    argc,
 void 
 gnac_options_process_late(void);
 
+void
+gnac_options_process_filenames(gchar **filenames);
+
+gboolean
+gnac_options_enable_verbose(void);
+
+gboolean
+gnac_options_enable_debug(void);
+
 G_END_DECLS
 
 #endif /* GNAC_OPTIONS_H */
diff --git a/src/gnac-ui.c b/src/gnac-ui.c
index 7e17ee2..74be15f 100644
--- a/src/gnac-ui.c
+++ b/src/gnac-ui.c
@@ -29,6 +29,7 @@
 
 #include <glib/gi18n.h>
 #include <glib/gprintf.h>
+#include <unique/unique.h>
 
 #include "gnac-bars.h"
 #include "gnac-file-list.h"
@@ -37,16 +38,19 @@
 #include "gnac-ui.h"
 #include "gnac-utils.h"
 #include "gnac-gconf.h"
+#include "libgnac-debug.h"
 #include "profiles/gnac-profiles.h"
 
+extern GnacState state;
+extern guint nb_files_added;
 extern LibgnacMetadata *metadata;
 
 static GtkBuilder     *gnac_main_builder = NULL;
 static GtkStatusIcon  *trayicon = NULL;
+static UniqueApp      *app;
 static gchar          *status_msg = NULL;
 static gchar          *tooltip_path = NULL;
 static gchar          *progress_msg = NULL;
-extern guint           nb_files_added;
 
 static gint root_x;
 static gint root_y;
@@ -60,8 +64,12 @@ static GtkTargetEntry target_list[] =  {
 
 static guint n_targets = G_N_ELEMENTS(target_list);
 
-extern GnacState state;
-
+enum {
+  UNIQUE_CMD_0, /* unused: 0 is an invalid command */
+  UNIQUE_CMD_ADD,
+  UNIQUE_CMD_DEBUG,
+  UNIQUE_CMD_VERBOSE
+};
 
 static void
 gnac_about_url_hook(GtkAboutDialog *dialog,
@@ -319,6 +327,117 @@ gnac_ui_get_action(const gchar *widget_name)
 }
 
 
+static UniqueResponse
+gnac_ui_message_received_cb(UniqueApp         *app,
+                            gint               command,
+                            UniqueMessageData *message,
+                            guint              time,
+                            gpointer           user_data)
+{
+  GtkWindow *main_window;
+
+  main_window = GTK_WINDOW(gtk_builder_get_object(gnac_main_builder,
+      "main_window"));
+
+  switch (command)
+  {
+    case UNIQUE_ACTIVATE:
+      gtk_window_set_screen(main_window,
+          unique_message_data_get_screen(message));
+      gtk_window_present_with_time(main_window, time);
+    break;
+
+    case UNIQUE_CMD_ADD: {
+      gchar **filenames;
+      filenames = unique_message_data_get_uris(message);
+      gnac_options_process_filenames(filenames);
+      g_strfreev(filenames);
+      break;
+    }
+
+    case UNIQUE_CMD_DEBUG:
+      g_print(_("Debug mode activated\n"));
+      gnac_options_enable_debug();
+      break;
+
+    case UNIQUE_CMD_VERBOSE:
+      g_print(_("Verbose mode activated\n"));
+      gnac_options_enable_verbose();
+      break;
+
+    default:
+      g_printerr("Received unknown libunique command: %d\n", command);
+      break;
+  }
+
+  return UNIQUE_RESPONSE_OK;
+}
+
+
+void
+gnac_ui_init_unique(GnacCmdLineOptions *options)
+{
+  /* We only want a single instance of gnac to be running */
+  app = unique_app_new_with_commands("org.gnome.Gnac", NULL,
+      "add-files", UNIQUE_CMD_ADD,
+      "debug"    , UNIQUE_CMD_DEBUG,
+      "verbose"  , UNIQUE_CMD_VERBOSE,
+      NULL);
+  g_signal_connect(app, "message-received",
+      G_CALLBACK(gnac_ui_message_received_cb), NULL);
+
+  if (unique_app_is_running(app)) {
+    g_print(_("An instance of Gnac is already running\n"));
+
+    UniqueResponse response;
+
+    /* Give the focus to the running instance */
+    response = unique_app_send_message(app, UNIQUE_ACTIVATE, NULL);
+
+    /* Transmit the debug option */
+    if (options->debug) {
+      response = unique_app_send_message(app, UNIQUE_CMD_DEBUG, NULL);
+      if (response != UNIQUE_RESPONSE_OK) {
+        g_printerr(_("Failed to transmit the debug option\n"));
+      }
+    }
+
+    /* Transmit the verbose option */
+    if (options->verbose) {
+      response = unique_app_send_message(app, UNIQUE_CMD_VERBOSE, NULL);
+      if (response != UNIQUE_RESPONSE_OK) {
+        g_printerr(_("Failed to transmit the verbose option\n"));
+      }
+    }
+
+    /* Transmit filenames */
+    if (options->filenames) {
+      gchar **uris;
+      UniqueMessageData *message;
+
+      message = unique_message_data_new();
+      uris = gnac_utils_get_filenames_from_cmd_line(options->filenames);
+      g_strfreev(options->filenames);
+      if (!unique_message_data_set_uris(message, uris)) {
+        g_printerr(_("Failed to convert some uris\n"));
+      }
+      g_strfreev(uris);
+      response = unique_app_send_message(app, UNIQUE_CMD_ADD, message);
+      unique_message_data_free(message);
+      if (response != UNIQUE_RESPONSE_OK) {
+        g_printerr(_("Failed to transmit filenames\n"));
+      } else {
+        g_print(_("Filenames transmitted to the running instance\n"));
+      }
+    }
+
+    g_object_unref(app);
+
+    exit(response == UNIQUE_RESPONSE_OK);
+  }
+}
+
+
 void 
 gnac_ui_show(void)
 {
@@ -334,6 +453,7 @@ gnac_ui_show(void)
     gtk_builder_get_object(gnac_main_builder, "progressbar"));
 
   main_window = GTK_WIDGET(gtk_builder_get_object(gnac_main_builder, "main_window"));
+  unique_app_watch_window(app, GTK_WINDOW(main_window));
   gtk_widget_show_all(main_window);
   gnac_ui_show_progress(FALSE);
   gnac_ui_show_pause(FALSE);
diff --git a/src/gnac-ui.h b/src/gnac-ui.h
index fa0831a..09144a4 100644
--- a/src/gnac-ui.h
+++ b/src/gnac-ui.h
@@ -30,6 +30,8 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
+#include "gnac-options.h"
+
 G_BEGIN_DECLS
 
 enum {
@@ -67,6 +69,9 @@ void
 gnac_ui_show_about_dialog(void);
 
 void
+gnac_ui_init_unique(GnacCmdLineOptions *options);
+
+void
 gnac_ui_new(void);
 
 GtkWidget *
diff --git a/src/gnac-utils.c b/src/gnac-utils.c
index f0887b4..1ad36e2 100644
--- a/src/gnac-utils.c
+++ b/src/gnac-utils.c
@@ -180,3 +180,35 @@ gnac_utils_add_border_to_pixbuf(GdkPixbuf *pixbuf)
             GNAC_UTILS_ICON_BORDER_WIDTH, GNAC_UTILS_ICON_BORDER_WIDTH);
   return bordered;
 }
+
+
+/*
+ * The returned value must be freed using g_strfreev()
+ */
+gchar **
+gnac_utils_get_filenames_from_cmd_line(gchar **argv)
+{
+  GPtrArray *array;
+
+  array = g_ptr_array_new();
+
+  if (argv) {
+    gint i;
+
+    for (i = 0; argv[i]; i++) {
+      GFile *file;
+
+      file = g_file_new_for_commandline_arg(argv[i]);
+      if (file) {
+        g_ptr_array_add(array, g_file_get_uri(file));
+        g_object_unref(file);
+      } else {
+        g_printerr("Invalid file name: %s\n", argv[i]);
+      }
+    }
+  }
+
+  g_ptr_array_add(array, NULL);
+
+  return (gchar**) g_ptr_array_free(array, FALSE);
+}
diff --git a/src/gnac-utils.h b/src/gnac-utils.h
index 1a1ed29..775c37f 100644
--- a/src/gnac-utils.h
+++ b/src/gnac-utils.h
@@ -59,6 +59,10 @@ gnac_utils_scale_pixbuf(GdkPixbuf *pixbuf,
 GdkPixbuf *
 gnac_utils_add_border_to_pixbuf(GdkPixbuf *pixbuf);
 
+/* The returned value must be freed using g_strfreev() */
+gchar **
+gnac_utils_get_filenames_from_cmd_line(gchar **argv);
+
 G_END_DECLS
 
 #endif /* GNAC_UTILS_H */



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