/*! \brief Select a script and execute it * \par Function Description * This function opens a file selection dialog. The selected script * is executed. */ void setup_script_selector (GSCHEM_TOPLEVEL *w_current) { char *filename; w_current->sowindow = gtk_file_chooser_dialog_new (_("Execute Script..."), GTK_WINDOW(w_current->main_window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_EXECUTE, GTK_RESPONSE_ACCEPT, NULL); /* Set the alternative button order (ok, cancel, help) for other systems */ gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->sowindow), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1); if (gtk_dialog_run (GTK_DIALOG (w_current->sowindow)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (w_current->sowindow)); if (!(g_file_test(filename, G_FILE_TEST_IS_DIR))) { s_log_message(_("Executing guile script [%s]\n"), filename); g_read_file(filename); } g_free (filename); } gtk_widget_destroy (GTK_WIDGET(w_current->sowindow)); w_current->sowindow = NULL; }
/*! \brief Load a configuration file. * \par Function Description * Load the configuration file \a rcfile, reporting errors via \a err. * * \param toplevel The current #TOPLEVEL structure. * \param rcfile The filename of the configuration file to load. * \param err Return location for errors, or NULL; * \return TRUE on success, FALSE on failure. */ gboolean g_rc_parse_file (TOPLEVEL *toplevel, const gchar *rcfile, GError **err) { gchar *name_norm = NULL; GError *tmp_err = NULL; g_return_val_if_fail ((toplevel != NULL), FALSE); g_return_val_if_fail ((rcfile != NULL), FALSE); /* Normalise filename */ name_norm = f_normalize_filename (rcfile, &tmp_err); if (name_norm == NULL) goto parse_file_error; /* Attempt to load the rc file, if it hasn't been loaded already. * If g_rc_try_mark_read() succeeds, it stores name_norm in * toplevel, so we *don't* free it. */ if (g_rc_try_mark_read (toplevel, name_norm, &tmp_err) && g_read_file (toplevel, name_norm, &tmp_err)) { s_log_message (_("Parsed config from [%s]\n"), name_norm); return TRUE; } parse_file_error: /* Copy tmp_err into err, with a prefixed message. */ /*! \todo We should upgrade to GLib >= 2.16 and use * g_propagate_prefixed_error(). */ if (err == NULL) { g_error_free (tmp_err); } else { gchar *orig_msg = tmp_err->message; tmp_err->message = g_strdup_printf (_("Unable to parse config from [%s]: %s"), (name_norm != NULL) ? name_norm : rcfile, orig_msg); g_free (orig_msg); *err = tmp_err; } g_free (name_norm); return FALSE; }
/*! \brief Main Scheme(GUILE) program function. * \par Function Description * This function is the main program called from scm_boot_guile. * It handles initializing all libraries and gSchem variables * and passes control to the gtk main loop. */ void main_prog(void *closure, int argc, char *argv[]) { int i; char *cwd = NULL; GSCHEM_TOPLEVEL *w_current = NULL; char *input_str = NULL; int argv_index; int first_page = 1; char *filename; SCM scm_tmp; #ifdef HAVE_GTHREAD /* Gschem isn't threaded, but some of GTK's file chooser * backends uses threading so we need to call g_thread_init(). * GLib requires threading be initialised before any other GLib * functions are called. Do it now if its not already setup. */ if (!g_thread_supported ()) g_thread_init (NULL); #endif #if ENABLE_NLS /* this should be equivalent to setlocale (LC_ALL, "") */ gtk_set_locale(); /* This must be the same for all locales */ setlocale(LC_NUMERIC, "C"); /* Disable gtk's ability to set the locale. */ /* If gtk is allowed to set the locale, then it will override the */ /* setlocale for LC_NUMERIC (which is important for proper PS output. */ /* This may look funny here, given we make a call to gtk_set_locale() */ /* above. I don't know yet, if this is really the right thing to do. */ gtk_disable_setlocale(); #endif gtk_init(&argc, &argv); argv_index = parse_commandline(argc, argv); cwd = g_get_current_dir(); libgeda_init(); /* create log file right away even if logging is enabled */ s_log_init ("gschem"); s_log_message( _("gEDA/gschem version %s%s.%s\n"), PREPEND_VERSION_STRING, PACKAGE_DOTTED_VERSION, PACKAGE_DATE_VERSION); s_log_message( _("gEDA/gschem comes with ABSOLUTELY NO WARRANTY; see COPYING for more details.\n")); s_log_message( _("This is free software, and you are welcome to redistribute it under certain\n")); s_log_message( _("conditions; please see the COPYING file for more details.\n\n")); #if defined(__MINGW32__) && defined(DEBUG) fprintf(stderr, _("This is the MINGW32 port.\n")); #endif #if DEBUG fprintf(stderr, _("Current locale settings: %s\n"), setlocale(LC_ALL, NULL)); #endif /* init global buffers */ o_buffer_init(); /* register guile (scheme) functions */ g_register_funcs(); g_init_window (); g_init_select (); g_init_hook (); g_init_attrib (); g_init_keys (); g_init_util (); /* initialise color map (need to do this before reading rc files */ x_color_init (); o_undo_init(); if (s_path_sys_data () == NULL) { const gchar *message = _("You must set the GEDADATA environment variable!\n\n" "gschem cannot locate its data files. You must set the GEDADATA\n" "environment variable to point to the correct location.\n"); GtkWidget* error_diag = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", message); gtk_dialog_run (GTK_DIALOG (error_diag)); g_error ("%s", message); } /* Allocate w_current */ w_current = gschem_toplevel_new (); /* Connect hooks that run for each s_toplevel_new() first */ s_toplevel_append_new_hook ((NewToplevelFunc) add_libgeda_toplevel_hooks, w_current); w_current->toplevel = s_toplevel_new (); w_current->toplevel->load_newer_backup_func = x_fileselect_load_backup; w_current->toplevel->load_newer_backup_data = w_current; o_text_set_rendered_bounds_func (w_current->toplevel, o_text_get_rendered_bounds, w_current); /* Damage notifications should invalidate the object on screen */ o_add_change_notify (w_current->toplevel, (ChangeNotifyFunc) o_invalidate, (ChangeNotifyFunc) o_invalidate, w_current); scm_dynwind_begin (0); g_dynwind_window (w_current); /* Run pre-load Scheme expressions */ g_scm_eval_protected (s_pre_load_expr, scm_current_module ()); /* By this point, libgeda should have setup the Guile load path, so * we can take advantage of that. */ scm_tmp = scm_sys_search_load_path (scm_from_utf8_string ("gschem.scm")); if (scm_is_false (scm_tmp)) { s_log_message (_("Couldn't find init scm file [%s]\n"), "gschem.scm"); } input_str = scm_to_utf8_string (scm_tmp); if (g_read_file(w_current->toplevel, input_str, NULL)) { s_log_message(_("Read init scm file [%s]\n"), input_str); } else { /*! \todo These two messages are the same. Should be * integrated. */ s_log_message(_("Failed to read init scm file [%s]\n"), input_str); } free (input_str); /* M'allocated by scm_to_utf8_string() */ scm_remember_upto_here_1 (scm_tmp); /* Now read in RC files. */ g_rc_parse_gtkrc(); x_rc_parse_gschem (w_current, rc_filename); /* Set default icon */ x_window_set_default_icon(); /* At end, complete set up of window. */ x_color_allocate(); x_window_setup (w_current); #ifdef HAVE_LIBSTROKE x_stroke_init (); #endif /* HAVE_LIBSTROKE */ for (i = argv_index; i < argc; i++) { if (g_path_is_absolute(argv[i])) { /* Path is already absolute so no need to do any concat of cwd */ filename = g_strdup (argv[i]); } else { filename = g_build_filename (cwd, argv[i], NULL); } if ( first_page ) first_page = 0; /* * SDB notes: at this point the filename might be unnormalized, like * /path/to/foo/../bar/baz.sch. Bad filenames will be normalized in * f_open (called by x_window_open_page). This works for Linux and MINGW32. */ x_window_open_page(w_current, filename); g_free (filename); } g_free(cwd); /* If no page has been loaded (wasn't specified in the command line.) */ /* Then create an untitled page */ if ( first_page ) { x_window_open_page( w_current, NULL ); } /* Update the window to show the current page */ x_window_set_current_page( w_current, w_current->toplevel->page_current ); #if DEBUG scm_c_eval_string ("(display \"hello guile\n\")"); #endif /* Run post-load expressions */ g_scm_eval_protected (s_post_load_expr, scm_current_module ()); /* open up log window on startup */ if (w_current->log_window == MAP_ON_STARTUP) { x_log_open (); } /* if there were any symbols which had major changes, put up an error */ /* dialog box */ major_changed_dialog(w_current); scm_dynwind_end (); /* enter main loop */ gtk_main(); }