1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2011 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
36 #ifdef HAVE_LIBDMALLOC
44 /* These are generated by parse_commandline() */
45 extern SCM s_pre_load_expr
;
46 extern SCM s_post_load_expr
;
49 gschem_atexit_func func
;
51 } gschem_atexit_struct
;
53 static GList
*exit_functions
= NULL
;
55 /*! \brief Register a function to be called on program exit
57 * \par Function Description
58 * This function registers a function to be called on
59 * program exit. Multiple functions will be executed in
60 * the order they are registered.
62 * \param [in] func a pointer to the function to be registered
63 * \param [in] data an arbitrary argument provided to the function
66 void gschem_atexit(gschem_atexit_func func
, gpointer data
)
68 gschem_atexit_struct
*p
;
70 p
= g_new(gschem_atexit_struct
, 1);
73 exit_functions
= g_list_append(exit_functions
, p
);
76 /*! \brief Cleanup gSchem on exit.
77 * \par Function Description
78 * This function cleans up all memory objects allocated during the
81 void gschem_quit(void)
84 gschem_atexit_struct
*p
;
86 /* Call all registered functions in order */
87 list
= exit_functions
;
89 p
= (gschem_atexit_struct
*) list
->data
;
92 list
= g_list_next(list
);
94 g_list_free(exit_functions
);
99 /* o_text_freeallfonts();*/
102 #ifdef HAVE_LIBSTROKE
104 #endif /* HAVE_LIBSTROKE */
106 /* s_stroke_free(); no longer needed */
109 i_vars_libgeda_freenames();
111 /* x_window_free_head(); can't do this since it causes a
112 * condition in which window_head->... is still being refered
115 /* enable this to get more memory usage from glib */
116 /* You also have to enable something in glib I think */
117 /* g_mem_profile();*/
123 /*! \brief Main Scheme(GUILE) program function.
124 * \par Function Description
125 * This function is the main program called from scm_boot_guile.
126 * It handles initializing all libraries and gSchem variables
127 * and passes control to the gtk main loop.
129 void main_prog(void *closure
, int argc
, char *argv
[])
133 GSCHEM_TOPLEVEL
*w_current
= NULL
;
134 char *input_str
= NULL
;
141 /* Gschem isn't threaded, but some of GTK's file chooser
142 * backends uses threading so we need to call g_thread_init().
143 * GLib requires threading be initialised before any other GLib
144 * functions are called. Do it now if its not already setup. */
145 if (!g_thread_supported ()) g_thread_init (NULL
);
149 /* this should be equivalent to setlocale (LC_ALL, "") */
152 /* This must be the same for all locales */
153 setlocale(LC_NUMERIC
, "C");
155 /* Disable gtk's ability to set the locale. */
156 /* If gtk is allowed to set the locale, then it will override the */
157 /* setlocale for LC_NUMERIC (which is important for proper PS output. */
158 /* This may look funny here, given we make a call to gtk_set_locale() */
159 /* above. I don't know yet, if this is really the right thing to do. */
160 gtk_disable_setlocale();
164 gtk_init(&argc
, &argv
);
166 argv_index
= parse_commandline(argc
, argv
);
167 cwd
= g_get_current_dir();
171 /* create log file right away even if logging is enabled */
172 s_log_init ("gschem");
175 _("gEDA/gschem version %s%s.%s\n"), PREPEND_VERSION_STRING
,
176 PACKAGE_DOTTED_VERSION
, PACKAGE_DATE_VERSION
);
178 _("gEDA/gschem comes with ABSOLUTELY NO WARRANTY; see COPYING for more details.\n"));
180 _("This is free software, and you are welcome to redistribute it under certain\n"));
182 _("conditions; please see the COPYING file for more details.\n\n"));
184 #if defined(__MINGW32__) && defined(DEBUG)
185 fprintf(stderr
, _("This is the MINGW32 port.\n"));
189 fprintf(stderr
, _("Current locale settings: %s\n"), setlocale(LC_ALL
, NULL
));
192 /* init global buffers */
195 /* register guile (scheme) functions */
204 /* initialise color map (need to do this before reading rc files */
209 if (s_path_sys_data () == NULL
) {
210 const gchar
*message
=
211 _("You must set the GEDADATA environment variable!\n\n"
212 "gschem cannot locate its data files. You must set the GEDADATA\n"
213 "environment variable to point to the correct location.\n");
214 GtkWidget
* error_diag
=
215 gtk_message_dialog_new (NULL
, 0, GTK_MESSAGE_ERROR
,
218 gtk_dialog_run (GTK_DIALOG (error_diag
));
219 g_error ("%s", message
);
222 /* Allocate w_current */
223 w_current
= gschem_toplevel_new ();
224 w_current
->toplevel
= s_toplevel_new ();
226 w_current
->toplevel
->load_newer_backup_func
= x_fileselect_load_backup
;
227 w_current
->toplevel
->load_newer_backup_data
= w_current
;
229 o_text_set_rendered_bounds_func (w_current
->toplevel
,
230 o_text_get_rendered_bounds
, w_current
);
232 /* Damage notifications should invalidate the object on screen */
233 o_add_change_notify (w_current
->toplevel
,
234 (ChangeNotifyFunc
) o_invalidate
,
235 (ChangeNotifyFunc
) o_invalidate
, w_current
);
237 scm_dynwind_begin (0);
238 g_dynwind_window (w_current
);
240 /* Run pre-load Scheme expressions */
241 g_scm_eval_protected (s_pre_load_expr
, scm_current_module ());
243 /* By this point, libgeda should have setup the Guile load path, so
244 * we can take advantage of that. */
245 scm_tmp
= scm_sys_search_load_path (scm_from_utf8_string ("gschem.scm"));
246 if (scm_is_false (scm_tmp
)) {
247 s_log_message (_("Couldn't find init scm file [%s]\n"), "gschem.scm");
249 input_str
= scm_to_utf8_string (scm_tmp
);
250 if (g_read_file(w_current
->toplevel
, input_str
, NULL
)) {
251 s_log_message(_("Read init scm file [%s]\n"), input_str
);
253 /*! \todo These two messages are the same. Should be
255 s_log_message(_("Failed to read init scm file [%s]\n"),
258 free (input_str
); /* M'allocated by scm_to_utf8_string() */
259 scm_remember_upto_here_1 (scm_tmp
);
261 /* Now read in RC files. */
263 x_rc_parse_gschem (w_current
, rc_filename
);
265 /* Set default icon */
266 x_window_set_default_icon();
268 /* At end, complete set up of window. */
270 x_window_setup (w_current
);
272 #ifdef HAVE_LIBSTROKE
274 #endif /* HAVE_LIBSTROKE */
276 for (i
= argv_index
; i
< argc
; i
++) {
278 if (g_path_is_absolute(argv
[i
]))
280 /* Path is already absolute so no need to do any concat of cwd */
281 filename
= g_strdup (argv
[i
]);
283 filename
= g_build_filename (cwd
, argv
[i
], NULL
);
290 * SDB notes: at this point the filename might be unnormalized, like
291 * /path/to/foo/../bar/baz.sch. Bad filenames will be normalized in
292 * f_open (called by x_window_open_page). This works for Linux and MINGW32.
294 x_window_open_page(w_current
, filename
);
300 /* If no page has been loaded (wasn't specified in the command line.) */
301 /* Then create an untitled page */
303 x_window_open_page( w_current
, NULL
);
306 /* Update the window to show the current page */
307 x_window_set_current_page( w_current
, w_current
->toplevel
->page_current
);
311 scm_c_eval_string ("(display \"hello guile\n\")");
314 /* Run post-load expressions */
315 g_scm_eval_protected (s_post_load_expr
, scm_current_module ());
317 /* open up log window on startup */
318 if (w_current
->log_window
== MAP_ON_STARTUP
) {
322 /* if there were any symbols which had major changes, put up an error */
324 major_changed_dialog(w_current
);
328 /* enter main loop */
332 /*! \brief Main executable entrance point.
333 * \par Function Description
334 * This is the main function for gSchem. It sets up the Scheme(GUILE)
335 * environment and passes control to via scm_boot_guile to
336 * the #main_prog function.
338 int main (int argc
, char *argv
[])
342 setlocale(LC_ALL
, "");
343 setlocale(LC_NUMERIC
, "C");
344 bindtextdomain("geda-gschem", LOCALEDIR
);
345 textdomain("geda-gschem");
346 bind_textdomain_codeset("geda-gschem", "UTF-8");
349 /* disable the deprecated warnings in guile 1.6.3 */
350 /* Eventually the warnings will need to be fixed */
351 if(getenv("GUILE_WARN_DEPRECATED") == NULL
)
352 putenv("GUILE_WARN_DEPRECATED=no");
354 scm_boot_guile (argc
, argv
, main_prog
, 0);