Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gschem / src / gschem.c
blob7911b55d17c716f44889b83b9f47367da30c4c6a
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 #include <config.h>
21 #include <version.h>
23 #include <stdio.h>
24 #ifdef HAVE_STRING_H
25 #include <string.h>
26 #endif
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
31 #include <glib.h>
33 #include "gschem.h"
35 #ifdef HAVE_LIBDMALLOC
36 #include <dmalloc.h>
37 #endif
39 #ifdef HAVE_LOCALE_H
40 #include <locale.h>
41 #endif
43 typedef struct {
44 gschem_atexit_func func;
45 gpointer arg;
46 } gschem_atexit_struct;
48 static GList *exit_functions = NULL;
50 /*! \brief Register a function to be called on program exit
52 * \par Function Description
53 * This function registers a function to be called on
54 * program exit. Multiple functions will be executed in
55 * the order they are registered.
57 * \param [in] func a pointer to the function to be registered
58 * \param [in] data an arbitrary argument provided to the function
59 * when it is called
61 void gschem_atexit(gschem_atexit_func func, gpointer data)
63 gschem_atexit_struct *p;
65 p = g_new(gschem_atexit_struct, 1);
66 p->func = func;
67 p->arg = data;
68 exit_functions = g_list_append(exit_functions, p);
71 /*! \brief Cleanup gSchem on exit.
72 * \par Function Description
73 * This function cleans up all memory objects allocated during the
74 * gSchem runtime.
76 void gschem_quit(void)
78 GList *list;
79 gschem_atexit_struct *p;
81 /* Call all registered functions in order */
82 list = exit_functions;
83 while(list != NULL) {
84 p = (gschem_atexit_struct *) list->data;
85 p->func(p->arg);
86 g_free(p);
87 list = g_list_next(list);
89 g_list_free(exit_functions);
91 s_clib_free();
92 s_slib_free();
93 s_menu_free();
94 /* o_text_freeallfonts();*/
95 s_attrib_free();
96 s_papersizes_free();
97 #ifdef HAVE_LIBSTROKE
98 x_stroke_free ();
99 #endif /* HAVE_LIBSTROKE */
100 o_undo_cleanup();
101 /* s_stroke_free(); no longer needed */
103 i_vars_freenames();
104 i_vars_libgeda_freenames();
106 /* x_window_free_head(); can't do this since it causes a
107 * condition in which window_head->... is still being refered
108 * after this */
110 /* enable this to get more memory usage from glib */
111 /* You also have to enable something in glib I think */
112 /* g_mem_profile();*/
115 gtk_main_quit();
118 /*! \brief Main Scheme(GUILE) program function.
119 * \par Function Description
120 * This function is the main program called from scm_boot_guile.
121 * It handles initializing all libraries and gSchem variables
122 * and passes control to the gtk main loop.
124 void main_prog(void *closure, int argc, char *argv[])
126 int i;
127 char *cwd = NULL;
128 GSCHEM_TOPLEVEL *w_current = NULL;
129 char *input_str = NULL;
130 int argv_index;
131 int first_page = 1;
132 char *filename;
133 SCM scm_tmp;
135 #ifdef HAVE_GTHREAD
136 /* Gschem isn't threaded, but some of GTK's file chooser
137 * backends uses threading so we need to call g_thread_init().
138 * GLib requires threading be initialised before any other GLib
139 * functions are called. Do it now if its not already setup. */
140 if (!g_thread_supported ()) g_thread_init (NULL);
141 #endif
143 #if ENABLE_NLS
144 /* this should be equivalent to setlocale (LC_ALL, "") */
145 gtk_set_locale();
147 /* This must be the same for all locales */
148 setlocale(LC_NUMERIC, "C");
150 /* Disable gtk's ability to set the locale. */
151 /* If gtk is allowed to set the locale, then it will override the */
152 /* setlocale for LC_NUMERIC (which is important for proper PS output. */
153 /* This may look funny here, given we make a call to gtk_set_locale() */
154 /* above. I don't know yet, if this is really the right thing to do. */
155 gtk_disable_setlocale();
157 #endif
159 gtk_init(&argc, &argv);
161 argv_index = parse_commandline(argc, argv);
162 cwd = g_get_current_dir();
164 libgeda_init();
166 /* Install various libgeda callbacks */
167 arc_draw_func = o_arc_draw;
168 box_draw_func = o_box_draw;
169 bus_draw_func = o_bus_draw;
170 circle_draw_func = o_circle_draw;
171 complex_draw_func = o_complex_draw;
172 line_draw_func = o_line_draw;
173 net_draw_func = o_net_draw;
174 picture_draw_func = o_picture_draw;
175 path_draw_func = o_path_draw;
176 pin_draw_func = o_pin_draw;
177 text_draw_func = o_text_draw;
178 select_func = o_select_object;
180 /* create log file right away even if logging is enabled */
181 s_log_init ("gschem");
183 s_log_message(
184 _("gEDA/gschem version %s%s.%s\n"), PREPEND_VERSION_STRING,
185 PACKAGE_DOTTED_VERSION, PACKAGE_DATE_VERSION);
186 s_log_message(
187 _("gEDA/gschem comes with ABSOLUTELY NO WARRANTY; see COPYING for more details.\n"));
188 s_log_message(
189 _("This is free software, and you are welcome to redistribute it under certain\n"));
190 s_log_message(
191 _("conditions; please see the COPYING file for more details.\n\n"));
193 #if defined(__MINGW32__) && defined(DEBUG)
194 fprintf(stderr, _("This is the MINGW32 port.\n"));
195 #endif
197 #if DEBUG
198 fprintf(stderr, _("Current locale settings: %s\n"), setlocale(LC_ALL, NULL));
199 #endif
201 /* init global buffers */
202 o_buffer_init();
204 /* register guile (scheme) functions */
205 g_register_funcs();
207 /* initialise color map (need to do this before reading rc files */
208 x_color_init ();
210 o_undo_init();
212 if (s_path_sys_data () == NULL) {
213 gchar *message = _("You must set the GEDADATA environment variable!\n\n"
214 "gschem cannot locate its data files. You must set the GEDADATA\n"
215 "environment variable to point to the correct location.\n");
216 GtkWidget* error_diag =
217 gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
218 GTK_BUTTONS_OK,
219 message);
220 gtk_dialog_run (GTK_DIALOG (error_diag));
221 g_error (message);
224 /* Allocate w_current */
225 w_current = gschem_toplevel_new ();
226 w_current->toplevel = s_toplevel_new ();
227 global_window_current = w_current;
229 w_current->toplevel->load_newer_backup_func = x_fileselect_load_backup;
230 w_current->toplevel->load_newer_backup_data = w_current;
232 o_text_set_rendered_bounds_func (w_current->toplevel,
233 o_text_get_rendered_bounds, w_current);
235 /* Now read in RC files. */
236 g_rc_parse_gtkrc();
237 g_rc_parse(w_current->toplevel, "gschemrc", rc_filename);
239 /* By this point, libgeda should have setup the Guile load path, so
240 * we can take advantage of that. */
241 scm_tmp = scm_sys_search_load_path (scm_from_locale_string ("gschem.scm"));
242 if (scm_is_false (scm_tmp)) {
243 s_log_message (_("Couldn't find init scm file [%s]\n"), "gschem.scm");
245 input_str = scm_to_locale_string (scm_tmp);
246 if (g_read_file(input_str) != -1) {
247 s_log_message(_("Read init scm file [%s]\n"), input_str);
248 } else {
249 /*! \todo These two messages are the same. Should be
250 * integrated. */
251 s_log_message(_("Failed to read init scm file [%s]\n"),
252 input_str);
254 free (input_str); /* M'allocated by scm_to_locale_string() */
255 scm_remember_upto_here_1 (scm_tmp);
257 /* Load recent files list. This must be done
258 * before calling x_window_setup(). */
259 recent_files_load();
260 gschem_atexit(recent_files_save, NULL);
262 /* Set default icon */
263 x_window_set_default_icon();
265 /* At end, complete set up of window. */
266 x_color_allocate();
267 x_window_setup (w_current);
269 #ifdef HAVE_LIBSTROKE
270 x_stroke_init ();
271 #endif /* HAVE_LIBSTROKE */
273 for (i = argv_index; i < argc; i++) {
275 if (g_path_is_absolute(argv[i]))
277 /* Path is already absolute so no need to do any concat of cwd */
278 filename = g_strdup (argv[i]);
279 } else {
280 filename = g_build_filename (cwd, argv[i], NULL);
283 if ( first_page )
284 first_page = 0;
287 * SDB notes: at this point the filename might be unnormalized, like
288 * /path/to/foo/../bar/baz.sch. Bad filenames will be normalized in
289 * f_open (called by x_window_open_page). This works for Linux and MINGW32.
291 x_window_open_page(w_current, filename);
292 g_free (filename);
295 g_free(cwd);
297 /* If no page has been loaded (wasn't specified in the command line.) */
298 /* Then create an untitled page */
299 if ( first_page ) {
300 x_window_open_page( w_current, NULL );
303 /* Update the window to show the current page */
304 x_window_set_current_page( w_current, w_current->toplevel->page_current );
307 #if DEBUG
308 scm_c_eval_string ("(display \"hello guile\n\")");
309 #endif
311 if (w_current->toplevel->scheme_directory == NULL) {
312 fprintf(stderr, _("Scheme directory NOT set!\n"));
313 exit(-1);
317 /* Execute a script if it exists */
318 if (script_filename) {
319 s_log_message(_("Executing guile script [%s]\n"),
320 script_filename);
321 g_read_file(script_filename);
324 /* open up log window on startup */
325 if (w_current->log_window == MAP_ON_STARTUP) {
326 x_log_open ();
329 /* if there were any symbols which had major changes, put up an error */
330 /* dialog box */
331 major_changed_dialog(w_current);
333 /* enter main loop */
334 gtk_main();
337 /*! \brief Main executable entrance point.
338 * \par Function Description
339 * This is the main function for gSchem. It sets up the Scheme(GUILE)
340 * environment and passes control to via scm_boot_guile to
341 * the #main_prog function.
343 int main (int argc, char *argv[])
346 #if ENABLE_NLS
347 setlocale(LC_ALL, "");
348 setlocale(LC_NUMERIC, "C");
349 bindtextdomain("geda-gschem", LOCALEDIR);
350 textdomain("geda-gschem");
351 bind_textdomain_codeset("geda-gschem", "UTF-8");
352 #endif
354 /* disable the deprecated warnings in guile 1.6.3 */
355 /* Eventually the warnings will need to be fixed */
356 if(getenv("GUILE_WARN_DEPRECATED") == NULL)
357 putenv("GUILE_WARN_DEPRECATED=no");
359 scm_boot_guile (argc, argv, main_prog, 0);
361 return 0;