aboutsummaryrefslogtreecommitdiffstats
path: root/shell/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/main.c')
-rw-r--r--shell/main.c468
1 files changed, 167 insertions, 301 deletions
diff --git a/shell/main.c b/shell/main.c
index 21cc278c7f..72333c17f7 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -23,6 +23,7 @@
#include <config.h>
#include <gtk/gtk.h>
+#include <gdk/gdkx.h> /* for copied UniqueApp code */
#include <glib/gstdio.h>
#ifdef G_OS_WIN32
@@ -40,12 +41,10 @@
#include "e-util/e-bconf-map.h"
#include <e-util/e-icon-factory.h>
-#include "e-shell-constants.h"
#include "e-util/e-profile-event.h"
#include "e-util/e-util.h"
#include "e-shell.h"
-#include "es-menu.h"
#include "es-event.h"
#include "e-util/e-util-private.h"
@@ -57,22 +56,13 @@
#include <gconf/gconf-client.h>
#include <glib/gi18n.h>
-#include <libgnome/gnome-sound.h>
-#include <libgnomeui/gnome-ui-init.h>
-#include <libgnomeui/gnome-client.h>
-
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <bonobo/bonobo-exception.h>
-
-#include <bonobo-activation/bonobo-activation.h>
+#include <libedataserver/e-categories.h>
#include <libedataserverui/e-passwords.h>
#include <glade/glade.h>
#include "e-config-upgrade.h"
-#include "Evolution-DataServer.h"
#include <misc/e-cursors.h>
#include "e-util/e-error.h"
@@ -98,13 +88,11 @@
#define DEVELOPMENT 1
#endif
-static EShell *shell = NULL;
-
/* Command-line options. */
static gboolean start_online = FALSE;
static gboolean start_offline = FALSE;
static gboolean setup_only = FALSE;
-static gboolean killev = FALSE;
+static gboolean force_shutdown = FALSE;
#ifdef DEVELOPMENT
static gboolean force_migrate = FALSE;
#endif
@@ -112,84 +100,43 @@ static gboolean disable_eplugin = FALSE;
static gboolean disable_preview = FALSE;
static gboolean idle_cb (gchar **uris);
-static gchar *default_component_id = NULL;
+static gchar *requested_view = NULL;
static gchar *evolution_debug_log = NULL;
static gchar **remaining_args;
-static void
-no_windows_left_cb (EShell *shell, gpointer data)
-{
- bonobo_object_unref (BONOBO_OBJECT (shell));
- bonobo_main_quit ();
-}
-
-static void
-shell_weak_notify (gpointer data,
- GObject *where_the_object_was)
-{
- bonobo_main_quit ();
-}
-
-#ifdef KILL_PROCESS_CMD
+/* Defined in <e-shell.h> */
+extern EShell *default_shell;
static void
-kill_dataserver (void)
+categories_icon_theme_hack (void)
{
- g_message ("Killing old version of evolution-data-server...");
-
- system (KILL_PROCESS_CMD " -9 lt-evolution-data-server 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.0 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.2 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.4 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.6 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.8 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.10 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.12 2> /dev/null");
-
- system (KILL_PROCESS_CMD " -9 lt-evolution-alarm-notify 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-alarm-notify 2> /dev/null");
+ GtkIconTheme *icon_theme;
+ const gchar *category_name;
+ const gchar *filename;
+ gchar *dirname;
+
+ /* XXX Allow the category icons to be referenced as named
+ * icons, since GtkAction does not support GdkPixbufs. */
+
+ /* Get the icon file for some default category. Doesn't matter
+ * which, so long as it has an icon. We're just interested in
+ * the directory components. */
+ category_name = _("Birthday");
+ filename = e_categories_get_icon_file_for (category_name);
+ g_return_if_fail (filename != NULL && *filename != '\0');
+
+ /* Extract the directory components. */
+ dirname = g_path_get_dirname (filename);
+
+ /* Add it to the icon theme's search path. This relies on
+ * GtkIconTheme's legacy feature of using image files found
+ * directly in the search path. */
+ icon_theme = gtk_icon_theme_get_default ();
+ gtk_icon_theme_append_search_path (icon_theme, dirname);
+
+ g_free (dirname);
}
-static void
-kill_old_dataserver (void)
-{
- GNOME_Evolution_DataServer_InterfaceCheck iface;
- CORBA_Environment ev;
- CORBA_char *version;
-
- CORBA_exception_init (&ev);
-
- /* FIXME Should we really kill it off? We also shouldn't hard code the version */
- iface = bonobo_activation_activate_from_id (
- (Bonobo_ActivationID) "OAFIID:GNOME_Evolution_DataServer_InterfaceCheck", 0, NULL, &ev);
- if (BONOBO_EX (&ev) || iface == CORBA_OBJECT_NIL) {
- kill_dataserver ();
- CORBA_exception_free (&ev);
- return;
- }
-
- version = GNOME_Evolution_DataServer_InterfaceCheck__get_interfaceVersion (iface, &ev);
- if (BONOBO_EX (&ev)) {
- kill_dataserver ();
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
- return;
- }
-
- if (strcmp (version, DATASERVER_VERSION) != 0) {
- CORBA_free (version);
- kill_dataserver ();
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_free (version);
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
-}
-#endif
-
#ifdef DEVELOPMENT
/* Warning dialog to scare people off a little bit. */
@@ -269,8 +216,6 @@ show_development_warning(void)
gtk_widget_destroy (warning_dialog);
- idle_cb (NULL);
-
return skip;
}
@@ -291,124 +236,26 @@ destroy_config (GConfClient *client)
#endif /* DEVELOPMENT */
-static void
-open_uris (GNOME_Evolution_Shell corba_shell, gchar **uris)
-{
- CORBA_Environment ev;
- guint n_uris, ii;
-
- g_return_if_fail (uris != NULL);
- n_uris = g_strv_length (uris);
-
- CORBA_exception_init (&ev);
-
- for (ii = 0; ii < n_uris; ii++) {
- GNOME_Evolution_Shell_handleURI (corba_shell, uris[ii], &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Invalid URI: %s", uris[ii]);
- CORBA_exception_free (&ev);
- }
- }
-
- CORBA_exception_free (&ev);
-}
-
/* This is for doing stuff that requires the GTK+ loop to be running already. */
static gboolean
idle_cb (gchar **uris)
{
- GNOME_Evolution_Shell corba_shell;
- CORBA_Environment ev;
- EShellConstructResult result;
- EShellStartupLineMode startup_line_mode;
-
- g_return_val_if_fail (uris == NULL || g_strv_length (uris) > 0, FALSE);
-
-#ifdef KILL_PROCESS_CMD
- kill_old_dataserver ();
-#endif
+ EShell *shell;
- CORBA_exception_init (&ev);
-
- if (! start_online && ! start_offline)
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_CONFIG;
- else if (start_online)
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_ONLINE;
- else
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_OFFLINE;
-
- shell = e_shell_new (startup_line_mode, &result);
-
- switch (result) {
- case E_SHELL_CONSTRUCT_RESULT_OK:
- e_shell_set_crash_recovery (shell, e_file_lock_exists ());
- g_signal_connect (shell, "no_windows_left", G_CALLBACK (no_windows_left_cb), NULL);
- g_object_weak_ref (G_OBJECT (shell), shell_weak_notify, NULL);
- corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell));
- corba_shell = CORBA_Object_duplicate (corba_shell, &ev);
- break;
-
- case E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER:
- corba_shell = bonobo_activation_activate_from_id (
- (Bonobo_ActivationID) E_SHELL_OAFIID, 0, NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION || corba_shell == CORBA_OBJECT_NIL) {
- e_error_run(NULL, "shell:noshell", NULL);
- CORBA_exception_free (&ev);
- bonobo_main_quit ();
- return FALSE;
- }
- break;
+ shell = e_shell_get_default ();
- default:
- e_error_run(NULL, "shell:noshell-reason",
- e_shell_construct_result_to_string(result), NULL);
- CORBA_exception_free (&ev);
- bonobo_main_quit ();
- return FALSE;
+ /* These calls do the right thing when another Evolution
+ * process is running. */
+ if (uris != NULL && *uris != NULL) {
+ if (e_shell_handle_uris (shell, uris) == 0)
+ gtk_main_quit ();
+ } else
+ e_shell_create_shell_window (shell, requested_view);
- }
-
- if (shell != NULL) {
- if (uris != NULL)
- open_uris (corba_shell, uris);
- else {
- e_file_lock_create ();
- e_shell_create_window (shell, default_component_id, NULL);
- }
- } else {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- if (uris != NULL)
- open_uris (corba_shell, uris);
- else
- if (default_component_id == NULL)
- GNOME_Evolution_Shell_createNewWindow (corba_shell, "", &ev);
- else
- GNOME_Evolution_Shell_createNewWindow (corba_shell, default_component_id, &ev);
-
- CORBA_exception_free (&ev);
- }
-
- CORBA_Object_release (corba_shell, &ev);
-
- CORBA_exception_free (&ev);
-
- if (shell == NULL) {
- /*there is another instance but because we don't open any windows
- we must notify the startup was complete manually*/
- gdk_notify_startup_complete ();
- bonobo_main_quit ();
- }
-
- /* This must be done after Bonobo has created all the components. For
- * example the mail component makes the global variable `session` which
- * is being used by several EPlugins */
-
- if (!disable_eplugin) {
- e_plugin_load_plugins_with_missing_symbols ();
- }
+ /* If another Evolution process is running, we're done. */
+ if (unique_app_is_running (UNIQUE_APP (shell)))
+ gtk_main_quit ();
return FALSE;
}
@@ -470,27 +317,15 @@ setup_segv_redirect (void)
#define setup_segv_redirect() (void)0
#endif
-static gint
-gnome_master_client_save_yourself_cb (GnomeClient *client, GnomeSaveStyle save_style, gint shutdown, GnomeInteractStyle interact_style, gint fast, gpointer user_data)
-{
- return !shell || e_shell_can_quit (shell);
-}
-
-static void
-gnome_master_client_die_cb (GnomeClient *client)
-{
- e_shell_do_quit (shell);
-}
-
-static const GOptionEntry options[] = {
- { "component", 'c', 0, G_OPTION_ARG_STRING, &default_component_id,
+static GOptionEntry entries[] = {
+ { "component", 'c', 0, G_OPTION_ARG_STRING, &requested_view,
N_("Start Evolution activating the specified component"), NULL },
{ "offline", '\0', 0, G_OPTION_ARG_NONE, &start_offline,
N_("Start in offline mode"), NULL },
{ "online", '\0', 0, G_OPTION_ARG_NONE, &start_online,
N_("Start in online mode"), NULL },
#ifdef KILL_PROCESS_CMD
- { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &killev,
+ { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &force_shutdown,
N_("Forcibly shut down all Evolution components"), NULL },
#endif
#ifdef DEVELOPMENT
@@ -514,8 +349,7 @@ static void
set_paths (void)
{
/* Set PATH to include the Evolution executable's folder
- * and the lib/evolution/$(BASE_VERSION)/components folder.
- */
+ * and the lib/evolution/$(BASE_VERSION)/components folder. */
wchar_t exe_filename[MAX_PATH];
wchar_t *p;
gchar *exe_folder_utf8;
@@ -536,60 +370,99 @@ set_paths (void)
*p = L'\0';
top_folder_utf8 = g_utf16_to_utf8 (exe_filename, -1, NULL, NULL, NULL);
- components_folder_utf8 =
- g_strconcat (top_folder_utf8,
- "/lib/evolution/" BASE_VERSION "/components",
- NULL);
-
- path = g_build_path (";",
- exe_folder_utf8,
- components_folder_utf8,
- g_getenv ("PATH"),
- NULL);
+ components_folder_utf8 = g_strconcat (
+ top_folder_utf8, "/lib/evolution/"
+ BASE_VERSION "/components", NULL);
+
+ path = g_build_path (
+ ";", exe_folder_utf8,
+ components_folder_utf8, g_getenv ("PATH"), NULL);
if (!g_setenv ("PATH", path, TRUE))
- g_warning ("Could not set PATH for Evolution and its child processes");
+ g_warning ("Could not set PATH for Evolution "
+ "and its child processes");
g_free (path);
g_free (exe_folder_utf8);
g_free (components_folder_utf8);
- /* Set BONOBO_ACTIVATION_PATH */
- if (g_getenv ("BONOBO_ACTIVATION_PATH" ) == NULL) {
- path = g_build_filename (top_folder_utf8,
- "lib/bonobo/servers",
- NULL);
- if (!g_setenv ("BONOBO_ACTIVATION_PATH", path, TRUE))
- g_warning ("Could not set BONOBO_ACTIVATION_PATH");
- g_free (path);
- }
g_free (top_folder_utf8);
}
#endif
+static void
+shell_window_destroyed_cb (EShell *shell)
+{
+ if (e_shell_get_watched_windows (shell) == NULL)
+ gtk_main_quit ();
+}
+
+static void
+create_default_shell (void)
+{
+ EShell *shell;
+ GConfClient *client;
+ gboolean online = TRUE;
+ GError *error = NULL;
+
+ client = gconf_client_get_default ();
+
+ if (start_online)
+ online = TRUE;
+ else if (start_offline)
+ online = FALSE;
+ else {
+ const gchar *key;
+ gboolean value;
+
+ key = "/apps/evolution/shell/start_offline";
+ value = gconf_client_get_bool (client, key, &error);
+ if (error == NULL)
+ online = !value;
+ else {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+ }
+
+ shell = g_object_new (
+ E_TYPE_SHELL,
+ "name", "org.gnome.evolution",
+ "online", online,
+ NULL);
+
+ g_signal_connect (
+ shell, "window-destroyed",
+ G_CALLBACK (shell_window_destroyed_cb), NULL);
+
+ g_object_unref (client);
+
+ /* EShell keeps its own reference to the first instance for use
+ * in e_shell_get_default(), so it's safe to unreference here. */
+ g_object_unref (shell);
+
+ g_idle_add ((GSourceFunc) idle_cb, remaining_args);
+}
+
gint
main (gint argc, gchar **argv)
{
#ifdef G_OS_WIN32
- if (fileno (stdout) != -1 &&
- _get_osfhandle (fileno (stdout)) != -1)
- {
- /* stdout is fine, presumably redirected to a file or pipe */
- }
- else
- {
- typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
+ if (fileno (stdout) != -1 && _get_osfhandle (fileno (stdout)) != -1) {
+ /* stdout is fine, presumably redirected to a file or pipe */
+ } else {
+ typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
- AttachConsole_t p_AttachConsole =
- (AttachConsole_t) GetProcAddress (GetModuleHandle ("kernel32.dll"), "AttachConsole");
+ AttachConsole_t p_AttachConsole =
+ (AttachConsole_t) GetProcAddress (
+ GetModuleHandle ("kernel32.dll"), "AttachConsole");
- if (p_AttachConsole != NULL && p_AttachConsole (ATTACH_PARENT_PROCESS))
+ if (p_AttachConsole != NULL && p_AttachConsole (ATTACH_PARENT_PROCESS))
{
- freopen ("CONOUT$", "w", stdout);
- dup2 (fileno (stdout), 1);
- freopen ("CONOUT$", "w", stderr);
- dup2 (fileno (stderr), 2);
-
- }
+ freopen ("CONOUT$", "w", stdout);
+ dup2 (fileno (stdout), 1);
+ freopen ("CONOUT$", "w", stderr);
+ dup2 (fileno (stderr), 2);
+ }
}
extern void link_shutdown (void);
@@ -599,10 +472,8 @@ main (gint argc, gchar **argv)
#ifdef DEVELOPMENT
gboolean skip_warning_dialog;
#endif
- GnomeProgram *program;
- GnomeClient *master_client;
- GOptionContext *context;
gchar *filename;
+ GError *error = NULL;
/* Make ElectricFence work. */
free (malloc (10));
@@ -611,21 +482,19 @@ main (gint argc, gchar **argv)
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
- context = g_option_context_new (_("- The Evolution PIM and Email Client"));
-
- g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
-
- g_option_context_set_translation_domain(context, GETTEXT_PACKAGE);
-
#ifdef G_OS_WIN32
set_paths ();
#endif
- program = gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv,
- GNOME_PROGRAM_STANDARD_PROPERTIES,
- GNOME_PARAM_GOPTION_CONTEXT, context,
- GNOME_PARAM_HUMAN_READABLE_NAME, _("Evolution"),
- NULL);
+ gtk_init_with_args (
+ &argc, &argv,
+ _("- The Evolution PIM and Email Client"),
+ entries, (gchar *) GETTEXT_PACKAGE, &error);
+ if (error != NULL) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ exit (1);
+ }
#ifdef G_OS_WIN32
if (strcmp (gettext (""), "") == 0) {
@@ -639,15 +508,14 @@ main (gint argc, gchar **argv)
}
#endif
if (start_online && start_offline) {
- fprintf (stderr, _("%s: --online and --offline cannot be used together.\n Use %s --help for more information.\n"),
+ g_printerr (_("%s: --online and --offline cannot be used together.\n Use %s --help for more information.\n"),
argv[0], argv[0]);
exit (1);
}
- if (killev) {
- filename = g_build_filename (EVOLUTION_TOOLSDIR,
- "killev",
- NULL);
+ if (force_shutdown) {
+ filename = g_build_filename (
+ EVOLUTION_TOOLSDIR, "killev", NULL);
execl (filename, "killev", NULL);
/* Not reached */
exit (0);
@@ -656,11 +524,10 @@ main (gint argc, gchar **argv)
client = gconf_client_get_default ();
#ifdef DEVELOPMENT
-
- if (force_migrate) {
+ if (force_migrate)
destroy_config (client);
- }
#endif
+
if (disable_preview) {
gconf_client_set_bool (client, "/apps/evolution/mail/display/show_preview", FALSE, NULL);
gconf_client_set_bool (client, "/apps/evolution/mail/display/safe_list", TRUE, NULL);
@@ -682,37 +549,19 @@ main (gint argc, gchar **argv)
g_warning ("Could not set up debugging output file.");
}
- master_client = gnome_master_client ();
-
- g_signal_connect (G_OBJECT (master_client), "save_yourself", G_CALLBACK (gnome_master_client_save_yourself_cb), NULL);
- g_signal_connect (G_OBJECT (master_client), "die", G_CALLBACK (gnome_master_client_die_cb), NULL);
-
glade_init ();
e_cursors_init ();
e_icon_factory_init ();
- e_passwords_init();
+ e_passwords_init ();
gtk_window_set_default_icon_name ("evolution");
if (setup_only)
exit (0);
- gnome_sound_init ("localhost");
+ categories_icon_theme_hack ();
gtk_accel_map_load (e_get_accels_filename ());
- if (!disable_eplugin) {
- e_plugin_register_type(e_plugin_lib_get_type());
- e_plugin_hook_register_type(es_menu_hook_get_type());
- e_plugin_hook_register_type(es_event_hook_get_type());
-#ifdef ENABLE_PROFILING
- e_plugin_hook_register_type(e_profile_event_hook_get_type());
-#endif
- e_plugin_hook_register_type(e_plugin_type_hook_get_type());
- e_plugin_hook_register_type(e_import_hook_get_type());
- e_plugin_hook_register_type(E_TYPE_PLUGIN_UI_HOOK);
- e_plugin_load_plugins ();
- }
-
#ifdef DEVELOPMENT
skip_warning_dialog = gconf_client_get_bool (
client, SKIP_WARNING_DIALOG_KEY, NULL);
@@ -721,24 +570,41 @@ main (gint argc, gchar **argv)
gconf_client_set_bool (
client, SKIP_WARNING_DIALOG_KEY,
show_development_warning (), NULL);
- else
- g_idle_add ((GSourceFunc) idle_cb, remaining_args);
-
-#else
- g_idle_add ((GSourceFunc) idle_cb, remaining_args);
#endif
+
g_object_unref (client);
- bonobo_main ();
+ create_default_shell ();
+
+ if (!disable_eplugin) {
+ /* Register built-in plugin hook types. */
+ es_event_hook_get_type ();
+#ifdef ENABLE_PROFILING
+ e_profile_event_hook_get_type ();
+#endif
+ e_import_hook_get_type ();
+ e_plugin_ui_hook_get_type ();
+
+ /* All EPlugin and EPluginHook subclasses should be
+ * registered in GType now, so load plugins now. */
+ e_plugin_load_plugins ();
+ }
+
+ gtk_main ();
+
+ /* Drop what should be the last reference to the shell.
+ * Emit a warning if references are leaking somewhere. */
+ g_object_unref (default_shell);
+ if (E_IS_SHELL (default_shell))
+ g_warning ("Shell not finalized on exit");
gtk_accel_map_save (e_get_accels_filename ());
e_icon_factory_shutdown ();
- g_object_unref (program);
- gnome_sound_shutdown ();
e_cursors_shutdown ();
#ifdef G_OS_WIN32
link_shutdown ();
#endif
+
return 0;
}