]> git.0d.be Git - empathy.git/commitdiff
Port to libunique
authorCosimo Cecchi <cosimo.cecchi@collabora.co.uk>
Sat, 1 Aug 2009 13:12:42 +0000 (15:12 +0200)
committerCosimo Cecchi <cosimo.cecchi@collabora.co.uk>
Sat, 1 Aug 2009 13:12:42 +0000 (15:12 +0200)
configure.ac
src/Makefile.am
src/bacon-message-connection.c [deleted file]
src/bacon-message-connection.h [deleted file]
src/empathy.c

index 62e08f0a4160706634caaef9778a0af0645212e0..0e11a66d8965add5a4112eea9ada2309ffabfb79 100644 (file)
@@ -126,6 +126,7 @@ PKG_CHECK_MODULES(EMPATHY,
    telepathy-glib >= $TELEPATHY_GLIB_REQUIRED
    telepathy-farsight
    gstreamer-0.10
+   unique-1.0
 ])
 
 PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= $LIBNOTIFY_REQUIRED)
index 50d317fbbdcb097e60b33e9b0bcba34802a9d4a8..01f47d2bb3dd2c71b8aee419d2eec5724a653f9b 100644 (file)
@@ -49,7 +49,6 @@ empathy_handwritten_source = \
 
 empathy_SOURCES =                                                      \
        $(empathy_handwritten_source)                                   \
-       bacon-message-connection.c bacon-message-connection.h           \
        ephy-spinner.c ephy-spinner.h
 
 nodist_empathy_SOURCES = $(BUILT_SOURCES)
diff --git a/src/bacon-message-connection.c b/src/bacon-message-connection.c
deleted file mode 100644 (file)
index c9fda4a..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (C) 2003 Bastien Nocera <hadess@hadess.net>
- *
- * 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.
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Totem project hereby grant permission for non-gpl compatible GStreamer
- * plugins to be used and distributed together with GStreamer and Totem. This
- * permission are above and beyond the permissions granted by the GPL license
- * Totem is covered by.
- *
- * Monday 7th February 2005: Christian Schaller: Add excemption clause.
- * See license_change file for details.
- *
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <errno.h>
-
-#include "bacon-message-connection.h"
-
-#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX 108
-#endif
-
-struct BaconMessageConnection {
-       /* A server accepts connections */
-       gboolean is_server;
-
-       /* The socket path itself */
-       char *path;
-
-       /* File descriptor of the socket */
-       int fd;
-       /* Channel to watch */
-       GIOChannel *chan;
-       /* Event id returned by g_io_add_watch() */
-       int conn_id;
-
-       /* Connections accepted by this connection */
-       GSList *accepted_connections;
-
-       /* callback */
-       void (*func) (const char *message, gpointer user_data);
-       gpointer data;
-};
-
-static gboolean
-test_is_socket (const char *path)
-{
-       struct stat s;
-
-       if (stat (path, &s) == -1)
-               return FALSE;
-
-       if (S_ISSOCK (s.st_mode))
-               return TRUE;
-
-       return FALSE;
-}
-
-static gboolean
-is_owned_by_user_and_socket (const char *path)
-{
-       struct stat s;
-
-       if (stat (path, &s) == -1)
-               return FALSE;
-
-       if (s.st_uid != geteuid ())
-               return FALSE;
-
-       if ((s.st_mode & S_IFSOCK) != S_IFSOCK)
-               return FALSE;
-       
-       return TRUE;
-}
-
-static gboolean server_cb (GIOChannel *source,
-                          GIOCondition condition, gpointer data);
-
-static gboolean
-setup_connection (BaconMessageConnection *conn)
-{
-       int fdflags;
-
-       g_return_val_if_fail (conn->chan == NULL, FALSE);
-
-       /* Add CLOEXEC flag on the fd to make sure the socket get closed
-        * if exec is called. */
-       fdflags = fcntl (conn->fd, F_GETFD, 0);
-       if (fdflags >= 0) {
-               fdflags |= FD_CLOEXEC;
-               fcntl (conn->fd, F_SETFD, fdflags);
-       }
-
-       conn->chan = g_io_channel_unix_new (conn->fd);
-       if (!conn->chan) {
-               return FALSE;
-       }
-       g_io_channel_set_line_term (conn->chan, "\n", 1);
-       conn->conn_id = g_io_add_watch (conn->chan, G_IO_IN, server_cb, conn);
-
-       return TRUE;
-}
-
-static void
-accept_new_connection (BaconMessageConnection *server_conn)
-{
-       BaconMessageConnection *conn;
-       int alen;
-
-       g_return_if_fail (server_conn->is_server);
-
-       conn = g_new0 (BaconMessageConnection, 1);
-       conn->is_server = FALSE;
-       conn->func = server_conn->func;
-       conn->data = server_conn->data;
-
-       conn->fd = accept (server_conn->fd, NULL, (guint *)&alen);
-
-       server_conn->accepted_connections =
-               g_slist_prepend (server_conn->accepted_connections, conn);
-
-       setup_connection (conn);
-}
-
-static gboolean
-server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
-{
-       BaconMessageConnection *conn = (BaconMessageConnection *)data;
-       char *message, *subs, buf;
-       int cd, rc, offset;
-       gboolean finished;
-
-       offset = 0;
-       if (conn->is_server && conn->fd == g_io_channel_unix_get_fd (source)) {
-               accept_new_connection (conn);
-               return TRUE;
-       }
-       message = g_malloc (1);
-       cd = conn->fd;
-       rc = read (cd, &buf, 1);
-       while (rc > 0 && buf != '\n')
-       {
-               message = g_realloc (message, rc + offset + 1);
-               message[offset] = buf;
-               offset = offset + rc;
-               rc = read (cd, &buf, 1);
-       }
-       if (rc <= 0) {
-               g_io_channel_shutdown (conn->chan, FALSE, NULL);
-               g_io_channel_unref (conn->chan);
-               conn->chan = NULL;
-               close (conn->fd);
-               conn->fd = -1;
-               g_free (message);
-               conn->conn_id = 0;
-
-               return FALSE;
-       }
-       message[offset] = '\0';
-
-       subs = message;
-       finished = FALSE;
-
-       while (finished == FALSE && *subs != '\0')
-       {
-               if (conn->func != NULL)
-                       (*conn->func) (subs, conn->data);
-
-               subs += strlen (subs) + 1;
-               if (subs - message >= offset)
-                       finished = TRUE;
-       }
-
-       g_free (message);
-
-       return TRUE;
-}
-
-static char *
-find_file_with_pattern (const char *dir, const char *pattern)
-{
-       GDir *filedir;
-       char *found_filename;
-       const char *filename;
-       GPatternSpec *pat;
-
-       filedir = g_dir_open (dir, 0, NULL);
-       if (filedir == NULL)
-               return NULL;
-
-       pat = g_pattern_spec_new (pattern);
-       if (pat == NULL)
-       {
-               g_dir_close (filedir);
-               return NULL;
-       }
-
-       found_filename = NULL;
-
-       while ((filename = g_dir_read_name (filedir)))
-       {
-               if (g_pattern_match_string (pat, filename))
-               {
-                       char *tmp = g_build_filename (dir, filename, NULL);
-                       if (is_owned_by_user_and_socket (tmp))
-                               found_filename = g_strdup (filename);
-                       g_free (tmp);
-               }
-
-               if (found_filename != NULL)
-                       break;
-       }
-
-       g_pattern_spec_free (pat);
-       g_dir_close (filedir);
-
-       return found_filename;
-}
-
-static char *
-socket_filename (const char *prefix)
-{
-       char *pattern, *newfile, *path, *filename;
-       const char *tmpdir;
-
-       pattern = g_strdup_printf ("%s.%s.*", prefix, g_get_user_name ());
-       tmpdir = g_get_tmp_dir ();
-       filename = find_file_with_pattern (tmpdir, pattern);
-       if (filename == NULL)
-       {
-               newfile = g_strdup_printf ("%s.%s.%u", prefix,
-                               g_get_user_name (), g_random_int ());
-               path = g_build_filename (tmpdir, newfile, NULL);
-               g_free (newfile);
-       } else {
-               path = g_build_filename (tmpdir, filename, NULL);
-               g_free (filename);
-       }
-
-       g_free (pattern);
-       return path;
-}
-
-static gboolean
-try_server (BaconMessageConnection *conn)
-{
-       struct sockaddr_un uaddr;
-
-       uaddr.sun_family = AF_UNIX;
-       strncpy (uaddr.sun_path, conn->path,
-                       MIN (strlen(conn->path)+1, UNIX_PATH_MAX));
-       conn->fd = socket (PF_UNIX, SOCK_STREAM, 0);
-       if (bind (conn->fd, (struct sockaddr *) &uaddr, sizeof (uaddr)) == -1)
-       {
-               conn->fd = -1;
-               return FALSE;
-       }
-       listen (conn->fd, 5);
-
-       return setup_connection (conn);
-}
-
-static gboolean
-try_client (BaconMessageConnection *conn)
-{
-       struct sockaddr_un uaddr;
-
-       uaddr.sun_family = AF_UNIX;
-       strncpy (uaddr.sun_path, conn->path,
-                       MIN(strlen(conn->path)+1, UNIX_PATH_MAX));
-       conn->fd = socket (PF_UNIX, SOCK_STREAM, 0);
-       if (connect (conn->fd, (struct sockaddr *) &uaddr,
-                               sizeof (uaddr)) == -1)
-       {
-               conn->fd = -1;
-               return FALSE;
-       }
-
-       return setup_connection (conn);
-}
-
-BaconMessageConnection *
-bacon_message_connection_new (const char *prefix)
-{
-       BaconMessageConnection *conn;
-
-       g_return_val_if_fail (prefix != NULL, NULL);
-
-       conn = g_new0 (BaconMessageConnection, 1);
-       conn->path = socket_filename (prefix);
-
-       if (test_is_socket (conn->path) == FALSE)
-       {
-               if (!try_server (conn))
-               {
-                       bacon_message_connection_free (conn);
-                       return NULL;
-               }
-
-               conn->is_server = TRUE;
-               return conn;
-       }
-
-       if (try_client (conn) == FALSE)
-       {
-               unlink (conn->path);
-               try_server (conn);
-               if (conn->fd == -1)
-               {
-                       bacon_message_connection_free (conn);
-                       return NULL;
-               }
-
-               conn->is_server = TRUE;
-               return conn;
-       }
-
-       conn->is_server = FALSE;
-       return conn;
-}
-
-void
-bacon_message_connection_free (BaconMessageConnection *conn)
-{
-       GSList *child_conn;
-
-       g_return_if_fail (conn != NULL);
-       /* Only servers can accept other connections */
-       g_return_if_fail (conn->is_server != FALSE ||
-                         conn->accepted_connections == NULL);
-
-       child_conn = conn->accepted_connections;
-       while (child_conn != NULL) {
-               bacon_message_connection_free (child_conn->data);
-               child_conn = g_slist_next (child_conn);
-       }
-       g_slist_free (conn->accepted_connections);
-
-       if (conn->conn_id) {
-               g_source_remove (conn->conn_id);
-               conn->conn_id = 0;
-       }
-       if (conn->chan) {
-               g_io_channel_shutdown (conn->chan, FALSE, NULL);
-               g_io_channel_unref (conn->chan);
-       }
-
-       if (conn->is_server != FALSE) {
-               unlink (conn->path);
-       }
-       if (conn->fd != -1) {
-               close (conn->fd);
-       }
-
-       g_free (conn->path);
-       g_free (conn);
-}
-
-void
-bacon_message_connection_set_callback (BaconMessageConnection *conn,
-                                      BaconMessageReceivedFunc func,
-                                      gpointer user_data)
-{
-       g_return_if_fail (conn != NULL);
-
-       conn->func = func;
-       conn->data = user_data;
-}
-
-void
-bacon_message_connection_send (BaconMessageConnection *conn,
-                              const char *message)
-{
-       g_return_if_fail (conn != NULL);
-       g_return_if_fail (message != NULL);
-
-       g_io_channel_write_chars (conn->chan, message, strlen (message),
-                                 NULL, NULL);
-       g_io_channel_write_chars (conn->chan, "\n", 1, NULL, NULL);
-       g_io_channel_flush (conn->chan, NULL);
-}
-
-gboolean
-bacon_message_connection_get_is_server (BaconMessageConnection *conn)
-{
-       g_return_val_if_fail (conn != NULL, FALSE);
-
-       return conn->is_server;
-}
-
diff --git a/src/bacon-message-connection.h b/src/bacon-message-connection.h
deleted file mode 100644 (file)
index db4a912..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2003 Bastien Nocera <hadess@hadess.net>
- *
- * 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.
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Totem project hereby grant permission for non-gpl compatible GStreamer
- * plugins to be used and distributed together with GStreamer and Totem. This
- * permission are above and beyond the permissions granted by the GPL license
- * Totem is covered by.
- *
- * Monday 7th February 2005: Christian Schaller: Add excemption clause.
- * See license_change file for details.
- *
- */
-
-#ifndef BACON_MESSAGE_CONNECTION_H
-#define BACON_MESSAGE_CONNECTION_H
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef void (*BaconMessageReceivedFunc) (const char *message,
-                                         gpointer user_data);
-
-typedef struct BaconMessageConnection BaconMessageConnection;
-
-BaconMessageConnection *bacon_message_connection_new   (const char *prefix);
-void bacon_message_connection_free                     (BaconMessageConnection *conn);
-void bacon_message_connection_set_callback             (BaconMessageConnection *conn,
-                                                        BaconMessageReceivedFunc func,
-                                                        gpointer user_data);
-void bacon_message_connection_send                     (BaconMessageConnection *conn,
-                                                        const char *message);
-gboolean bacon_message_connection_get_is_server                (BaconMessageConnection *conn);
-
-G_END_DECLS
-
-#endif /* BACON_MESSAGE_CONNECTION_H */
index 63747077371ec08eb60451a70c9b9739f07bd4de..3cc494a94480a19cf4f23e5e7464fa1b26127671 100644 (file)
@@ -30,6 +30,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
+#include <unique/unique.h>
 
 #if HAVE_LIBCHAMPLAIN
 #include <clutter-gtk/gtk-clutter-embed.h>
@@ -68,7 +69,6 @@
 #include "empathy-call-window.h"
 #include "empathy-chat-window.h"
 #include "empathy-ft-manager.h"
-#include "bacon-message-connection.h"
 
 #include "extensions/extensions.h"
 
@@ -77,7 +77,7 @@
 
 #include <gst/gst.h>
 
-static BaconMessageConnection *connection = NULL;
+#define COMMAND_ACCOUNTS_DIALOG 1
 
 static void
 dispatch_cb (EmpathyDispatcher *dispatcher,
@@ -403,85 +403,29 @@ migrate_config_to_xdg_dir (void)
        g_free (old_dir);
 }
 
-/* The code that handles single-instance and startup notification is
- * copied from gedit.
- *
- * Copyright (C) 2005 - Paolo Maggi
- */
-static void
-on_bacon_message_received (const char *message,
-                          gpointer    data)
+static UniqueResponse
+unique_app_message_cb (UniqueApp *unique_app,
+                       gint command,
+                       UniqueMessageData *data,
+                       guint timestamp,
+                       gpointer user_data)
 {
-       GtkWidget *window = data;
-       guint32    startup_timestamp;
-
-       g_return_if_fail (message != NULL);
+       GtkWidget *window = user_data;
 
-       DEBUG ("Other instance launched, presenting the main window. message='%s'",
-               message);
+       DEBUG ("Other instance launched, presenting the main window. "
+              "Command=%d, timestamp %u", command, timestamp);
 
-       if (strcmp (message, "accounts") == 0) {
-               /* accounts dialog requested */
+       if (command == COMMAND_ACCOUNTS_DIALOG) {
                empathy_accounts_dialog_show (GTK_WINDOW (window), NULL);
        } else {
-               startup_timestamp = atoi (message);
-
-               /* Set the proper interaction time on the window.
-                * Fall back to roundtripping to the X server when we
-                * don't have the timestamp, e.g. when launched from
-                * terminal. We also need to make sure that the window
-                * has been realized otherwise it will not work. lame. */
-               if (startup_timestamp == 0) {
-                       /* Work if launched from the terminal */
-                       DEBUG ("Using X server timestamp as a fallback");
-
-                       if (!GTK_WIDGET_REALIZED (window)) {
-                               gtk_widget_realize (GTK_WIDGET (window));
-                       }
-
-                       startup_timestamp = gdk_x11_get_server_time (gtk_widget_get_window (window));
-               }
-
-               gtk_window_present_with_time (GTK_WINDOW (window), startup_timestamp);
+               gtk_window_set_screen (GTK_WINDOW (window),
+                                      unique_message_data_get_screen (data));
+               gtk_window_set_startup_id (GTK_WINDOW (window),
+                                          unique_message_data_get_startup_id (data));
+               gtk_window_present_with_time (GTK_WINDOW (window), timestamp);
        }
-}
-
-static guint32
-get_startup_timestamp ()
-{
-       const gchar *startup_id_env;
-       gchar       *startup_id = NULL;
-       gchar       *time_str;
-       gchar       *end;
-       gulong       retval = 0;
-
-       /* we don't unset the env, since startup-notification
-        * may still need it */
-       startup_id_env = g_getenv ("DESKTOP_STARTUP_ID");
-       if (startup_id_env == NULL) {
-               goto out;
-       }
-
-       startup_id = g_strdup (startup_id_env);
-
-       time_str = g_strrstr (startup_id, "_TIME");
-       if (time_str == NULL) {
-               goto out;
-       }
-
-       errno = 0;
 
-       /* Skip past the "_TIME" part */
-       time_str += 5;
-
-       retval = strtoul (time_str, &end, 0);
-       if (end == time_str || errno != 0)
-               retval = 0;
-
- out:
-       g_free (startup_id);
-
-       return (retval > 0) ? retval : 0;
+       return UNIQUE_RESPONSE_OK;
 }
 
 static gboolean
@@ -579,7 +523,6 @@ account_manager_ready_cb (EmpathyAccountManager *manager,
 int
 main (int argc, char *argv[])
 {
-       guint32            startup_timestamp;
 #if HAVE_GEOCLUE
        EmpathyLocationManager *location_manager = NULL;
 #endif
@@ -598,6 +541,7 @@ main (int argc, char *argv[])
        gboolean           accounts_dialog = FALSE;
        GError            *error = NULL;
        TpDBusDaemon      *dbus_daemon;
+       UniqueApp         *unique_app;
        GOptionEntry       options[] = {
                { "no-connect", 'n',
                  0, G_OPTION_ARG_NONE, &no_connect,
@@ -645,39 +589,20 @@ main (int argc, char *argv[])
        g_log_set_default_handler (default_log_handler, NULL);
 #endif
 
-        /* Setting up the bacon connection */
-       startup_timestamp = get_startup_timestamp ();
-       connection = bacon_message_connection_new ("empathy");
-       if (connection != NULL) {
-               if (!bacon_message_connection_get_is_server (connection)) {
-                       gchar *message;
-
-                       if (accounts_dialog) {
-                               DEBUG ("Showing accounts dialog from existing Empathy instance");
-
-                               message = g_strdup ("accounts");
-
-                       } else {
-
-                               DEBUG ("Activating existing instance");
-
-                               message = g_strdup_printf ("%" G_GUINT32_FORMAT,
-                                                          startup_timestamp);
-                       }
-
-                       bacon_message_connection_send (connection, message);
-
-                       /* We never popup a window, so tell startup-notification
-                        * that we are done. */
-                       gdk_notify_startup_complete ();
-
-                       g_free (message);
-                       bacon_message_connection_free (connection);
-
-                       return EXIT_SUCCESS;
-               }
-       } else {
-               g_warning ("Cannot create the 'empathy' bacon connection.");
+       unique_app = unique_app_new_with_commands ("org.gnome.Empathy",
+                                                  NULL,
+                                                  "accounts_dialog",
+                                                  COMMAND_ACCOUNTS_DIALOG,
+                                                  NULL);
+
+       if (unique_app_is_running (unique_app)) {
+               unique_app_send_message (unique_app,
+                                        accounts_dialog ?
+                                        COMMAND_ACCOUNTS_DIALOG :
+                                                UNIQUE_ACTIVATE,
+                                        NULL);
+               g_object_unref (unique_app);
+               return EXIT_SUCCESS;
        }
 
        /* Take well-known name */
@@ -737,12 +662,9 @@ main (int argc, char *argv[])
        window = empathy_main_window_show ();
        icon = empathy_status_icon_new (GTK_WINDOW (window), hide_contact_list);
 
-       if (connection) {
-               /* We se the callback here because we need window */
-               bacon_message_connection_set_callback (connection,
-                                                      on_bacon_message_received,
-                                                      window);
-       }
+       g_signal_connect (unique_app, "message-received",
+                         G_CALLBACK (unique_app_message_cb),
+                         window);
 
        /* Handle channels */
        dispatcher = empathy_dispatcher_dup_singleton ();
@@ -786,6 +708,7 @@ main (int argc, char *argv[])
        g_object_unref (location_manager);
 #endif
        g_object_unref (ft_factory);
+       g_object_unref (unique_app);
 
        notify_uninit ();