/*! \brief Setup icon search paths. * \par Function Description * Add the icons installed by gschem to the search path for the * default icon theme, so that they can be automatically found by GTK. */ void x_window_init_icons (void) { gchar *icon_path; g_return_if_fail (s_path_sys_data () != NULL); icon_path = g_build_filename (s_path_sys_data (), "icons", NULL); gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), icon_path); g_free (icon_path); }
/*! \brief Perform runtime initialization of libgeda library. * \par Function Description * This function is responsible for making sure that any runtime * initialization is done for all the libgeda routines. It should * be called before any other libgeda functions are called. * */ void libgeda_init(void) { #ifdef ENABLE_NLS /* Initialise gettext */ bindtextdomain (LIBGEDA_GETTEXT_DOMAIN, LOCALEDIR); bind_textdomain_codeset(LIBGEDA_GETTEXT_DOMAIN, "UTF-8"); #endif /* Initialise gobject */ g_type_init (); s_path_sys_data (); s_path_sys_config (); s_clib_init(); s_slib_init(); s_menu_init(); s_attrib_init(); s_color_init(); g_register_libgeda_funcs(); g_register_libgeda_dirs(); edascm_init (); }
/*! \brief Register some libgeda directories with Scheme. * \par Function Description * Ensures that the default gEDA Scheme directory is added to the * Guile load path. */ void g_register_libgeda_dirs (void) { char *scheme_dir; scheme_dir = g_build_filename (s_path_sys_data (), "scheme", NULL); g_rc_scheme_directory (scm_from_utf8_string (scheme_dir)); g_free (scheme_dir); }
/*! \brief Get the directory with the gEDA system configuration. * \par Function description * Returns the path to be searched for gEDA configuration shared * between all users. If the GEDADATARC environment variable is set, * returns its value; otherwise, uses a compiled-in path. Finally * fallback to using the system data path. * * \warning The returned string is owned by libgeda and should not be * modified or free'd. * * \todo On UNIX platforms we should follow the XDG Base Directory * Specification. * * \return the gEDA shared config path, or NULL if none could be * found. */ const char *s_path_sys_config () { static const char *p = NULL; /* If GEDADATARC is set in the environment, use that path */ if (p == NULL) { p = g_getenv ("GEDADATARC"); } if (p == NULL) { #if defined (GEDARCDIR) && !defined(_WIN32) /* If available, use the rc directory set during configure. */ p = GEDARCDIR; #else /* Otherwise, just use the data directory */ p = s_path_sys_data (); #endif } return p; }
/*! \brief Register some libgeda variables with scheme. * \par Function Description * Define some variables to be visible to Scheme. */ void g_register_libgeda_vars (void) { scm_c_define("geda-rc-path", scm_from_utf8_string (s_path_sys_config ())); scm_c_define("geda-data-path", scm_from_utf8_string (s_path_sys_data ())); scm_c_define("path-sep", scm_from_utf8_string(G_DIR_SEPARATOR_S)); scm_c_define("OBJ_LINE", SCM_MAKE_CHAR((unsigned char) OBJ_LINE)); scm_c_define("OBJ_BOX", SCM_MAKE_CHAR((unsigned char) OBJ_BOX)); scm_c_define("OBJ_PICTURE", SCM_MAKE_CHAR((unsigned char) OBJ_PICTURE)); scm_c_define("OBJ_CIRCLE", SCM_MAKE_CHAR((unsigned char) OBJ_CIRCLE)); scm_c_define("OBJ_NET", SCM_MAKE_CHAR((unsigned char) OBJ_NET)); scm_c_define("OBJ_BUS", SCM_MAKE_CHAR((unsigned char) OBJ_BUS)); scm_c_define("OBJ_COMPLEX", SCM_MAKE_CHAR((unsigned char) OBJ_COMPLEX)); scm_c_define("OBJ_TEXT", SCM_MAKE_CHAR((unsigned char) OBJ_TEXT)); scm_c_define("OBJ_PIN", SCM_MAKE_CHAR((unsigned char) OBJ_PIN)); scm_c_define("OBJ_ARC", SCM_MAKE_CHAR((unsigned char) OBJ_ARC)); scm_c_define("OBJ_PLACEHOLDER", SCM_MAKE_CHAR((unsigned char) OBJ_PLACEHOLDER)); scm_c_define("OBJ_PATH", SCM_MAKE_CHAR((unsigned char) OBJ_PATH)); }
/*! \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(); }