2 * main-application.c: Main entry point for the Gnumeric application
5 * Jon Kåre Hellan <hellan@acm.org>
6 * Morten Welinder <terra@gnome.org>
7 * Jody Goldberg <jody@gnome.org>
9 * Copyright (C) 2002-2004, Jon Kåre Hellan
12 #include <gnumeric-config.h>
13 #include <glib/gi18n.h>
15 #include <libgnumeric.h>
17 #define _WIN32_WINNT 0x0501
22 #include <command-context.h>
23 #include <goffice/goffice.h>
24 #include <io-context-gtk.h>
25 /* TODO: Get rid of this one */
26 #include <command-context-stderr.h>
27 #include <wbc-gtk-impl.h>
28 #include <workbook-view.h>
31 #include <gnumeric-conf.h>
32 #include <gnumeric-paths.h>
36 #include <gnm-plugin.h>
37 #include <application.h>
40 #include <glib/gstdio.h>
42 #include <sys/types.h>
47 #ifdef HAVE_FPU_CONTROL_H
48 #include <fpu_control.h>
51 static gboolean immediate_exit_flag
= FALSE
;
52 static gboolean gnumeric_no_splash
= FALSE
;
53 static gboolean gnumeric_no_warnings
= FALSE
;
54 static gchar
*geometry
= NULL
;
55 static gchar
**startup_files
;
57 static const GOptionEntry gnumeric_options
[] = {
58 /*********************************
60 { "geometry", 'g', 0, G_OPTION_ARG_STRING
, &geometry
,
61 N_("Specify the size and location of the initial window"),
62 N_("WIDTHxHEIGHT+XOFF+YOFF")
64 { "no-splash", 0, 0, G_OPTION_ARG_NONE
, &gnumeric_no_splash
,
65 N_("Don't show splash screen"), NULL
},
66 { "no-warnings", 0, 0, G_OPTION_ARG_NONE
, &gnumeric_no_warnings
,
67 N_("Don't display warning dialogs when importing"),
71 /*********************************
75 G_OPTION_FLAG_HIDDEN
, G_OPTION_ARG_NONE
, &immediate_exit_flag
,
76 N_("Exit immediately after loading the selected books"),
79 { G_OPTION_REMAINING
, 0, 0, G_OPTION_ARG_FILENAME_ARRAY
, &startup_files
, NULL
, NULL
},
85 handle_paint_events (void)
87 /* FIXME: we need to mask input events correctly here */
88 /* Show something coherent */
89 while (gtk_events_pending () && !gnm_app_shutting_down ())
90 gtk_main_iteration_do (FALSE
);
93 static GObject
*program
= NULL
;
96 gnumeric_arg_shutdown (void)
99 g_object_unref (program
);
105 gnumeric_arg_parse (int argc
, char **argv
)
107 GOptionContext
*ocontext
;
108 GError
*error
= NULL
;
110 ocontext
= g_option_context_new (_("[FILE ...]"));
111 g_option_context_add_main_entries (ocontext
, gnumeric_options
, GETTEXT_PACKAGE
);
112 g_option_context_add_group (ocontext
, gnm_get_option_group ());
114 #if defined(G_OS_WIN32)
115 /* we have already translated to utf8, do not do it again.
116 * http://bugzilla.gnome.org/show_bug.cgi?id=361321 */
117 g_option_context_set_delocalize (ocontext
, FALSE
);
120 g_option_context_add_group (ocontext
, gtk_get_option_group (TRUE
));
121 g_option_context_parse (ocontext
, &argc
, &argv
, &error
);
124 g_option_context_free (ocontext
);
127 g_printerr (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
128 error
->message
, argv
[0]);
129 g_error_free (error
);
133 gtk_init (&argc
, &argv
);
137 * WARNING WARNING WARNING
138 * This does not belong here
139 * but it is expedient for now to get things to compile
141 #warning "REMOVE REMOVE REMOVE"
143 store_plugin_state (void)
145 GSList
*active_plugins
= go_plugins_get_active_plugins ();
146 gnm_conf_set_plugins_active (active_plugins
);
147 g_slist_free (active_plugins
);
151 cb_kill_wbcg (WBCGtk
*wbcg
)
153 gboolean still_open
= wbc_gtk_close (wbcg
);
154 g_assert (!still_open
);
159 cb_workbook_removed (void)
161 if (gnm_app_workbook_list () == NULL
) {
167 cpu_sanity_check (void)
169 #if (defined(i386) || defined(__i386__) || defined(__i386) || defined(__x86_64__) || defined(__x86_64)) && HAVE_FPU_CONTROL_H
171 const fpu_control_t mask
= _FPU_EXTENDED
| _FPU_DOUBLE
| _FPU_SINGLE
;
174 if ((state
& mask
) != _FPU_EXTENDED
) {
175 // Evidently currentlly happinging when Windows runs Linux
176 // binaries. See bug 794515.
177 g_warning ("Sanity check failed! The cpu is not in \"extended\" mode as it should be. Attempting to fix, but expect trouble.");
178 state
= (state
& ~mask
) | _FPU_EXTENDED
;
188 main (int argc
, char const **argv
)
190 gboolean opened_workbook
= FALSE
;
193 GSList
*wbcgs_to_kill
= NULL
;
195 gboolean any_error
= FALSE
;
198 gboolean has_console
;
201 /* No code before here, we need to init threads */
202 argv
= gnm_pre_parse_init (argc
, argv
);
207 * Attempt to disable Ubuntu's funky, non-working scroll
208 * bars. This needs to be done before gtk starts loading
209 * modules. Note: the following call will not replace
210 * an existing setting, so you can run with =1 if you like.
212 g_setenv ("LIBOVERLAY_SCROLLBAR", "0", FALSE
);
217 typedef BOOL (CALLBACK
* LPFNATTACHCONSOLE
)(DWORD
);
218 LPFNATTACHCONSOLE MyAttachConsole
;
221 if ((hmod
= GetModuleHandle("kernel32.dll"))) {
222 MyAttachConsole
= (LPFNATTACHCONSOLE
) GetProcAddress(hmod
, "AttachConsole");
223 if (MyAttachConsole
&& MyAttachConsole(ATTACH_PARENT_PROCESS
)) {
224 freopen("CONOUT$", "w", stdout
);
225 freopen("CONOUT$", "w", stderr
);
226 dup2(fileno(stdout
), 1);
227 dup2(fileno(stderr
), 2);
234 gnumeric_arg_parse (argc
, (char **)argv
);
235 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
236 bind_textdomain_codeset (GETTEXT_PACKAGE
"-functions", "UTF-8");
238 gnm_session_init (argv
[0]);
242 cc
= gnm_cmd_context_stderr_new ();
243 go_component_set_default_command_context (cc
);
246 cc
= g_object_new (GNM_TYPE_IO_CONTEXT_GTK
,
247 "show-splash", !gnumeric_no_splash
,
248 "show-warnings", !gnumeric_no_warnings
,
250 ioc
= GO_IO_CONTEXT (g_object_ref (cc
));
251 handle_paint_events ();
253 /* Keep in sync with .desktop file */
254 g_set_application_name (_("Gnumeric Spreadsheet"));
255 gnm_plugins_init (GO_CMD_CONTEXT (ioc
));
260 N
= g_strv_length (startup_files
);
261 go_io_context_set_num_files (ioc
, N
);
262 for (i
= 0; i
< N
&& !gnm_app_shutting_down (); i
++) {
263 char *uri
= go_shell_arg_to_uri (startup_files
[i
]);
266 g_warning ("Ignoring invalid URI.");
271 go_io_context_processing_file (ioc
, uri
);
272 wbv
= workbook_view_new_from_uri (uri
, NULL
, ioc
, NULL
);
275 if (go_io_error_occurred (ioc
) ||
276 go_io_warning_occurred (ioc
)) {
277 if (go_io_error_occurred (ioc
))
279 go_io_error_display (ioc
);
280 go_io_error_clear (ioc
);
285 workbook_update_history (wb_view_get_workbook (wbv
), GNM_FILE_SAVE_AS_STYLE_SAVE
);
287 wbcg
= wbc_gtk_new (wbv
, NULL
, NULL
, geometry
);
289 sheet_update (wb_view_cur_sheet (wbv
));
290 opened_workbook
= TRUE
;
291 gnm_io_context_gtk_set_transient_for (GNM_IO_CONTEXT_GTK (ioc
),
292 wbcg_toplevel (wbcg
));
293 if (immediate_exit_flag
)
294 wbcgs_to_kill
= g_slist_prepend (wbcgs_to_kill
,
297 /* cheesy attempt to keep the ui from freezing during
299 handle_paint_events ();
300 if (gnm_io_context_gtk_get_interrupted (GNM_IO_CONTEXT_GTK (ioc
)))
301 break; /* Don't load any more workbooks */
308 // If we actually opened a workbook, we are not about to exit so
309 // suppress the error. (Returning an error when the GUI exits
310 // down the line is not helpful.)
314 // If we were intentionally short circuited exit now
315 if (any_error
|| gnm_app_shutting_down ()) {
316 g_object_unref (ioc
);
317 g_slist_foreach (wbcgs_to_kill
, (GFunc
)cb_kill_wbcg
, NULL
);
319 g_object_set (gnm_app_get_app (),
320 "initial-open-complete", TRUE
, NULL
);
322 if (!opened_workbook
) {
323 gint n_of_sheets
= gnm_conf_get_core_workbook_n_sheet ();
325 workbook_new_with_sheets (n_of_sheets
),
329 if (immediate_exit_flag
) {
331 for (l
= wbcgs_to_kill
; l
; l
= l
->next
)
332 g_idle_add ((GSourceFunc
)cb_kill_wbcg
, l
->data
);
335 g_signal_connect (gnm_app_get_app (),
337 G_CALLBACK (cb_workbook_removed
),
340 gnm_io_context_gtk_discharge_splash (GNM_IO_CONTEXT_GTK (ioc
));
341 g_object_unref (ioc
);
346 g_object_set (gnm_app_get_app (), "shutting-down", TRUE
, NULL
);
348 g_slist_free (wbcgs_to_kill
);
349 gnumeric_arg_shutdown ();
350 store_plugin_state ();
353 #if defined(G_OS_WIN32)
361 gnm_pre_parse_shutdown ();
362 go_component_set_default_command_context (NULL
);
365 * This helps finding leaks. We might want it in developent
368 if (gnm_debug_flag ("close-displays")) {
372 while (g_main_context_iteration (NULL
, FALSE
))
375 displays
= gdk_display_manager_list_displays
376 (gdk_display_manager_get ());
377 g_slist_foreach (displays
, (GFunc
)gdk_display_close
, NULL
);
378 g_slist_free (displays
);
381 return any_error
? 1 : 0;