source: trunk/third/nautilus/src/nautilus-main.c @ 18383

Revision 18383, 8.6 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18382, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */
2
3/*
4 * Nautilus
5 *
6 * Copyright (C) 1999, 2000 Red Hat, Inc.
7 * Copyright (C) 1999, 2000 Eazel, Inc.
8 *
9 * Nautilus is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * Nautilus is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Authors: Elliot Lee <sopwith@redhat.com>,
24 *          Darin Adler <darin@bentspoon.com>,
25 *          John Sullivan <sullivan@eazel.com>
26 *
27 */
28
29/* nautilus-main.c: Implementation of the routines that drive program lifecycle and main window creation/destruction. */
30
31#include <config.h>
32#include "nautilus-main.h"
33
34#include "nautilus-application.h"
35#include "nautilus-self-check-functions.h"
36#include "nautilus-window.h"
37#include <bonobo-activation/bonobo-activation.h>
38#include <bonobo/bonobo-main.h>
39#include <bonobo/bonobo-ui-main.h>
40#include <dlfcn.h>
41#include <eel/eel-debug.h>
42#include <eel/eel-glib-extensions.h>
43#include <eel/eel-self-checks.h>
44#include <gdk/gdkx.h>
45#include <gtk/gtkmain.h>
46#include <gtk/gtksignal.h>
47#include <libgnome/gnome-i18n.h>
48#include <libgnome/gnome-init.h>
49#include <libgnomeui/gnome-ui-init.h>
50#include <libgnomevfs/gnome-vfs-init.h>
51#include <libnautilus-private/nautilus-directory-metafile.h>
52#include <libnautilus-private/nautilus-global-preferences.h>
53#include <libnautilus-private/nautilus-lib-self-check-functions.h>
54#include <libxml/parser.h>
55#include <popt.h>
56#include <stdlib.h>
57#include <unistd.h>
58
59/* Keeps track of everyone who wants the main event loop kept active */
60static GSList *event_loop_registrants;
61
62static gboolean
63is_event_loop_needed (void)
64{
65        return event_loop_registrants != NULL;
66}
67
68static int
69quit_if_in_main_loop (gpointer callback_data)
70{
71        guint level;
72
73        g_assert (callback_data == NULL);
74
75        level = gtk_main_level ();
76
77        /* We can be called even outside the main loop by gnome_vfs_shutdown,
78         * so check that we are in a loop before calling quit.
79         */
80        if (level != 0) {
81                gtk_main_quit ();
82        }
83
84        /* We need to be called again if we quit a nested loop. */
85        return level > 1;
86}
87
88static void
89eel_gtk_main_quit_all (void)
90{
91        /* Calling gtk_main_quit directly only kills the current/top event loop.
92         * This idler will be run by the current event loop, killing it, and then
93         * by the next event loop, ...
94         */
95        gtk_idle_add (quit_if_in_main_loop, NULL);
96}
97
98static void
99event_loop_unregister (GtkObject *object)
100{
101        event_loop_registrants = g_slist_remove (event_loop_registrants, object);
102        if (!is_event_loop_needed ()) {
103                eel_gtk_main_quit_all ();
104        }
105}
106
107void
108nautilus_main_event_loop_register (GtkObject *object)
109{
110        g_signal_connect (object, "destroy", G_CALLBACK (event_loop_unregister), NULL);
111        event_loop_registrants = g_slist_prepend (event_loop_registrants, object);
112}
113
114gboolean
115nautilus_main_is_event_loop_mainstay (GtkObject *object)
116{
117        return g_slist_length (event_loop_registrants) == 1
118                && event_loop_registrants->data == object;
119}
120
121void
122nautilus_main_event_loop_quit (void)
123{
124        while (event_loop_registrants != NULL) {
125                gtk_object_destroy (event_loop_registrants->data);
126        }
127}
128
129int
130main (int argc, char *argv[])
131{
132        gboolean kill_shell;
133        gboolean restart_shell;
134        gboolean no_default_window;
135        gboolean no_desktop;
136        char *geometry;
137        gboolean perform_self_check;
138        poptContext popt_context;
139        const char **args;
140        NautilusApplication *application;
141        char **argv_copy;
142        GnomeProgram *program;
143        GValue context_as_value = { 0 };
144
145        struct poptOption options[] = {
146#ifndef NAUTILUS_OMIT_SELF_CHECK
147                { "check", 'c', POPT_ARG_NONE, &perform_self_check, 0,
148                  N_("Perform a quick set of self-check tests."), NULL },
149#endif
150                { "geometry", 'g', POPT_ARG_STRING, &geometry, 0,
151                  N_("Create the initial window with the given geometry."), N_("GEOMETRY") },
152                { "no-default-window", 'n', POPT_ARG_NONE, &no_default_window, 0,
153                  N_("Only create windows for explicitly specified URIs."), NULL },
154                { "no-desktop", '\0', POPT_ARG_NONE, &no_desktop, 0,
155                  N_("Do not manage the desktop (ignore the preference set in the preferences dialog)."), NULL },
156                { "quit", 'q', POPT_ARG_NONE, &kill_shell, 0,
157                  N_("Quit Nautilus."), NULL },
158                { "restart", '\0', POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &restart_shell, 0,
159                  N_("Restart Nautilus."), NULL },
160                { NULL, '\0', 0, NULL, 0, NULL, NULL }
161        };
162
163        if (g_getenv ("NAUTILUS_DEBUG") != NULL) {
164                eel_make_warnings_and_criticals_stop_in_debugger ();
165        }
166       
167        /* Initialize gettext support */
168        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
169        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
170        textdomain (GETTEXT_PACKAGE);
171
172        /* Get parameters. */
173        geometry = NULL;
174        kill_shell = FALSE;
175        no_default_window = FALSE;
176        no_desktop = FALSE;
177        perform_self_check = FALSE;
178        restart_shell = FALSE;
179
180        program = gnome_program_init ("nautilus", VERSION,
181                                      LIBGNOMEUI_MODULE, argc, argv,
182                                      GNOME_PROGRAM_STANDARD_PROPERTIES,
183                                      GNOME_PARAM_POPT_TABLE, options,
184                                      GNOME_PARAM_HUMAN_READABLE_NAME, _("Nautilus"),
185                                      NULL);
186
187        g_object_get_property (G_OBJECT (program),
188                               GNOME_PARAM_POPT_CONTEXT,
189                               g_value_init (&context_as_value, G_TYPE_POINTER));
190
191        popt_context = g_value_get_pointer (&context_as_value);
192
193        /* Check for argument consistency. */
194        args = poptGetArgs (popt_context);
195        if (perform_self_check && args != NULL) {
196                fprintf (stderr, _("nautilus: --check cannot be used with URIs.\n"));
197                return EXIT_FAILURE;
198        }
199        if (perform_self_check && (kill_shell || restart_shell)) {
200                fprintf (stderr, _("nautilus: --check cannot be used with other options.\n"));
201                return EXIT_FAILURE;
202        }
203        if (kill_shell && args != NULL) {
204                fprintf (stderr, _("nautilus: --quit cannot be used with URIs.\n"));
205                return EXIT_FAILURE;
206        }
207        if (restart_shell && args != NULL) {
208                fprintf (stderr, _("nautilus: --restart cannot be used with URIs.\n"));
209                return EXIT_FAILURE;
210        }
211        if (geometry != NULL && args != NULL && args[0] != NULL && args[1] != NULL) {
212                fprintf (stderr, _("nautilus: --geometry cannot be used with more than one URI.\n"));
213                return EXIT_FAILURE;
214        }
215
216        /* Initialize the services that we use. */
217        LIBXML_TEST_VERSION
218
219        if (g_getenv ("NAUTILUS_ENABLE_TEST_COMPONENTS") != NULL) {
220                bonobo_activation_set_test_components_enabled (TRUE);
221        }
222
223        /* Initialize preferences. This is needed so that proper
224         * defaults are available before any preference peeking
225         * happens.
226         */
227        nautilus_global_preferences_init_with_folder_browsing ();
228        if (no_desktop) {
229                eel_preferences_set_is_invisible
230                        (NAUTILUS_PREFERENCES_SHOW_DESKTOP, TRUE);
231                eel_preferences_set_is_invisible
232                        (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR, TRUE);
233        }
234       
235        bonobo_activate (); /* do now since we need it before main loop */
236
237        /* Do either the self-check or the real work. */
238        if (perform_self_check) {
239#ifndef NAUTILUS_OMIT_SELF_CHECK
240                /* Run the checks (each twice) for nautilus and libnautilus-private. */
241
242                nautilus_directory_use_self_contained_metafile_factory ();
243
244                nautilus_run_self_checks ();
245                nautilus_run_lib_self_checks ();
246                eel_exit_if_self_checks_failed ();
247
248                nautilus_run_self_checks ();
249                nautilus_run_lib_self_checks ();
250                eel_exit_if_self_checks_failed ();
251#endif
252        } else {
253                /* Run the nautilus application. */
254                application = nautilus_application_new ();
255                nautilus_application_startup
256                        (application,
257                         kill_shell, restart_shell, no_default_window, no_desktop,
258                         !(kill_shell || restart_shell),
259                         geometry,
260                         args);
261                if (is_event_loop_needed ()) {
262                        gtk_main ();
263                }
264                bonobo_object_unref (application);
265        }
266
267        poptFreeContext (popt_context);
268
269        gnome_vfs_shutdown ();
270        eel_debug_shut_down ();
271        bonobo_ui_debug_shutdown ();
272
273        /* If told to restart, exec() myself again. This is used when
274         * the program is told to restart with CORBA, for example when
275         * an update takes place.
276         */
277
278        if (g_getenv ("_NAUTILUS_RESTART") != NULL) {
279                eel_unsetenv ("_NAUTILUS_RESTART");
280               
281                /* Might eventually want to copy all the parameters
282                 * from argv into the new exec. For now, though, that
283                 * would just interfere with the re-creation of
284                 * windows based on the window info stored in gconf,
285                 * including whether the desktop was started.
286                 */
287                argv_copy = g_new0 (char *, 2);
288                argv_copy[0] = argv[0];
289               
290                execvp (argv[0], argv_copy);
291        }
292
293        return EXIT_SUCCESS;
294}
Note: See TracBrowser for help on using the repository browser.