--- BasiliskII/src/Unix/prefs_editor_gtk.cpp 2002/01/20 16:58:56 1.20 +++ BasiliskII/src/Unix/prefs_editor_gtk.cpp 2006/04/16 16:32:45 1.32 @@ -1,7 +1,7 @@ /* * prefs_editor_gtk.cpp - Preferences editor, Unix implementation using GTK+ * - * Basilisk II (C) 1997-2002 Christian Bauer + * Basilisk II (C) 1997-2005 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +28,10 @@ #include #include +#ifdef HAVE_GNOMEUI +#include +#endif + #include "user_strings.h" #include "version.h" #include "cdrom.h" @@ -48,6 +52,7 @@ static void create_graphics_pane(GtkWidg static void create_input_pane(GtkWidget *top); static void create_serial_pane(GtkWidget *top); static void create_memory_pane(GtkWidget *top); +static void create_jit_pane(GtkWidget *top); static void read_settings(void); @@ -55,11 +60,54 @@ static void read_settings(void); * Utility functions */ +#if ! GLIB_CHECK_VERSION(2,0,0) +#define G_OBJECT(obj) GTK_OBJECT(obj) +#define g_object_get_data(obj, key) gtk_object_get_data((obj), (key)) +#define g_object_set_data(obj, key, data) gtk_object_set_data((obj), (key), (data)) +#endif + struct opt_desc { int label_id; GtkSignalFunc func; }; +struct combo_desc { + int label_id; +}; + +struct file_req_assoc { + file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {} + GtkWidget *req; + GtkWidget *entry; +}; + +static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc) +{ + gchar *file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); + gtk_entry_set_text(GTK_ENTRY(assoc->entry), file); + gtk_widget_destroy(assoc->req); + delete assoc; +} + +static void cb_browse(GtkWidget *widget, void *user_data) +{ + GtkWidget *req = gtk_file_selection_new(GetString(STR_BROWSE_TITLE)); + gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(cb_browse_ok), new file_req_assoc(req, (GtkWidget *)user_data)); + gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); + gtk_widget_show(req); +} + +static GtkWidget *make_browse_button(GtkWidget *entry) +{ + GtkWidget *button; + + button = gtk_button_new_with_label(GetString(STR_BROWSE_CTRL)); + gtk_widget_show(button); + gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)cb_browse, (void *)entry); + return button; +} + static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func) { GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id)); @@ -123,6 +171,86 @@ static GtkWidget *make_table(GtkWidget * return table; } +static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active) +{ + GtkWidget *label, *opt, *menu; + + label = gtk_label_new(GetString(label_id)); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); + + opt = gtk_option_menu_new(); + gtk_widget_show(opt); + menu = gtk_menu_new(); + + while (options->label_id) { + add_menu_item(menu, options->label_id, options->func); + options++; + } + gtk_menu_set_active(GTK_MENU(menu), active); + + gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); + gtk_table_attach(GTK_TABLE(table), opt, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); + return menu; +} + +static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, GList *glist) +{ + GtkWidget *label, *combo; + char str[32]; + + label = gtk_label_new(GetString(label_id)); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); + + combo = gtk_combo_new(); + gtk_widget_show(combo); + gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); + + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value); + gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); + + return combo; +} + +static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, const combo_desc *options) +{ + GList *glist = NULL; + while (options->label_id) { + glist = g_list_append(glist, (void *)GetString(options->label_id)); + options++; + } + + return table_make_combobox(table, row, label_id, default_value, glist); +} + +static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id, const char *prefs_item, bool only_dirs = false) +{ + GtkWidget *box, *label, *entry, *button; + + label = gtk_label_new(GetString(label_id)); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); + + const char *str = PrefsFindString(prefs_item); + if (str == NULL) + str = ""; + + box = gtk_hbox_new(FALSE, 4); + gtk_widget_show(box); + gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4); + + entry = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(entry), str); + gtk_widget_show(entry); + gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); + + button = make_browse_button(entry); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + g_object_set_data(G_OBJECT(entry), "chooser_button", button); + return entry; +} + static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active) { GtkWidget *box, *label, *opt, *menu; @@ -150,7 +278,7 @@ static GtkWidget *make_option_menu(GtkWi return menu; } -static GtkWidget *make_entry(GtkWidget *top, int label_id, const char *prefs_item) +static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false) { GtkWidget *box, *label, *entry; @@ -162,16 +290,33 @@ static GtkWidget *make_entry(GtkWidget * gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - entry = gtk_entry_new(); - gtk_widget_show(entry); const char *str = PrefsFindString(prefs_item); if (str == NULL) str = ""; + +#ifdef HAVE_GNOMEUI + entry = gnome_file_entry_new(NULL, GetString(label_id)); + if (only_dirs) + gnome_file_entry_set_directory(GNOME_FILE_ENTRY(entry), true); + gtk_entry_set_text(GTK_ENTRY(gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(entry))), str); +#else + entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entry), str); +#endif + gtk_widget_show(entry); gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); return entry; } +static const gchar *get_file_entry_path(GtkWidget *entry) +{ +#ifdef HAVE_GNOMEUI + return gnome_file_entry_get_full_path(GNOME_FILE_ENTRY(entry), false); +#else + return gtk_entry_get_text(GTK_ENTRY(entry)); +#endif +} + static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func) { GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id)); @@ -182,7 +327,37 @@ static GtkWidget *make_checkbox(GtkWidge return button; } +static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *prefs_item, const combo_desc *options) +{ + GtkWidget *box, *label, *combo; + char str[32]; + + box = gtk_hbox_new(FALSE, 4); + gtk_widget_show(box); + gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0); + + label = gtk_label_new(GetString(label_id)); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + GList *glist = NULL; + while (options->label_id) { + glist = g_list_append(glist, (void *)GetString(options->label_id)); + options++; + } + + combo = gtk_combo_new(); + gtk_widget_show(combo); + gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist); + + sprintf(str, "%d", PrefsFindInt32(prefs_item)); + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str); + gtk_box_pack_start(GTK_BOX(box), combo, TRUE, TRUE, 0); + + return combo; +} + + /* * Show preferences editor * Returns true when user clicked on "Start", false otherwise @@ -225,12 +400,48 @@ static void dl_quit(GtkWidget *dialog) // "About" selected static void mn_about(...) { - GtkWidget *dialog, *label, *button; + GtkWidget *dialog; + +#ifdef HAVE_GNOMEUI + + char version[32]; + sprintf(version, "Version %d.%d", VERSION_MAJOR, VERSION_MINOR); + const char *authors[] = { + "Christian Bauer", + "Orlando Bassotto", + "Gwenolé Beauchesne", + "Marc Chabanas", + "Marc Hellwig", + "Biill Huey", + "Brian J. Johnson", + "Jürgen Lachmann", + "Samuel Lander", + "David Lawrence", + "Lauri Pesonen", + "Bernd Schmidt", + "and others", + NULL + }; + dialog = gnome_about_new( + "Basilisk II", + version, + "Copyright (C) 1997-2005 Christian Bauer", + authors, + "Basilisk II comes with ABSOLUTELY NO WARRANTY." + "This is free software, and you are welcome to redistribute it" + "under the terms of the GNU General Public License.", + NULL + ); + gnome_dialog_set_parent(GNOME_DIALOG(dialog), GTK_WINDOW(win)); + +#else + + GtkWidget *label, *button; char str[512]; sprintf(str, "Basilisk II\nVersion %d.%d\n\n" - "Copyright (C) 1997-2002 Christian Bauer et al.\n" + "Copyright (C) 1997-2005 Christian Bauer et al.\n" "E-mail: Christian.Bauer@uni-mainz.de\n" "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n" "Basilisk II comes with ABSOLUTELY NO\n" @@ -256,6 +467,9 @@ static void mn_about(...) gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); gtk_widget_grab_default(button); + +#endif + gtk_widget_show(dialog); } @@ -268,7 +482,7 @@ static void mn_zap_pram(...) // Menu item descriptions static GtkItemFactoryEntry menu_items[] = { {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, ""}, - {(gchar *)GetString(STR_PREFS_ITEM_START_GTK), NULL, GTK_SIGNAL_FUNC(cb_start), 0, NULL}, + {(gchar *)GetString(STR_PREFS_ITEM_START_GTK), "S", GTK_SIGNAL_FUNC(cb_start), 0, NULL}, {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, GTK_SIGNAL_FUNC(mn_zap_pram), 0, NULL}, {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, ""}, {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL}, @@ -292,7 +506,11 @@ bool PrefsEditor(void) GtkAccelGroup *accel_group = gtk_accel_group_new(); GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "
", accel_group); gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL); +#if GTK_CHECK_VERSION(1,3,15) + gtk_window_add_accel_group(GTK_WINDOW(win), accel_group); +#else gtk_accel_group_attach(accel_group, GTK_OBJECT(win)); +#endif GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "
"); gtk_widget_show(menu_bar); gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0); @@ -309,6 +527,7 @@ bool PrefsEditor(void) create_input_pane(notebook); create_serial_pane(notebook); create_memory_pane(notebook); + create_jit_pane(notebook); static const opt_desc buttons[] = { {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)}, @@ -337,16 +556,10 @@ static void cl_selected(GtkWidget *list, selected_volume = row; } -struct file_req_assoc { - file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {} - GtkWidget *req; - GtkWidget *entry; -}; - // Volume selected for addition static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc) { - char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); + gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); gtk_clist_append(GTK_CLIST(volume_list), &file); gtk_widget_destroy(assoc->req); delete assoc; @@ -355,9 +568,9 @@ static void add_volume_ok(GtkWidget *but // Volume selected for creation static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc) { - char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); + gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); - char *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry)); + const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry)); int size = atoi(str); char cmd[1024]; @@ -431,7 +644,7 @@ static void read_volumes_settings(void) PrefsAddString("disk", str); } - PrefsReplaceString("extfs", gtk_entry_get_text(GTK_ENTRY(w_extfs))); + PrefsReplaceString("extfs", get_file_entry_path(w_extfs)); } // Create "Volumes" pane @@ -452,7 +665,7 @@ static void create_volumes_pane(GtkWidge gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL); char *str; int32 index = 0; - while ((str = (char *)PrefsFindString("disk", index++)) != NULL) + while ((str = const_cast(PrefsFindString("disk", index++))) != NULL) gtk_clist_append(GTK_CLIST(volume_list), &str); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list); gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0); @@ -467,7 +680,7 @@ static void create_volumes_pane(GtkWidge make_button_box(box, 0, buttons); make_separator(box); - w_extfs = make_entry(box, STR_EXTFS_CTRL, "extfs"); + w_extfs = make_file_entry(box, STR_EXTFS_CTRL, "extfs", true); static const opt_desc options[] = { {STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)}, @@ -486,6 +699,95 @@ static void create_volumes_pane(GtkWidge /* + * "JIT Compiler" pane + */ + +static GtkWidget *w_jit_fpu; +static GtkWidget *w_jit_atraps; +static GtkWidget *w_jit_cache_size; +static GtkWidget *w_jit_lazy_flush; +static GtkWidget *w_jit_follow_const_jumps; + +// Set sensitivity of widgets +static void set_jit_sensitive(void) +{ + const bool jit_enabled = PrefsFindBool("jit"); + gtk_widget_set_sensitive(w_jit_fpu, jit_enabled); + gtk_widget_set_sensitive(w_jit_cache_size, jit_enabled); + gtk_widget_set_sensitive(w_jit_lazy_flush, jit_enabled); + gtk_widget_set_sensitive(w_jit_follow_const_jumps, jit_enabled); +} + +// "Use JIT Compiler" button toggled +static void tb_jit(GtkWidget *widget) +{ + PrefsReplaceBool("jit", GTK_TOGGLE_BUTTON(widget)->active); + set_jit_sensitive(); +} + +// "Compile FPU Instructions" button toggled +static void tb_jit_fpu(GtkWidget *widget) +{ + PrefsReplaceBool("jitfpu", GTK_TOGGLE_BUTTON(widget)->active); +} + +// "Lazy translation cache invalidation" button toggled +static void tb_jit_lazy_flush(GtkWidget *widget) +{ + PrefsReplaceBool("jitlazyflush", GTK_TOGGLE_BUTTON(widget)->active); +} + +// "Translate through constant jumps (inline blocks)" button toggled +static void tb_jit_follow_const_jumps(GtkWidget *widget) +{ + PrefsReplaceBool("jitinline", GTK_TOGGLE_BUTTON(widget)->active); +} + +// Read settings from widgets and set preferences +static void read_jit_settings(void) +{ +#if USE_JIT + bool jit_enabled = PrefsFindBool("jit"); + if (jit_enabled) { + const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry)); + PrefsReplaceInt32("jitcachesize", atoi(str)); + } +#endif +} + +// Create "JIT Compiler" pane +static void create_jit_pane(GtkWidget *top) +{ +#if USE_JIT + GtkWidget *box, *table, *label, *menu; + char str[32]; + + box = make_pane(top, STR_JIT_PANE_TITLE); + make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit)); + + w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", GTK_SIGNAL_FUNC(tb_jit_fpu)); + + // Translation cache size + static const combo_desc options[] = { + STR_JIT_CACHE_SIZE_2MB_LAB, + STR_JIT_CACHE_SIZE_4MB_LAB, + STR_JIT_CACHE_SIZE_8MB_LAB, + STR_JIT_CACHE_SIZE_16MB_LAB, + 0 + }; + w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, "jitcachesize", options); + + // Lazy translation cache invalidation + w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", GTK_SIGNAL_FUNC(tb_jit_lazy_flush)); + + // Follow constant jumps (inline basic blocks) + w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps)); + + set_jit_sensitive(); +#endif +} + +/* * "SCSI" pane */ @@ -497,7 +799,7 @@ static void read_scsi_settings(void) for (int id=0; id<7; id++) { char prefs_name[32]; sprintf(prefs_name, "scsi%d", id); - const char *str = gtk_entry_get_text(GTK_ENTRY(w_scsi[id])); + const char *str = get_file_entry_path(w_scsi[id]); if (str && strlen(str)) PrefsReplaceString(prefs_name, str); else @@ -515,7 +817,7 @@ static void create_scsi_pane(GtkWidget * for (int id=0; id<7; id++) { char prefs_name[32]; sprintf(prefs_name, "scsi%d", id); - w_scsi[id] = make_entry(box, STR_SCSI_ID_0 + id, prefs_name); + w_scsi[id] = make_file_entry(box, STR_SCSI_ID_0 + id, prefs_name); } } @@ -541,6 +843,8 @@ static GtkWidget *l_fbdev_name, *l_fbdev static char fbdev_name[256]; #endif +static GtkWidget *w_dspdevice_file, *w_mixerdevice_file; + // Hide/show graphics widgets static void hide_show_graphics_widgets(void) { @@ -587,10 +891,19 @@ static void mn_30hz(...) {PrefsReplaceIn static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);} static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);} +// Set sensitivity of widgets +static void set_graphics_sensitive(void) +{ + const bool sound_enabled = !PrefsFindBool("nosound"); + gtk_widget_set_sensitive(w_dspdevice_file, sound_enabled); + gtk_widget_set_sensitive(w_mixerdevice_file, sound_enabled); +} + // "Disable Sound Output" button toggled static void tb_nosound(GtkWidget *widget) { PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active); + set_graphics_sensitive(); } // Read graphics preferences @@ -645,6 +958,16 @@ static void read_graphics_settings(void) return; } PrefsReplaceString("screen", pref); + +#ifdef ENABLE_FBDEV_DGA + str = get_file_entry_path(w_fbdevice_file); + if (str && strlen(str)) + PrefsReplaceString("fbdevicefile", str); + else + PrefsRemoveItem("fbdevicefile"); +#endif + PrefsReplaceString("dsp", get_file_entry_path(w_dspdevice_file)); + PrefsReplaceString("mixer", get_file_entry_path(w_mixerdevice_file)); } // Create "Graphics/Sound" pane @@ -760,11 +1083,15 @@ static void create_graphics_pane(GtkWidg gtk_entry_set_text(GTK_ENTRY(w_fbdev_name), fbdev_name); gtk_table_attach(GTK_TABLE(table), w_fbdev_name, 1, 2, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - w_fbdevice_file = make_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile"); + w_fbdevice_file = make_file_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile"); #endif make_separator(box); make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound)); + w_dspdevice_file = make_file_entry(box, STR_DSPDEVICE_FILE_CTRL, "dsp"); + w_mixerdevice_file = make_file_entry(box, STR_MIXERDEVICE_FILE_CTRL, "mixer"); + + set_graphics_sensitive(); hide_show_graphics_widgets(); } @@ -780,7 +1107,9 @@ static GtkWidget *w_mouse_wheel_lines; // Set sensitivity of widgets static void set_input_sensitive(void) { - gtk_widget_set_sensitive(w_keycode_file, PrefsFindBool("keycodes")); + const bool use_keycodes = PrefsFindBool("keycodes"); + gtk_widget_set_sensitive(w_keycode_file, use_keycodes); + gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_keycode_file), "chooser_button")), use_keycodes); gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1); } @@ -798,7 +1127,7 @@ static void mn_wheel_cursor(...) {PrefsR // Read settings from widgets and set preferences static void read_input_settings(void) { - const char *str = gtk_entry_get_text(GTK_ENTRY(w_keycode_file)); + const char *str = get_file_entry_path(w_keycode_file); if (str && strlen(str)) PrefsReplaceString("keycodefile", str); else @@ -810,13 +1139,33 @@ static void read_input_settings(void) // Create "Input" pane static void create_input_pane(GtkWidget *top) { - GtkWidget *box, *hbox, *menu, *label; + GtkWidget *box, *hbox, *menu, *label, *button; GtkObject *adj; box = make_pane(top, STR_INPUT_PANE_TITLE); make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes)); - w_keycode_file = make_entry(box, STR_KEYCODE_FILE_CTRL, "keycodefile"); + + hbox = gtk_hbox_new(FALSE, 4); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0); + + label = gtk_label_new(GetString(STR_KEYCODES_CTRL)); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + const char *str = PrefsFindString("keycodefile"); + if (str == NULL) + str = ""; + + w_keycode_file = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str); + gtk_widget_show(w_keycode_file); + gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0); + + button = make_browse_button(w_keycode_file); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button); make_separator(box); @@ -964,6 +1313,10 @@ static GList *add_ether_names(void) } close(s); } +#ifdef HAVE_SLIRP + static char s_slirp[] = "slirp"; + glist = g_list_append(glist, s_slirp); +#endif if (glist) g_list_sort(glist, gl_str_cmp); else @@ -1053,9 +1406,17 @@ static void create_serial_pane(GtkWidget * "Memory/Misc" pane */ -static GtkObject *w_ramsize_adj; +static GtkWidget *w_ramsize; static GtkWidget *w_rom_file; +// "Ignore SEGV" button toggled +#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION +static void tb_ignoresegv(GtkWidget *widget) +{ + PrefsReplaceBool("ignoresegv", GTK_TOGGLE_BUTTON(widget)->active); +} +#endif + // Model ID selected static void mn_modelid_5(...) {PrefsReplaceInt32("modelid", 5);} static void mn_modelid_14(...) {PrefsReplaceInt32("modelid", 14);} @@ -1070,9 +1431,10 @@ static void mn_cpu_68040(...) {PrefsRepl // Read settings from widgets and set preferences static void read_memory_settings(void) { - PrefsReplaceInt32("ramsize", int(GTK_ADJUSTMENT(w_ramsize_adj)->value) << 20); + const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_ramsize)->entry)); + PrefsReplaceInt32("ramsize", atoi(str) << 20); - const char *str = gtk_entry_get_text(GTK_ENTRY(w_rom_file)); + str = get_file_entry_path(w_rom_file); if (str && strlen(str)) PrefsReplaceString("rom", str); else @@ -1083,47 +1445,27 @@ static void read_memory_settings(void) // Create "Memory/Misc" pane static void create_memory_pane(GtkWidget *top) { - GtkWidget *box, *hbox, *vbox, *hbox2, *label, *scale; + GtkWidget *box, *hbox, *table, *label, *menu; box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE); + table = make_table(box, 2, 5); - hbox = gtk_hbox_new(FALSE, 4); - gtk_widget_show(hbox); - - label = gtk_label_new(GetString(STR_RAMSIZE_SLIDER)); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - vbox = gtk_vbox_new(FALSE, 4); - gtk_widget_show(vbox); - - gfloat min, max; - min = 1; - max = 1024; - w_ramsize_adj = gtk_adjustment_new(min, min, max, 1, 16, 0); - gtk_adjustment_set_value(GTK_ADJUSTMENT(w_ramsize_adj), PrefsFindInt32("ramsize") >> 20); - - scale = gtk_hscale_new(GTK_ADJUSTMENT(w_ramsize_adj)); - gtk_widget_show(scale); - gtk_scale_set_digits(GTK_SCALE(scale), 0); - gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0); - - hbox2 = gtk_hbox_new(FALSE, 4); - gtk_widget_show(hbox2); - - char val[32]; - sprintf(val, GetString(STR_RAMSIZE_FMT), int(min)); - label = gtk_label_new(val); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); - - sprintf(val, GetString(STR_RAMSIZE_FMT), int(max)); - label = gtk_label_new(val); - gtk_widget_show(label); - gtk_box_pack_end(GTK_BOX(hbox2), label, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0); + static const combo_desc options[] = { + STR_RAMSIZE_2MB_LAB, + STR_RAMSIZE_4MB_LAB, + STR_RAMSIZE_8MB_LAB, + STR_RAMSIZE_16MB_LAB, + STR_RAMSIZE_32MB_LAB, + STR_RAMSIZE_64MB_LAB, + STR_RAMSIZE_128MB_LAB, + STR_RAMSIZE_256MB_LAB, + STR_RAMSIZE_512MB_LAB, + STR_RAMSIZE_1024MB_LAB, + 0 + }; + char default_ramsize[10]; + sprintf(default_ramsize, "%d", PrefsFindInt32("ramsize") >> 20); + w_ramsize = table_make_combobox(table, 0, STR_RAMSIZE_CTRL, default_ramsize, options); static const opt_desc model_options[] = { {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)}, @@ -1135,7 +1477,7 @@ static void create_memory_pane(GtkWidget case 5: active = 0; break; case 14: active = 1; break; } - make_option_menu(box, STR_MODELID_CTRL, model_options, active); + table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active); #if EMULATED_68K static const opt_desc cpu_options[] = { @@ -1154,10 +1496,14 @@ static void create_memory_pane(GtkWidget case 3: active = fpu ? 3 : 2; break; case 4: active = 4; } - make_option_menu(box, STR_CPU_CTRL, cpu_options, active); + table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active); #endif - w_rom_file = make_entry(box, STR_ROM_FILE_CTRL, "rom"); + w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom"); + +#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION + make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv)); +#endif } @@ -1173,4 +1519,112 @@ static void read_settings(void) read_input_settings(); read_serial_settings(); read_memory_settings(); + read_jit_settings(); +} + + +#ifdef STANDALONE_GUI +#include + +/* + * Fake unused data and functions + */ + +uint8 XPRAM[XPRAM_SIZE]; +void MountVolume(void *fh) { } +void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { } +void WarningAlert(const char *text) { } + + +/* + * Display alert + */ + +static void dl_destroyed(void) +{ + gtk_main_quit(); } + +static void display_alert(int title_id, int prefix_id, int button_id, const char *text) +{ + char str[256]; + sprintf(str, GetString(prefix_id), text); + + GtkWidget *dialog = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id)); + gtk_container_border_width(GTK_CONTAINER(dialog), 5); + gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); + gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL); + + GtkWidget *label = gtk_label_new(str); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); + + GtkWidget *button = gtk_button_new_with_label(GetString(button_id)); + gtk_widget_show(button); + gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_widget_grab_default(button); + gtk_widget_show(dialog); + + gtk_main(); +} + + +/* + * Display error alert + */ + +static void ErrorAlert(const char *text) +{ + display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text); +} + + +/* + * Start standalone GUI + */ + +int main(int argc, char *argv[]) +{ +#ifdef HAVE_GNOMEUI + // Init GNOME/GTK + char version[16]; + sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR); + gnome_init("Basilisk II", version, argc, argv); +#else + // Init GTK + gtk_set_locale(); + gtk_init(&argc, &argv); +#endif + + // Read preferences + PrefsInit(argc, argv); + + // Show preferences editor + bool start = PrefsEditor(); + + // Exit preferences + PrefsExit(); + + // Transfer control to the executable + if (start) { + char b2_path[PATH_MAX]; + strcpy(b2_path, argv[0]); + char *p = strrchr(b2_path, '/'); + p = p ? p + 1 : b2_path; + *p = '\0'; + strcat(b2_path, "BasiliskII"); + argv[0] = b2_path; + execv(b2_path, argv); + + char str[256]; + sprintf(str, GetString(STR_NO_B2_EXE_FOUND), b2_path, strerror(errno)); + ErrorAlert(str); + return 1; + } + + return 0; +} +#endif