int main(int argc, char *argv[]) { GError *error = NULL; gtk_init(&argc, &argv); create_window(); gtk_widget_show_all(window); if(argc < 2) g_error("Must provide a plugin\n"); GFile *plugin_file; if( g_str_has_suffix(argv[1], ".la") ) plugin_file = libname_from_la_file(argv[1]); else plugin_file = g_file_new_for_commandline_arg(argv[1]); chimara_glk_set_resource_load_callback(CHIMARA_GLK(glk), (ChimaraResourceLoadFunc)resource_load, NULL, NULL); if( !chimara_glk_run_file(CHIMARA_GLK(glk), plugin_file, argc - 1, argv + 1, &error) ) g_error("Error starting Glk library: %s\n", error->message); g_object_unref(plugin_file); gtk_main(); chimara_glk_stop(CHIMARA_GLK(glk)); chimara_glk_wait(CHIMARA_GLK(glk)); g_object_unref(glk); return 0; }
int main(int argc, char *argv[]) { #ifdef ENABLE_NLS bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain(GETTEXT_PACKAGE); #endif gtk_init(&argc, &argv); /* Create configuration dir ~/.chimara */ gchar *configdir = g_build_filename(g_get_home_dir(), ".chimara", NULL); if(!g_file_test(configdir, G_FILE_TEST_IS_DIR) && g_mkdir(configdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) g_error("Cannot create configuration directory ~/.chimara"); g_free(configdir); /* Initialize settings file; it can be overridden by a "chimara-config" file in the current directory */ gchar *keyfile; if(g_file_test("chimara-config", G_FILE_TEST_IS_REGULAR)) keyfile = g_strdup("chimara-config"); else keyfile = g_build_filename(g_get_home_dir(), ".chimara", "config", NULL); GSettingsBackend *backend = g_keyfile_settings_backend_new(keyfile, "/org/chimara-if/player/", NULL); prefs_settings = g_settings_new_with_backend("org.chimara-if.player.preferences", backend); state_settings = g_settings_new_with_backend("org.chimara-if.player.state", backend); g_free(keyfile); app = gtk_application_new("org.chimara-if.player", G_APPLICATION_HANDLES_OPEN); g_signal_connect(app, "activate", G_CALLBACK(on_activate), NULL); g_signal_connect(app, "open", G_CALLBACK(on_open), NULL); if( !create_window() ) { error_dialog(NULL, NULL, "Error while building interface."); return 1; } int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); chimara_glk_stop(CHIMARA_GLK(glk)); chimara_glk_wait(CHIMARA_GLK(glk)); g_object_unref( G_OBJECT(builder) ); return status; }
int main(int argc, char **argv) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(window, 800, 500); g_signal_connect(window, "delete_event", G_CALLBACK(on_delete_event), NULL); GtkWidget *hpaned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); gtk_paned_set_position(GTK_PANED(hpaned), 400); GtkWidget *frotz = chimara_glk_new(); chimara_glk_set_css_from_string(CHIMARA_GLK(frotz), "buffer.normal { font-family: 'Lucida Sans'; font-size: 12; }" "grid.normal { font-family: 'Lucida Console'; font-size: 12; }"); g_signal_connect(frotz, "started", G_CALLBACK(on_started), "Frotz"); g_signal_connect(frotz, "stopped", G_CALLBACK(on_stopped), "Frotz"); GtkWidget *nitfol = chimara_glk_new(); chimara_glk_set_css_from_string(CHIMARA_GLK(frotz), "buffer.normal { font-family: 'Bitstream Charter'; font-size: 12; }" "grid.normal { font-family: 'Luxi Mono'; font-size: 12; }"); g_signal_connect(nitfol, "started", G_CALLBACK(on_started), "Nitfol"); g_signal_connect(nitfol, "stopped", G_CALLBACK(on_stopped), "Nitfol"); gtk_paned_pack1(GTK_PANED(hpaned), frotz, TRUE, TRUE); gtk_paned_pack2(GTK_PANED(hpaned), nitfol, TRUE, TRUE); gtk_container_add(GTK_CONTAINER(window), hpaned); gtk_widget_show_all(window); if(!chimara_glk_run(CHIMARA_GLK(frotz), "../interpreters/frotz/.libs/frotz.so", argc, argv, NULL)) return 1; if(!chimara_glk_run(CHIMARA_GLK(nitfol), "../interpreters/nitfol/.libs/nitfol.so", argc, argv, NULL)) return 1; gtk_main(); chimara_glk_stop(CHIMARA_GLK(frotz)); chimara_glk_stop(CHIMARA_GLK(nitfol)); return 0; }
static gboolean create_window(void) { GError *error = NULL; builder = gtk_builder_new(); if( !gtk_builder_add_from_file(builder, PACKAGE_DATA_DIR "/chimara.ui", &error) ) { #ifdef DEBUG g_error_free(error); error = NULL; if( !gtk_builder_add_from_file(builder, PACKAGE_SRC_DIR "/chimara.ui", &error) ) { #endif /* DEBUG */ return FALSE; #ifdef DEBUG } #endif /* DEBUG */ } window = GTK_WIDGET(load_object("chimara")); aboutwindow = GTK_WIDGET(load_object("aboutwindow")); prefswindow = GTK_WIDGET(load_object("prefswindow")); GtkActionGroup *actiongroup = GTK_ACTION_GROUP(load_object("actiongroup")); /* Set the default value of the "View/Toolbar" menu item upon creation of a new window to the "show-toolbar-default" setting, but bind the setting one-way only - we don't want toolbars to disappear suddenly */ GtkToggleAction *toolbar_action = GTK_TOGGLE_ACTION(load_object("toolbar")); gtk_toggle_action_set_active(toolbar_action, g_settings_get_boolean(state_settings, "show-toolbar-default")); g_settings_bind(state_settings, "show-toolbar-default", toolbar_action, "active", G_SETTINGS_BIND_SET); const gchar **ptr; GtkRecentFilter *filter = gtk_recent_filter_new(); /* TODO: Use mimetypes and construct the filter dynamically depending on what plugins are installed */ const gchar *patterns[] = { "*.z[1-8]", "*.[zg]lb", "*.[zg]blorb", "*.ulx", "*.blb", "*.blorb", NULL }; for(ptr = patterns; *ptr; ptr++) gtk_recent_filter_add_pattern(filter, *ptr); GtkRecentChooser *recent = GTK_RECENT_CHOOSER(load_object("recent")); gtk_recent_chooser_add_filter(recent, filter); uimanager = gtk_ui_manager_new(); if( !gtk_ui_manager_add_ui_from_file(uimanager, PACKAGE_DATA_DIR "/chimara.menus", &error) ) { #ifdef DEBUG g_error_free(error); error = NULL; if( !gtk_ui_manager_add_ui_from_file(uimanager, PACKAGE_SRC_DIR "/chimara.menus", &error) ) #endif /* DEBUG */ return FALSE; } glk = chimara_if_new(); g_object_set(glk, "ignore-errors", TRUE, /*"interpreter-number", CHIMARA_IF_ZMACHINE_TANDY_COLOR,*/ NULL); if( !chimara_glk_set_css_from_file(CHIMARA_GLK(glk), PACKAGE_DATA_DIR "/style.css", &error) ) { #ifdef DEBUG g_error_free(error); error = NULL; if( !chimara_glk_set_css_from_file(CHIMARA_GLK(glk), PACKAGE_SRC_DIR "/style.css", &error) ) #endif /* DEBUG */ return FALSE; } /* DON'T UNCOMMENT THIS your eyes will burn but it is a good test of programmatically altering just one style chimara_glk_set_css_from_string(CHIMARA_GLK(glk), "buffer { font-family: 'Comic Sans MS'; }");*/ GtkBox *vbox = GTK_BOX( gtk_builder_get_object(builder, "vbox") ); if(vbox == NULL) return FALSE; gtk_ui_manager_insert_action_group(uimanager, actiongroup, 0); GtkWidget *menubar = gtk_ui_manager_get_widget(uimanager, "/menubar"); toolbar = gtk_ui_manager_get_widget(uimanager, "/toolbar"); gtk_widget_set_no_show_all(toolbar, TRUE); if(gtk_toggle_action_get_active(toolbar_action)) gtk_widget_show(toolbar); else gtk_widget_hide(toolbar); /* Connect the accelerators */ GtkAccelGroup *accels = gtk_ui_manager_get_accel_group(uimanager); gtk_window_add_accel_group(GTK_WINDOW(window), accels); gtk_box_pack_end(vbox, glk, TRUE, TRUE, 0); gtk_box_pack_start(vbox, menubar, FALSE, FALSE, 0); gtk_box_pack_start(vbox, toolbar, FALSE, FALSE, 0); gtk_builder_connect_signals(builder, glk); g_signal_connect(glk, "notify::program-name", G_CALLBACK(change_window_title), window); g_signal_connect(glk, "notify::story-name", G_CALLBACK(change_window_title), window); /* Create preferences window */ preferences_create(CHIMARA_GLK(glk)); return TRUE; }
int main(int argc, char *argv[]) { GError *error = NULL; #ifdef ENABLE_NLS bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain(GETTEXT_PACKAGE); #endif gdk_threads_init(); gtk_init(&argc, &argv); /* Create configuration dir ~/.chimara */ gchar *configdir = g_build_filename(g_get_home_dir(), ".chimara", NULL); if(!g_file_test(configdir, G_FILE_TEST_IS_DIR) && g_mkdir(configdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) g_error(_("Cannot create configuration directory ~/.chimara")); g_free(configdir); /* Initialize settings file; it can be overridden by a "chimara-config" file in the current directory */ gchar *keyfile; if(g_file_test("chimara-config", G_FILE_TEST_IS_REGULAR)) keyfile = g_strdup("chimara-config"); else keyfile = g_build_filename(g_get_home_dir(), ".chimara", "config", NULL); GSettingsBackend *backend = g_keyfile_settings_backend_new(keyfile, "/org/chimara-if/player/", NULL); prefs_settings = g_settings_new_with_backend("org.chimara-if.player.preferences", backend); state_settings = g_settings_new_with_backend("org.chimara-if.player.state", backend); g_free(keyfile); if( !create_window() ) { error_dialog(NULL, NULL, "Error while building interface."); return 1; } gtk_widget_show_all(window); g_object_unref( G_OBJECT(uimanager) ); if(argc == 3) { g_object_set(glk, "graphics-file", argv[2], NULL); } if(argc >= 2) { if( !chimara_if_run_game(CHIMARA_IF(glk), argv[1], &error) ) { error_dialog(GTK_WINDOW(window), error, "Error starting Glk library: "); return 1; } } gdk_threads_enter(); gtk_main(); gdk_threads_leave(); chimara_glk_stop(CHIMARA_GLK(glk)); chimara_glk_wait(CHIMARA_GLK(glk)); g_object_unref( G_OBJECT(builder) ); return 0; }
static gboolean create_window(void) { GError *error = NULL; builder = gtk_builder_new_from_resource("/org/chimara-if/player/chimara.ui"); window = GTK_WIDGET(load_object("chimara")); aboutwindow = GTK_WIDGET(load_object("aboutwindow")); prefswindow = GTK_WIDGET(load_object("prefswindow")); recentwindow = GTK_WIDGET(load_object("recentwindow")); glk = chimara_if_new(); g_object_set(glk, "ignore-errors", TRUE, /*"interpreter-number", CHIMARA_IF_ZMACHINE_TANDY_COLOR,*/ NULL); GBytes *css_bytes = g_resources_lookup_data("/org/chimara-if/player/style.css", G_RESOURCE_LOOKUP_FLAGS_NONE, &error); if (!css_bytes) return FALSE; size_t len; char *css = g_bytes_unref_to_data(css_bytes, &len); chimara_glk_set_css_from_string(CHIMARA_GLK(glk), css); g_free(css); /* DON'T UNCOMMENT THIS your eyes will burn but it is a good test of programmatically altering just one style chimara_glk_set_css_from_string(CHIMARA_GLK(glk), "buffer { font-family: 'Comic Sans MS'; }");*/ GtkBox *vbox = GTK_BOX( gtk_builder_get_object(builder, "vbox") ); if(vbox == NULL) return FALSE; create_app_actions(G_ACTION_MAP(app), glk); create_window_actions(G_ACTION_MAP(window), glk); GtkWidget *toolbar = GTK_WIDGET(gtk_builder_get_object(builder, "toolbar")); /* Set the default value of the "View/Toolbar" menu item upon creation of a new window to the "show-toolbar-default" setting, but bind the setting one-way only - we don't want toolbars to disappear suddenly */ GPropertyAction *toolbar_action = g_property_action_new("toolbar", toolbar, "visible"); g_action_map_add_action(G_ACTION_MAP(window), G_ACTION(toolbar_action)); if (g_settings_get_boolean(state_settings, "show-toolbar-default")) gtk_widget_show(toolbar); else gtk_widget_hide(toolbar); g_settings_bind(state_settings, "show-toolbar-default", toolbar, "visible", G_SETTINGS_BIND_SET); gtk_box_pack_end(vbox, glk, TRUE, TRUE, 0); gtk_box_pack_start(vbox, toolbar, FALSE, FALSE, 0); gtk_builder_connect_signals(builder, glk); g_signal_connect(glk, "notify::program-name", G_CALLBACK(change_window_title), window); g_signal_connect(glk, "notify::story-name", G_CALLBACK(change_window_title), window); /* Create preferences window */ preferences_create(CHIMARA_GLK(glk)); return TRUE; }
/* Internal function: flush a window's text buffer to the screen. */ void flush_window_buffer(winid_t win) { #ifdef DEBUG_STYLES g_printf("%s\n", win->buffer->str); #endif if(win->type != wintype_TextBuffer && win->type != wintype_TextGrid) return; if(win->buffer->len == 0) return; gdk_threads_enter(); GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); switch(win->type) { case wintype_TextBuffer: { GtkTextIter start, end; gtk_text_buffer_get_end_iter(buffer, &end); gint start_offset; start_offset = gtk_text_iter_get_offset(&end); gtk_text_buffer_insert(buffer, &end, win->buffer->str, -1); gtk_text_buffer_get_iter_at_offset(buffer, &start, start_offset); style_apply(win, &start, &end); ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK)); g_assert(glk); g_signal_emit_by_name(glk, "text-buffer-output", win->rock, win->librock, win->buffer->str); } break; case wintype_TextGrid: { /* Number of characters to insert */ glong length = win->buffer->len; glong chars_left = length; GtkTextMark *cursor = gtk_text_buffer_get_mark(buffer, "cursor_position"); /* Get cursor position */ GtkTextIter start, insert; gint start_offset; gtk_text_buffer_get_iter_at_mark(buffer, &insert, cursor); while(chars_left > 0 && !gtk_text_iter_is_end(&insert)) { /* Spaces available on this line */ gint available_space = win->width - gtk_text_iter_get_line_offset(&insert); GtkTextIter end = insert; if(chars_left <= available_space) gtk_text_iter_forward_chars(&end, chars_left); else gtk_text_iter_forward_to_line_end(&end); gtk_text_buffer_delete(buffer, &insert, &end); start_offset = gtk_text_iter_get_offset(&insert); gtk_text_buffer_insert(buffer, &insert, win->buffer->str + (length - chars_left), MIN(chars_left, available_space)); gtk_text_buffer_get_iter_at_offset(buffer, &start, start_offset); style_apply(win, &start, &insert); chars_left -= available_space; if(gtk_text_iter_get_line_offset(&insert) >= win->width) gtk_text_iter_forward_line(&insert); } gtk_text_buffer_move_mark(buffer, cursor, &insert); } break; } gdk_threads_leave(); g_string_truncate(win->buffer, 0); }