int main(int argc, char *argv[]) { gboolean root_override=FALSE, open_in_new_window = FALSE; GList *filenames = NULL, *projectfiles=NULL; gint linenumber = -1; Tbfwin *firstbfwin; #ifndef NOSPLASH GtkWidget *splash_window; #endif /* #ifndef NOSPLASH */ #ifdef ENABLE_NLS setlocale(LC_ALL,""); bindtextdomain(PACKAGE,LOCALEDIR); DEBUG_MSG("set bindtextdomain for %s to %s\n",PACKAGE,LOCALEDIR); bind_textdomain_codeset(PACKAGE, "UTF-8"); textdomain(PACKAGE); #endif #ifdef HAVE_ATLEAST_GNOMEUI_2_6 gnome_init(PACKAGE, VERSION, argc, argv); #else gtk_init(&argc, &argv); #endif /* HAVE_ATLEAST_GNOMEUI_2_6 */ main_v = g_new0(Tmain, 1); main_v->session = g_new0(Tsessionvars,1); DEBUG_MSG("main, main_v is at %p\n", main_v); rcfile_check_directory(); rcfile_parse_main(); parse_commandline(argc, argv, &root_override, &filenames, &projectfiles, &open_in_new_window, &linenumber); #ifdef WITH_MSG_QUEUE if (((filenames || projectfiles) && (main_v->props.view_bars & MODE_REUSE_WINDOW)) || open_in_new_window) { msg_queue_start(filenames, projectfiles, linenumber, open_in_new_window); } #endif /* WITH_MSG_QUEUE */ #ifndef NOSPLASH /* start splash screen somewhere here */ splash_window = start_splash_screen(); splash_screen_set_label(_("parsing highlighting file...")); #endif /* #ifndef NOSPLASH */ { gchar *filename = g_strconcat(g_get_home_dir(), "/.winefish/dir_history", NULL); main_v->recent_directories = get_stringlist(filename, NULL); g_free(filename); } rcfile_parse_global_session(); rcfile_parse_highlighting(); #ifndef NOSPLASH splash_screen_set_label(_("compiling highlighting patterns...")); #endif /* #ifndef NOSPLASH */ hl_init(); #ifndef NOSPLASH splash_screen_set_label(_("initialize some other things...")); #endif /* #ifndef NOSPLASH */ filebrowserconfig_init(); filebrowser_filters_rebuild(); autoclosing_init(); #ifndef NOSPLASH splash_screen_set_label(_("parsing autotext and words file...")); #endif /* #ifndef NOSPLASH */ autotext_init(); completion_init(); #ifndef NOSPLASH splash_screen_set_label(_("parsing custom menu file...")); #endif /* #ifndef NOSPLASH */ rcfile_parse_custom_menu(FALSE,FALSE); #ifdef SNOOPER2 #ifndef NOSPLASH splash_screen_set_label(_("parsing keymap and initializing function list...")); #endif /* #ifndef NOSPLASH */ funclist_init(); keymap_init(); #endif /* SNOOPER2 */ main_v->tooltips = gtk_tooltips_new(); /* initialize the completion window */ /* main_v->completion.window = NULL; */ fref_init(); bmark_init(); #ifdef WITH_MSG_QUEUE if (!filenames && !projectfiles && (main_v->props.view_bars & MODE_REUSE_WINDOW)) { msg_queue_start(NULL, NULL, -1, open_in_new_window); } #endif /* WITH_MSG_QUEUE */ #ifndef NOSPLASH splash_screen_set_label(_("creating main gui...")); #endif /* #ifndef NOSPLASH */ /* create the first window */ firstbfwin = g_new0(Tbfwin,1); firstbfwin->session = main_v->session; firstbfwin->bookmarkstore = main_v->bookmarkstore; main_v->bfwinlist = g_list_append(NULL, firstbfwin); gui_create_main(firstbfwin, filenames, linenumber); bmark_reload(firstbfwin); #ifndef NOSPLASH splash_screen_set_label(_("showing main gui...")); #endif /* #ifndef NOSPLASH */ /* set GTK settings, must be AFTER the menu is created */ { gchar *shortcutfilename; GtkSettings* gtksettings = gtk_settings_get_default(); g_object_set(G_OBJECT(gtksettings), "gtk-can-change-accels", TRUE, NULL); shortcutfilename = g_strconcat(g_get_home_dir(), "/.winefish/menudump_2", NULL); gtk_accel_map_load(shortcutfilename); g_free(shortcutfilename); } gui_show_main(firstbfwin); /* if (main_v->props.view_html_toolbar && main_v->globses.quickbar_items == NULL) { info_dialog(firstbfwin->main_window, _("Winefish tip:"), _("This message is shown since you DONOT have any items in the QuickBar.\n\nIf you right-click a button in the Standard toolbars you can add buttons to the Quickbar.")); } */ if (projectfiles) { GList *tmplist = g_list_first(projectfiles); while (tmplist) { project_open_from_file(firstbfwin, tmplist->data, linenumber); tmplist = g_list_next(tmplist); } } #ifndef NOSPLASH DEBUG_MSG("destroy splash\n"); flush_queue(); { static struct timespec const req = { 0, 10000000}; nanosleep(&req, NULL); } gtk_widget_destroy(splash_window); #endif /* #ifndef NOSPLASH */ /* snooper must be installed after the main gui has shown; otherwise the program may be aborted */ #ifndef SNOOPER2 snooper_install(); #endif /* SNOOPER2 */ DEBUG_MSG("main, before gtk_main()\n"); gtk_main(); DEBUG_MSG("main, after gtk_main()\n"); #ifdef WITH_MSG_QUEUE /* do the cleanup */ msg_queue_cleanup(); #endif /* WITH_MSG_QUEUE */ DEBUG_MSG("Winefish: exiting cleanly\n"); return 0; }
/** * msg_queue_check: * * checks the queue for any messages * this is called by the master program, usually by gtk_timeout_add() * the messages it will listen to are the types: * - MSG_QUEUE_ASK_ALIVE - we should respond with a type MSG_QUEUE_SEND_ALIVE * - MSG_QUEUE_OPENFILE - open a filename * - MSG_QUEUE_OPENPROJECT - open a filename as project * - MSG_QUEUE_OPENNEWWIN - open a new window */ static gboolean msg_queue_check(gint started_by_gtk_timeout) { struct msgbuf { long mtype; char mtext[MSQ_QUEUE_SIZE]; } msgp; gint retval; if (main_v->bfwinlist == NULL || BFWIN(main_v->bfwinlist->data)->documentlist == NULL) { DEBUG_MSG("msg_queue_check, no documentlist yet, so we do not continue\n"); return TRUE; } if (msg_queue.msgid == -1) { return FALSE; } retval = msgrcv(msg_queue.msgid, &msgp, MSQ_QUEUE_SIZE, -MSG_QUEUE_OPENFILE, IPC_NOWAIT); if (retval != -1) { DEBUG_MSG("msg_queue_check, found type %ld\n", msgp.mtype); if (msgp.mtype == MSG_QUEUE_ASK_ALIVE) { struct small_msgbuf { long mtype; char mtext[MSQ_QUEUE_SMALL_SIZE]; } small_msgp; DEBUG_MSG("msg_queue_check, a keepalive is asked from %s, sending!\n", msgp.mtext); small_msgp.mtype = MSG_QUEUE_SEND_ALIVE; strncpy(small_msgp.mtext, msgp.mtext, MSQ_QUEUE_SMALL_SIZE - 1); msgsnd(msg_queue.msgid, (void *) &small_msgp, MSQ_QUEUE_SMALL_SIZE * sizeof(char), IPC_NOWAIT); } else if (msgp.mtype == MSG_QUEUE_OPENFILE) { GList *lastlist = g_list_last(main_v->bfwinlist); gboolean delay_activate = TRUE; if (g_list_length(BFWIN(lastlist->data)->documentlist) < 2 && doc_is_empty_non_modified_and_nameless(BFWIN(lastlist->data)->current_document)) { delay_activate = FALSE; } DEBUG_MSG("msg_queue_check, a filename %s is received\n", msgp.mtext); if (!doc_new_with_file(BFWIN(lastlist->data),msgp.mtext, delay_activate, FALSE)) { msg_queue.file_error_list = g_list_append(msg_queue.file_error_list, g_strdup(msgp.mtext)); } msg_queue_check(0); /* call myself again, there may have been multiple files */ if (started_by_gtk_timeout) { if (msg_queue.file_error_list) { gchar *message, *tmp; tmp = stringlist_to_string(msg_queue.file_error_list, "\n"); free_stringlist(msg_queue.file_error_list); msg_queue.file_error_list = NULL; message = g_strconcat(_("These files were not opened:\n"), tmp, NULL); g_free(tmp); warning_dialog(BFWIN(main_v->bfwinlist->data)->main_window,_("Unable to open file(s)\n"), message); g_free(message); } /* gtk_notebook_set_page(GTK_NOTEBOOK(main_v->notebook),g_list_length(main_v->documentlist) - 1); notebook_changed(-1);*/ } } else if (msgp.mtype == MSG_QUEUE_OPENPROJECT) { GList *lastlist = g_list_last(main_v->bfwinlist); DEBUG_MSG("msg_queue_check, a project %s is received\n", msgp.mtext); project_open_from_file(BFWIN(lastlist->data), msgp.mtext); msg_queue_check(0); /* call myself again, there may have been multiple projects */ } else if (msgp.mtype == MSG_QUEUE_OPENNEWWIN) { /* now check if this is indeed send by another process if the message queue was dead during the startup of this process, it might be started by this very process */ int otherpid = atoi(msgp.mtext); DEBUG_MSG("msg_queue_check, a new window is requested by PID=%d\n",otherpid); if (otherpid != (int) getpid()) { DEBUG_MSG("msg_queue_check, the PID is not ours, opening new window\n"); gui_new_window(NULL, NULL); } } #ifdef DEBUG else { DEBUG_MSG("msg_queue_check, unknown message queue type %ld\n", msgp.mtype); } #endif } else { #ifdef MSG_QUEUE_DEBUG DEBUG_MSG("msg_queue_check, found errno(%d)=%s\n", errno, g_strerror(errno)); #endif /* 43 = Identifier removed */ if (errno == 22 || errno == 43) { DEBUG_MSG("msg_queue_check, re-opening message queue ?!?!?\n"); /* the msg_queue was removed !?!?! */ if (msg_queue_open()) { DEBUG_MSG("msg_queue_check, another process has opened the message_queue, stopping server\n"); msg_queue.server = FALSE; return FALSE; } } } return TRUE; }