GTK2: Replace file chooser dialogs and about dialogs

The GtkFileChooserDialog API makes it easier to select files and
folders. Additionally Browse buttons have been added to all file
entry fields.
This commit is contained in:
robxnano 2022-10-01 17:04:43 +01:00
parent 0083bc7ea7
commit a9d1f35cdf
6 changed files with 409 additions and 297 deletions

View File

@ -77,36 +77,58 @@ 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)
// User closed the file chooser dialog, possibly selecting a file
static void cb_browse_response(GtkWidget *chooser, int response, GtkEntry *entry)
{
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;
if (response == GTK_RESPONSE_ACCEPT)
{
gchar *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
gtk_entry_set_text(GTK_ENTRY(entry), filename);
g_free (filename);
}
gtk_widget_destroy (chooser);
}
static void cb_browse(GtkWidget *widget, void *user_data)
// Open the file chooser dialog to select a file
static void cb_browse(GtkWidget *button, GtkWidget *entry)
{
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);
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_BROWSE_TITLE),
GTK_WINDOW(win),
GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL,
"Open", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_ACCEPT);
gtk_window_set_transient_for(GTK_WINDOW(chooser), GTK_WINDOW(win));
gtk_window_set_modal(GTK_WINDOW(chooser), true);
g_signal_connect(chooser, "response", G_CALLBACK(cb_browse_response), GTK_ENTRY(entry));
gtk_widget_show(chooser);
}
static GtkWidget *make_browse_button(GtkWidget *entry)
// Open the file chooser dialog to select a folder
static void cb_browse_dir(GtkWidget *button, GtkWidget *entry)
{
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_BROWSE_FOLDER_TITLE),
GTK_WINDOW(win),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
"Cancel", GTK_RESPONSE_CANCEL,
"Select", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_ACCEPT);
gtk_window_set_transient_for(GTK_WINDOW(chooser), GTK_WINDOW(win));
gtk_window_set_modal(GTK_WINDOW(chooser), true);
g_signal_connect(chooser, "response", G_CALLBACK(cb_browse_response), GTK_WIDGET(entry));
gtk_widget_show(chooser);
}
static GtkWidget *make_browse_button(GtkWidget *entry, bool only_dirs)
{
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);
g_signal_connect(button, "clicked", only_dirs ? G_CALLBACK(cb_browse_dir) : G_CALLBACK(cb_browse), entry);
return button;
}
@ -114,7 +136,7 @@ static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
{
GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id));
gtk_widget_show(item);
gtk_signal_connect(GTK_OBJECT(item), "activate", func, NULL);
g_signal_connect(item, "activate", func, NULL);
gtk_menu_append(GTK_MENU(menu), item);
}
@ -150,7 +172,7 @@ static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *bu
while (buttons->label_id) {
button = gtk_button_new_with_label(GetString(buttons->label_id));
gtk_widget_show(button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL);
g_signal_connect_object(button, "clicked", buttons->func, NULL, (GConnectFlags) 0);
gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0);
buttons++;
}
@ -246,7 +268,7 @@ static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id,
gtk_widget_show(entry);
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
button = make_browse_button(entry);
button = make_browse_button(entry, false);
gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(entry), "chooser_button", button);
return entry;
@ -281,7 +303,7 @@ static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc
static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false)
{
GtkWidget *box, *label, *entry;
GtkWidget *box, *label, *entry, *button;
box = gtk_hbox_new(FALSE, 4);
gtk_widget_show(box);
@ -297,8 +319,14 @@ static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *pref
entry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry), str);
button = make_browse_button(entry, only_dirs);
gtk_widget_show(entry);
#if GLIB_CHECK_VERSION(2,26,0)
g_object_bind_property(entry, "sensitive", button, "sensitive", G_BINDING_SYNC_CREATE);
#endif
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
return entry;
}
@ -312,7 +340,7 @@ static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_
GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
gtk_widget_show(button);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item));
gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
g_signal_connect(button, "toggled", func, NULL);
gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
return button;
}
@ -391,7 +419,6 @@ static void dl_quit(GtkWidget *dialog)
static void mn_about(...)
{
GtkWidget *dialog, *label, *button;
const char *authors[] = {
"Christian Bauer",
"Orlando Bassotto",
@ -408,38 +435,18 @@ static void mn_about(...)
"and others",
NULL
};
char str[512];
sprintf(str,
"Basilisk II\nVersion %d.%d\n\n"
"Copyright (C) 1997-2008 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"
"WARRANTY. This is free software, and\n"
"you are welcome to redistribute it\n"
"under the terms of the GNU General\n"
"Public License.\n",
VERSION_MAJOR, VERSION_MINOR
);
dialog = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE));
gtk_container_border_width(GTK_CONTAINER(dialog), 5);
gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
label = gtk_label_new(str);
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
button = gtk_button_new_with_label(GetString(STR_OK_BUTTON));
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);
char version[64];
sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR);
gtk_show_about_dialog(GTK_WINDOW(win), "version", version,
"copyright", GetString(STR_ABOUT_COPYRIGHT),
"authors", authors,
"comments", GetString(STR_ABOUT_COMMENTS),
"website", GetString(STR_ABOUT_WEBSITE),
"website-label", GetString(STR_ABOUT_WEBSITE_LABEL),
"license", GetString(STR_ABOUT_LICENSE),
"wrap-license", true,
"logo-icon-name", "BasiliskII",
NULL);
}
// "Zap PRAM" selected
@ -451,12 +458,12 @@ static void mn_zap_pram(...)
// Menu item descriptions
static GtkItemFactoryEntry menu_items[] = {
{(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, "<Branch>"},
{(gchar *)GetString(STR_PREFS_ITEM_START_GTK), "<control>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_START_GTK), "<control>S", G_CALLBACK(cb_start), 0, NULL},
{(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, G_CALLBACK(mn_zap_pram), 0, NULL},
{(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, "<Separator>"},
{(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL},
{(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", G_CALLBACK(cb_quit), 0, NULL},
{(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, "<LastBranch>"},
{(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, GTK_SIGNAL_FUNC(mn_about), 0, NULL}
{(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, G_CALLBACK(mn_about), 0, NULL}
};
bool PrefsEditor(void)
@ -464,8 +471,8 @@ bool PrefsEditor(void)
// Create window
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE));
gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL);
gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL);
g_signal_connect(win, "delete_event", G_CALLBACK(window_closed), NULL);
g_signal_connect(win, "destroy", G_CALLBACK(window_destroyed), NULL);
// Create window contents
GtkWidget *box = gtk_vbox_new(FALSE, 4);
@ -500,8 +507,8 @@ bool PrefsEditor(void)
gtk_widget_show(notebook);
static const opt_desc buttons[] = {
{STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
{STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)},
{STR_START_BUTTON, G_CALLBACK(cb_start)},
{STR_QUIT_BUTTON, G_CALLBACK(cb_quit)},
{0, NULL}
};
make_button_box(box, 4, buttons);
@ -527,70 +534,91 @@ static void cl_selected(GtkWidget *list, int row, int column)
}
// Volume selected for addition
static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
static void cb_add_volume_response (GtkWidget *chooser, int response)
{
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;
if (response == GTK_RESPONSE_ACCEPT)
{
char *file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
gtk_clist_append(GTK_CLIST(volume_list), &file);
}
gtk_widget_destroy(chooser);
}
// Volume selected for creation
static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
static void cb_create_volume_response (GtkWidget *chooser, int response, GtkEntry *size_entry)
{
gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
int disk_size = atoi(str);
if (disk_size < 1 || disk_size > 2000) {
printf("Disk size needs to be between 1 and 2000 MB.\n");
gtk_widget_destroy(GTK_WIDGET(assoc->req));
delete assoc;
return;
if (response == GTK_RESPONSE_ACCEPT)
{
char *file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
const gchar *str = gtk_entry_get_text(GTK_ENTRY(size_entry));
int disk_size = atoi(str);
if (disk_size < 1 || disk_size > 2000)
{
GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(win),
(GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
GTK_MESSAGE_WARNING,
GTK_BUTTONS_CLOSE,
"Enter a valid size", NULL);
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "The volume size should be between 1 and 2000.");
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(chooser));
g_signal_connect(dialog, "response", G_CALLBACK(dl_quit), NULL);
gtk_widget_show(dialog);
return; // Don't close the file chooser dialog
}
int fd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd < 0) {
fprintf(stderr, "Could not create %s (%s)\n", file, strerror(errno));
} else {
ftruncate(fd, disk_size * 1024 * 1024);
gtk_clist_append(GTK_CLIST(volume_list), &file);
}
}
int fd = open(file, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd < 0 && errno == EEXIST) {
printf("File already exists, refusing to overwrite file.\n");
} else {
ftruncate(fd, disk_size * 1024 * 1024);
gtk_clist_append(GTK_CLIST(volume_list), &file);
}
close(fd);
gtk_widget_destroy(GTK_WIDGET(assoc->req));
delete assoc;
gtk_widget_destroy (chooser);
}
// "Add Volume" button clicked
static void cb_add_volume(...)
static void cb_add_volume (...)
{
GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_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(add_volume_ok), new file_req_assoc(req, NULL));
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);
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_ADD_VOLUME_TITLE),
GTK_WINDOW(win),
GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL,
"Add", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_ACCEPT);
gtk_window_set_modal(GTK_WINDOW(chooser), true);
g_signal_connect(chooser, "response", G_CALLBACK(cb_add_volume_response), NULL);
gtk_widget_show(chooser);
}
// "Create Hardfile" button clicked
static void cb_create_volume(...)
static void cb_create_volume (...)
{
GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE));
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_CREATE_VOLUME_TITLE),
GTK_WINDOW(win),
GTK_FILE_CHOOSER_ACTION_SAVE,
"Cancel", GTK_RESPONSE_CANCEL,
"Create", GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser), TRUE);
gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_ACCEPT);
gtk_window_set_transient_for(GTK_WINDOW(chooser), GTK_WINDOW(win));
gtk_window_set_modal(GTK_WINDOW(chooser), true);
GtkWidget *box = gtk_hbox_new(FALSE, 4);
GtkWidget *box = gtk_hbox_new(false, 8);
gtk_widget_show(box);
GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL));
gtk_widget_show(label);
GtkWidget *entry = gtk_entry_new();
gtk_widget_show(entry);
char str[32];
sprintf(str, "%d", 40);
gtk_entry_set_text(GTK_ENTRY(entry), str);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0);
GtkWidget *size_entry = gtk_entry_new();
gtk_widget_show(size_entry);
gtk_entry_set_text(GTK_ENTRY(size_entry), "40");
gtk_box_pack_end(GTK_BOX(box), size_entry, FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(box), label, FALSE, FALSE, 0);
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(create_volume_ok), new file_req_assoc(req, entry));
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);
gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(chooser), box);
g_signal_connect(chooser, "response", G_CALLBACK(cb_create_volume_response), size_entry);
gtk_widget_show(chooser);
}
// "Remove Volume" button clicked
@ -639,7 +667,7 @@ static void create_volumes_pane(GtkWidget *top)
gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
g_signal_connect(volume_list, "select_row", G_CALLBACK(cl_selected), NULL);
char *str;
int32 index = 0;
while ((str = const_cast<char *>(PrefsFindString("disk", index++))) != NULL)
@ -649,9 +677,9 @@ static void create_volumes_pane(GtkWidget *top)
selected_volume = 0;
static const opt_desc buttons[] = {
{STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)},
{STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)},
{STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)},
{STR_ADD_VOLUME_BUTTON, G_CALLBACK(cb_add_volume)},
{STR_CREATE_VOLUME_BUTTON, G_CALLBACK(cb_create_volume)},
{STR_REMOVE_VOLUME_BUTTON, G_CALLBACK(cb_remove_volume)},
{0, NULL},
};
make_button_box(box, 0, buttons);
@ -660,8 +688,8 @@ static void create_volumes_pane(GtkWidget *top)
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)},
{STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)},
{STR_BOOT_ANY_LAB, G_CALLBACK(mn_boot_any)},
{STR_BOOT_CDROM_LAB, G_CALLBACK(mn_boot_cdrom)},
{0, NULL}
};
int bootdriver = PrefsFindInt32("bootdriver"), active = 0;
@ -671,7 +699,7 @@ static void create_volumes_pane(GtkWidget *top)
}
make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active);
make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", G_CALLBACK(tb_nocdrom));
}
@ -759,9 +787,9 @@ static void create_jit_pane(GtkWidget *top)
GtkWidget *box;
box = make_pane(top, STR_JIT_PANE_TITLE);
make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit));
make_checkbox(box, STR_JIT_CTRL, "jit", G_CALLBACK(tb_jit));
w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", GTK_SIGNAL_FUNC(tb_jit_fpu));
w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", G_CALLBACK(tb_jit_fpu));
// Translation cache size
static const combo_desc options[] = {
@ -774,10 +802,10 @@ static void create_jit_pane(GtkWidget *top)
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));
w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", G_CALLBACK(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));
w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", G_CALLBACK(tb_jit_follow_const_jumps));
set_jit_sensitive();
}
@ -983,8 +1011,8 @@ static void create_graphics_pane(GtkWidget *top)
opt = gtk_option_menu_new();
gtk_widget_show(opt);
menu = gtk_menu_new();
add_menu_item(menu, STR_WINDOW_LAB, GTK_SIGNAL_FUNC(mn_window));
add_menu_item(menu, STR_FULLSCREEN_LAB, GTK_SIGNAL_FUNC(mn_fullscreen));
add_menu_item(menu, STR_WINDOW_LAB, G_CALLBACK(mn_window));
add_menu_item(menu, STR_FULLSCREEN_LAB, G_CALLBACK(mn_fullscreen));
switch (display_type) {
case DISPLAY_WINDOW:
gtk_menu_set_active(GTK_MENU(menu), 0);
@ -1003,13 +1031,13 @@ static void create_graphics_pane(GtkWidget *top)
w_frameskip = gtk_option_menu_new();
gtk_widget_show(w_frameskip);
menu = gtk_menu_new();
add_menu_item(menu, STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz));
add_menu_item(menu, STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz));
add_menu_item(menu, STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz));
add_menu_item(menu, STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz));
add_menu_item(menu, STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz));
add_menu_item(menu, STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz));
add_menu_item(menu, STR_REF_DYNAMIC_LAB, GTK_SIGNAL_FUNC(mn_dynamic));
add_menu_item(menu, STR_REF_5HZ_LAB, G_CALLBACK(mn_5hz));
add_menu_item(menu, STR_REF_7_5HZ_LAB, G_CALLBACK(mn_7hz));
add_menu_item(menu, STR_REF_10HZ_LAB, G_CALLBACK(mn_10hz));
add_menu_item(menu, STR_REF_15HZ_LAB, G_CALLBACK(mn_15hz));
add_menu_item(menu, STR_REF_30HZ_LAB, G_CALLBACK(mn_30hz));
add_menu_item(menu, STR_REF_60HZ_LAB, G_CALLBACK(mn_60hz));
add_menu_item(menu, STR_REF_DYNAMIC_LAB, G_CALLBACK(mn_dynamic));
int frameskip = PrefsFindInt32("frameskip");
int item = -1;
switch (frameskip) {
@ -1082,7 +1110,7 @@ static void create_graphics_pane(GtkWidget *top)
#endif
make_separator(box);
make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
make_checkbox(box, STR_NOSOUND_CTRL, "nosound", G_CALLBACK(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");
@ -1139,7 +1167,7 @@ static void create_input_pane(GtkWidget *top)
box = make_pane(top, STR_INPUT_PANE_TITLE);
make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", G_CALLBACK(tb_keycodes));
hbox = gtk_hbox_new(FALSE, 4);
gtk_widget_show(hbox);
@ -1158,15 +1186,15 @@ static void create_input_pane(GtkWidget *top)
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);
button = make_browse_button(w_keycode_file, false);
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);
static const opt_desc options[] = {
{STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)},
{STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)},
{STR_MOUSEWHEELMODE_PAGE_LAB, G_CALLBACK(mn_wheel_page)},
{STR_MOUSEWHEELMODE_CURSOR_LAB, G_CALLBACK(mn_wheel_cursor)},
{0, NULL}
};
int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0;
@ -1377,7 +1405,7 @@ static void create_serial_pane(GtkWidget *top)
w_ether = GTK_COMBO(combo)->entry;
#if SUPPORTS_UDP_TUNNEL
make_checkbox(box, STR_UDPTUNNEL_CTRL, "udptunnel", GTK_SIGNAL_FUNC(tb_udptunnel));
make_checkbox(box, STR_UDPTUNNEL_CTRL, "udptunnel", G_CALLBACK(tb_udptunnel));
hbox = gtk_hbox_new(FALSE, 4);
gtk_widget_show(hbox);
@ -1469,8 +1497,8 @@ static void create_memory_pane(GtkWidget *top)
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)},
{STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)},
{STR_MODELID_5_LAB, G_CALLBACK(mn_modelid_5)},
{STR_MODELID_14_LAB, G_CALLBACK(mn_modelid_14)},
{0, NULL}
};
int modelid = PrefsFindInt32("modelid"), active = 0;
@ -1482,11 +1510,11 @@ static void create_memory_pane(GtkWidget *top)
#if EMULATED_68K
static const opt_desc cpu_options[] = {
{STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)},
{STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)},
{STR_CPU_68030_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030)},
{STR_CPU_68030_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030_fpu)},
{STR_CPU_68040_LAB, GTK_SIGNAL_FUNC(mn_cpu_68040)},
{STR_CPU_68020_LAB, G_CALLBACK(mn_cpu_68020)},
{STR_CPU_68020_FPU_LAB, G_CALLBACK(mn_cpu_68020_fpu)},
{STR_CPU_68030_LAB, G_CALLBACK(mn_cpu_68030)},
{STR_CPU_68030_FPU_LAB, G_CALLBACK(mn_cpu_68030_fpu)},
{STR_CPU_68040_LAB, G_CALLBACK(mn_cpu_68040)},
{0, NULL}
};
int cpu = PrefsFindInt32("cpu");
@ -1502,9 +1530,9 @@ static void create_memory_pane(GtkWidget *top)
w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom");
make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", GTK_SIGNAL_FUNC(tb_idlewait));
make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", G_CALLBACK(tb_idlewait));
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", G_CALLBACK(tb_ignoresegv));
#endif
}
@ -1565,7 +1593,7 @@ static void display_alert(int title_id, int prefix_id, int button_id, const char
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);
g_signal_connect(dialog, "destroy", G_CALLBACK(dl_destroyed), NULL);
GtkWidget *label = gtk_label_new(str);
gtk_widget_show(label);
@ -1573,7 +1601,7 @@ static void display_alert(int title_id, int prefix_id, int button_id, const char
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));
g_signal_connect_object(button, "clicked", G_CALLBACK(dl_quit), dialog, (GConnectFlags) 0);
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);

View File

@ -73,7 +73,8 @@ user_string_def platform_strings[] = {
{STR_DSPDEVICE_FILE_CTRL, "Audio Output Device"},
{STR_MIXERDEVICE_FILE_CTRL, "Audio Mixer Device"},
{STR_BROWSE_TITLE, "Browse file"},
{STR_BROWSE_TITLE, "Select File"},
{STR_BROWSE_FOLDER_TITLE, "Select Folder"},
{STR_BROWSE_CTRL, "Browse..."},
{STR_INPUT_PANE_TITLE, "Keyboard/Mouse"},
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
@ -87,6 +88,22 @@ user_string_def platform_strings[] = {
{STR_NO_B2_EXE_FOUND, "Could not start %s (%s)."},
{STR_ABOUT_COPYRIGHT, "© 1997-2008 Christian Bauer et al."},
{STR_ABOUT_LICENSE, "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 \
the Free Software Foundation; either version 2 of the License, or \
(at your option) any later version.\n\n\
This program is distributed in the hope that it will be useful, \
but WITHOUT ANY WARRANTY; without even the implied warranty of \
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \
GNU General Public License for more details.\n\n\
You should have received a copy of the GNU General Public License \
along with this program; if not, write to the Free Software \
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"},
{STR_ABOUT_COMMENTS, "Open source 68k Mac emulator"},
{STR_ABOUT_WEBSITE, "http://basilisk.cebix.net"},
{STR_ABOUT_WEBSITE_LABEL, "Website"},
{-1, NULL} // End marker
};

View File

@ -66,6 +66,7 @@ enum {
STR_BROWSE_CTRL,
STR_BROWSE_TITLE,
STR_BROWSE_FOLDER_TITLE,
STR_INPUT_PANE_TITLE,
STR_KEYCODES_CTRL,
STR_KEYCODE_FILE_CTRL,
@ -76,7 +77,13 @@ enum {
STR_IGNORESEGV_CTRL,
STR_NO_B2_EXE_FOUND
STR_NO_B2_EXE_FOUND,
STR_ABOUT_COPYRIGHT,
STR_ABOUT_LICENSE,
STR_ABOUT_COMMENTS,
STR_ABOUT_WEBSITE,
STR_ABOUT_WEBSITE_LABEL
};
#endif

View File

@ -70,51 +70,73 @@ static void read_settings(void);
struct opt_desc {
int label_id;
GtkSignalFunc func;
GCallback 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)
// User closed the file chooser dialog, possibly selecting a file
static void cb_browse_response(GtkWidget *chooser, int response, GtkEntry *entry)
{
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;
if (response == GTK_RESPONSE_ACCEPT)
{
gchar *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
gtk_entry_set_text(GTK_ENTRY(entry), filename);
g_free (filename);
}
gtk_widget_destroy (chooser);
}
static void cb_browse(GtkWidget *widget, void *user_data)
// Open the file chooser dialog to select a file
static void cb_browse(GtkWidget *button, GtkWidget *entry)
{
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);
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_BROWSE_TITLE),
GTK_WINDOW(win),
GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL,
"Open", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_ACCEPT);
gtk_window_set_transient_for(GTK_WINDOW(chooser), GTK_WINDOW(win));
gtk_window_set_modal(GTK_WINDOW(chooser), true);
g_signal_connect(chooser, "response", G_CALLBACK(cb_browse_response), GTK_ENTRY(entry));
gtk_widget_show(chooser);
}
static GtkWidget *make_browse_button(GtkWidget *entry)
// Open the file chooser dialog to select a folder
static void cb_browse_dir(GtkWidget *button, GtkWidget *entry)
{
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_BROWSE_FOLDER_TITLE),
GTK_WINDOW(win),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
"Cancel", GTK_RESPONSE_CANCEL,
"Select", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_ACCEPT);
gtk_window_set_transient_for(GTK_WINDOW(chooser), GTK_WINDOW(win));
gtk_window_set_modal(GTK_WINDOW(chooser), true);
g_signal_connect(chooser, "response", G_CALLBACK(cb_browse_response), GTK_WIDGET(entry));
gtk_widget_show(chooser);
}
static GtkWidget *make_browse_button(GtkWidget *entry, bool only_dirs)
{
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);
g_signal_connect(button, "clicked", only_dirs ? G_CALLBACK(cb_browse_dir) : G_CALLBACK(cb_browse), entry);
return button;
}
static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
static void add_menu_item(GtkWidget *menu, int label_id, GCallback func)
{
GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id));
gtk_widget_show(item);
gtk_signal_connect(GTK_OBJECT(item), "activate", func, NULL);
g_signal_connect(item, "activate", func, NULL);
gtk_menu_append(GTK_MENU(menu), item);
}
@ -150,7 +172,7 @@ static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *bu
while (buttons->label_id) {
button = gtk_button_new_with_label(GetString(buttons->label_id));
gtk_widget_show(button);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL);
g_signal_connect_object(button, "clicked", buttons->func, NULL, (GConnectFlags) 0);
gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0);
buttons++;
}
@ -247,7 +269,7 @@ static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id,
gtk_widget_show(entry);
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
button = make_browse_button(entry);
button = make_browse_button(entry, false);
gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(entry), "chooser_button", button);
return entry;
@ -280,9 +302,9 @@ static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc
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;
GtkWidget *box, *label, *entry, *button;
box = gtk_hbox_new(FALSE, 4);
gtk_widget_show(box);
@ -297,8 +319,15 @@ static GtkWidget *make_entry(GtkWidget *top, int label_id, const char *prefs_ite
const char *str = PrefsFindString(prefs_item);
if (str == NULL)
str = "";
gtk_entry_set_text(GTK_ENTRY(entry), str);
gtk_entry_set_text(GTK_ENTRY(entry), str);
button = make_browse_button(entry, only_dirs);
gtk_widget_show(entry);
#if GLIB_CHECK_VERSION(2,26,0)
g_object_bind_property(entry, "sensitive", button, "sensitive", G_BINDING_SYNC_CREATE);
#endif
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
return entry;
}
@ -307,22 +336,22 @@ static const gchar *get_file_entry_path(GtkWidget *entry)
return gtk_entry_get_text(GTK_ENTRY(entry));
}
static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func)
static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GCallback func)
{
GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
gtk_widget_show(button);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item));
gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
g_signal_connect(button, "toggled", func, NULL);
gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
return button;
}
static GtkWidget *make_checkbox(GtkWidget *top, int label_id, bool active, GtkSignalFunc func)
static GtkWidget *make_checkbox(GtkWidget *top, int label_id, bool active, GCallback func)
{
GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
gtk_widget_show(button);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), active);
gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
g_signal_connect(button, "toggled", func, NULL);
gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
return button;
}
@ -371,37 +400,24 @@ static void dl_quit(GtkWidget *dialog)
static void mn_about(...)
{
GtkWidget *dialog, *label, *button;
char str[512];
sprintf(str,
"SheepShaver\nVersion %d.%d\n\n"
"Copyright (C) 1997-2008 Christian Bauer and Marc Hellwig\n"
"E-mail: cb@cebix.net\n"
"http://sheepshaver.cebix.net/\n\n"
"SheepShaver comes with ABSOLUTELY NO\n"
"WARRANTY. This is free software, and\n"
"you are welcome to redistribute it\n"
"under the terms of the GNU General\n"
"Public License.\n",
VERSION_MAJOR, VERSION_MINOR
);
dialog = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE));
gtk_container_border_width(GTK_CONTAINER(dialog), 5);
gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
label = gtk_label_new(str);
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
button = gtk_button_new_with_label(GetString(STR_OK_BUTTON));
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);
const char *authors[] = {
"Christian Bauer",
"Marc Hellwig",
"Gwenolé Beauchesne",
NULL
};
char version[64];
sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR);
gtk_show_about_dialog(GTK_WINDOW(win), "version", version,
"copyright", GetString(STR_ABOUT_COPYRIGHT),
"authors", authors,
"comments", GetString(STR_ABOUT_COMMENTS),
"website", GetString(STR_ABOUT_WEBSITE),
"website-label", GetString(STR_ABOUT_WEBSITE_LABEL),
"license", GetString(STR_ABOUT_LICENSE),
"wrap-license", true,
"logo-icon-name", "SheepShaver",
NULL);
}
// "Zap NVRAM" selected
@ -413,12 +429,12 @@ static void mn_zap_pram(...)
// Menu item descriptions
static GtkItemFactoryEntry menu_items[] = {
{(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, "<Branch>"},
{(gchar *)GetString(STR_PREFS_ITEM_START_GTK), "<control>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_START_GTK), "<control>S", G_CALLBACK(cb_start), 0, NULL},
{(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, G_CALLBACK(mn_zap_pram), 0, NULL},
{(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, "<Separator>"},
{(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL},
{(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", G_CALLBACK(cb_quit), 0, NULL},
{(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, "<LastBranch>"},
{(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, GTK_SIGNAL_FUNC(mn_about), 0, NULL}
{(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, G_CALLBACK(mn_about), 0, NULL}
};
bool PrefsEditor(void)
@ -430,8 +446,8 @@ bool PrefsEditor(void)
// Create window
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE));
gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL);
gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL);
g_signal_connect(win, "delete_event", G_CALLBACK(window_closed), NULL);
g_signal_connect(win, "destroy", G_CALLBACK(window_destroyed), NULL);
// Create window contents
GtkWidget *box = gtk_vbox_new(FALSE, 4);
@ -465,8 +481,8 @@ bool PrefsEditor(void)
gtk_widget_show(notebook);
static const opt_desc buttons[] = {
{STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
{STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)},
{STR_START_BUTTON, G_CALLBACK(cb_start)},
{STR_QUIT_BUTTON, G_CALLBACK(cb_quit)},
{0, NULL}
};
make_button_box(box, 4, buttons);
@ -492,72 +508,92 @@ static void cl_selected(GtkWidget *list, int row, int column)
}
// Volume selected for addition
static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
static void cb_add_volume_response (GtkWidget *chooser, int response)
{
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;
if (response == GTK_RESPONSE_ACCEPT)
{
char *file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
gtk_clist_append(GTK_CLIST(volume_list), &file);
}
gtk_widget_destroy(chooser);
}
// Volume selected for creation
static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
static void cb_create_volume_response (GtkWidget *chooser, int response, GtkEntry *size_entry)
{
gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
int disk_size = atoi(str);
if (disk_size < 1 || disk_size > 2000) {
printf("Disk size needs to be between 1 and 2000 MB.\n");
gtk_widget_destroy(GTK_WIDGET(assoc->req));
delete assoc;
return;
if (response == GTK_RESPONSE_ACCEPT)
{
char *file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
const gchar *str = gtk_entry_get_text(GTK_ENTRY(size_entry));
int disk_size = atoi(str);
if (disk_size < 1 || disk_size > 2000)
{
GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(win),
(GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
GTK_MESSAGE_WARNING,
GTK_BUTTONS_CLOSE,
"Enter a valid size", NULL);
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "The volume size should be between 1 and 2000.");
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(chooser));
g_signal_connect(dialog, "response", G_CALLBACK(dl_quit), NULL);
gtk_widget_show(dialog);
return; // Don't close the file chooser dialog
}
int fd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd < 0) {
fprintf(stderr, "Could not create %s (%s)\n", file, strerror(errno));
} else {
ftruncate(fd, disk_size * 1024 * 1024);
gtk_clist_append(GTK_CLIST(volume_list), &file);
}
}
int fd = open(file, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd < 0 && errno == EEXIST) {
printf("File already exists, refusing to overwrite file.\n");
} else {
ftruncate(fd, disk_size * 1024 * 1024);
gtk_clist_append(GTK_CLIST(volume_list), &file);
}
close(fd);
gtk_widget_destroy(GTK_WIDGET(assoc->req));
delete assoc;
gtk_widget_destroy (chooser);
}
// "Add Volume" button clicked
static void cb_add_volume(...)
static void cb_add_volume (...)
{
GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_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(add_volume_ok), new file_req_assoc(req, NULL));
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);
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_ADD_VOLUME_TITLE),
GTK_WINDOW(win),
GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL,
"Add", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_ACCEPT);
gtk_window_set_modal(GTK_WINDOW(chooser), true);
g_signal_connect(chooser, "response", G_CALLBACK(cb_add_volume_response), NULL);
gtk_widget_show(chooser);
}
// "Create Hardfile" button clicked
static void cb_create_volume(...)
static void cb_create_volume (...)
{
GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE));
GtkWidget *chooser = gtk_file_chooser_dialog_new(GetString(STR_CREATE_VOLUME_TITLE),
GTK_WINDOW(win),
GTK_FILE_CHOOSER_ACTION_SAVE,
"Cancel", GTK_RESPONSE_CANCEL,
"Create", GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser), TRUE);
gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_ACCEPT);
gtk_window_set_transient_for(GTK_WINDOW(chooser), GTK_WINDOW(win));
gtk_window_set_modal(GTK_WINDOW(chooser), true);
GtkWidget *box = gtk_hbox_new(FALSE, 4);
GtkWidget *box = gtk_hbox_new(false, 8);
gtk_widget_show(box);
GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL));
gtk_widget_show(label);
GtkWidget *entry = gtk_entry_new();
gtk_widget_show(entry);
char str[32];
sprintf(str, "%d", 40);
gtk_entry_set_text(GTK_ENTRY(entry), str);
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0);
GtkWidget *size_entry = gtk_entry_new();
gtk_widget_show(size_entry);
gtk_entry_set_text(GTK_ENTRY(size_entry), "40");
gtk_box_pack_end(GTK_BOX(box), size_entry, FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(box), label, FALSE, FALSE, 0);
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(create_volume_ok), new file_req_assoc(req, entry));
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);
gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(chooser), box);
g_signal_connect(chooser, "response", G_CALLBACK(cb_create_volume_response), size_entry);
gtk_widget_show(chooser);
}
// "Remove Volume" button clicked
static void cb_remove_volume(...)
{
@ -604,7 +640,7 @@ static void create_volumes_pane(GtkWidget *top)
gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
g_signal_connect(volume_list, "select_row", G_CALLBACK(cl_selected), NULL);
char *str;
int32 index = 0;
while ((str = (char *)PrefsFindString("disk", index++)) != NULL)
@ -614,19 +650,19 @@ static void create_volumes_pane(GtkWidget *top)
selected_volume = 0;
static const opt_desc buttons[] = {
{STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)},
{STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)},
{STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)},
{STR_ADD_VOLUME_BUTTON, G_CALLBACK(cb_add_volume)},
{STR_CREATE_VOLUME_BUTTON, G_CALLBACK(cb_create_volume)},
{STR_REMOVE_VOLUME_BUTTON, G_CALLBACK(cb_remove_volume)},
{0, NULL},
};
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)},
{STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)},
{STR_BOOT_ANY_LAB, G_CALLBACK(mn_boot_any)},
{STR_BOOT_CDROM_LAB, G_CALLBACK(mn_boot_cdrom)},
{0, NULL}
};
int bootdriver = PrefsFindInt32("bootdriver"), active = 0;
@ -636,7 +672,7 @@ static void create_volumes_pane(GtkWidget *top)
}
menu = make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active);
make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", G_CALLBACK(tb_nocdrom));
}
@ -699,11 +735,11 @@ static void create_jit_pane(GtkWidget *top)
box = make_pane(top, STR_JIT_PANE_TITLE);
if (is_jit_capable()) {
make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit));
make_checkbox(box, STR_JIT_CTRL, "jit", G_CALLBACK(tb_jit));
set_jit_sensitive();
}
make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k));
make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", G_CALLBACK(tb_jit_68k));
}
@ -898,8 +934,8 @@ static void create_graphics_pane(GtkWidget *top)
opt = gtk_option_menu_new();
gtk_widget_show(opt);
menu = gtk_menu_new();
add_menu_item(menu, STR_WINDOW_CTRL, GTK_SIGNAL_FUNC(mn_window));
add_menu_item(menu, STR_FULLSCREEN_CTRL, GTK_SIGNAL_FUNC(mn_fullscreen));
add_menu_item(menu, STR_WINDOW_CTRL, G_CALLBACK(mn_window));
add_menu_item(menu, STR_FULLSCREEN_CTRL, G_CALLBACK(mn_fullscreen));
switch (display_type) {
case DISPLAY_WINDOW:
gtk_menu_set_active(GTK_MENU(menu), 0);
@ -918,12 +954,12 @@ static void create_graphics_pane(GtkWidget *top)
w_frameskip = gtk_option_menu_new();
gtk_widget_show(w_frameskip);
menu = gtk_menu_new();
add_menu_item(menu, STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz));
add_menu_item(menu, STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz));
add_menu_item(menu, STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz));
add_menu_item(menu, STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz));
add_menu_item(menu, STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz));
add_menu_item(menu, STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz));
add_menu_item(menu, STR_REF_5HZ_LAB, G_CALLBACK(mn_5hz));
add_menu_item(menu, STR_REF_7_5HZ_LAB, G_CALLBACK(mn_7hz));
add_menu_item(menu, STR_REF_10HZ_LAB, G_CALLBACK(mn_10hz));
add_menu_item(menu, STR_REF_15HZ_LAB, G_CALLBACK(mn_15hz));
add_menu_item(menu, STR_REF_30HZ_LAB, G_CALLBACK(mn_30hz));
add_menu_item(menu, STR_REF_60HZ_LAB, G_CALLBACK(mn_60hz));
int frameskip = PrefsFindInt32("frameskip");
int item = -1;
switch (frameskip) {
@ -982,12 +1018,12 @@ static void create_graphics_pane(GtkWidget *top)
gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
w_display_y = GTK_COMBO(combo)->entry;
make_checkbox(box, STR_GFXACCEL_CTRL, PrefsFindBool("gfxaccel"), GTK_SIGNAL_FUNC(tb_gfxaccel));
make_checkbox(box, STR_GFXACCEL_CTRL, PrefsFindBool("gfxaccel"), G_CALLBACK(tb_gfxaccel));
make_separator(box);
make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
w_dspdevice_file = make_entry(box, STR_DSPDEVICE_FILE_CTRL, "dsp");
w_mixerdevice_file = make_entry(box, STR_MIXERDEVICE_FILE_CTRL, "mixer");
make_checkbox(box, STR_NOSOUND_CTRL, "nosound", G_CALLBACK(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();
@ -1042,7 +1078,7 @@ static void create_input_pane(GtkWidget *top)
box = make_pane(top, STR_INPUT_PANE_TITLE);
make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", G_CALLBACK(tb_keycodes));
hbox = gtk_hbox_new(FALSE, 4);
gtk_widget_show(hbox);
@ -1061,15 +1097,15 @@ static void create_input_pane(GtkWidget *top)
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);
button = make_browse_button(w_keycode_file, false);
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);
static const opt_desc options[] = {
{STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)},
{STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)},
{STR_MOUSEWHEELMODE_PAGE_LAB, G_CALLBACK(mn_wheel_page)},
{STR_MOUSEWHEELMODE_CURSOR_LAB, G_CALLBACK(mn_wheel_cursor)},
{0, NULL}
};
int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0;
@ -1314,8 +1350,8 @@ static void create_memory_pane(GtkWidget *top)
w_rom_file = table_make_file_entry(table, 1, STR_ROM_FILE_CTRL, "rom");
make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", GTK_SIGNAL_FUNC(tb_idlewait));
make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", G_CALLBACK(tb_ignoresegv));
make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", G_CALLBACK(tb_idlewait));
}
@ -1374,7 +1410,7 @@ static void display_alert(int title_id, int prefix_id, int button_id, const char
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);
g_signal_connect(dialog, "destroy", G_CALLBACK(dl_destroyed), NULL);
GtkWidget *label = gtk_label_new(str);
gtk_widget_show(label);
@ -1382,7 +1418,7 @@ static void display_alert(int title_id, int prefix_id, int button_id, const char
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));
g_signal_connect_object(button, "clicked", G_CALLBACK(dl_quit), dialog, (GConnectFlags) 0)
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);

View File

@ -71,7 +71,8 @@ user_string_def platform_strings[] = {
{STR_HELP_ITEM_ABOUT_GTK, "/Help/_About SheepShaver"},
{STR_DSPDEVICE_FILE_CTRL, "Audio Output Device"},
{STR_MIXERDEVICE_FILE_CTRL, "Audio Mixer Device"},
{STR_BROWSE_TITLE, "Browse file"},
{STR_BROWSE_TITLE, "Select File"},
{STR_BROWSE_FOLDER_TITLE, "Select Folder"},
{STR_BROWSE_CTRL, "Browse..."},
{STR_INPUT_PANE_TITLE, "Keyboard/Mouse"},
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
@ -87,6 +88,22 @@ user_string_def platform_strings[] = {
{STR_NO_B2_EXE_FOUND, "Could not start %s (%s)."},
{STR_ABOUT_COPYRIGHT, "© 1997-2008 Christian Bauer and Marc Hellwig"},
{STR_ABOUT_LICENSE, "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 \
the Free Software Foundation; either version 2 of the License, or \
(at your option) any later version.\n\n\
This program is distributed in the hope that it will be useful, \
but WITHOUT ANY WARRANTY; without even the implied warranty of \
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \
GNU General Public License for more details.\n\n\
You should have received a copy of the GNU General Public License \
along with this program; if not, write to the Free Software \
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"},
{STR_ABOUT_COMMENTS, "Open source PowerPC Mac emulator"},
{STR_ABOUT_WEBSITE, "http://sheepshaver.cebix.net"},
{STR_ABOUT_WEBSITE_LABEL, "Website"},
{-1, NULL} // End marker
};

View File

@ -69,6 +69,7 @@ enum {
STR_BROWSE_CTRL,
STR_BROWSE_TITLE,
STR_BROWSE_FOLDER_TITLE,
STR_INPUT_PANE_TITLE,
STR_KEYCODES_CTRL,
STR_KEYCODE_FILE_CTRL,
@ -79,7 +80,13 @@ enum {
STR_OPEN_WINDOW_ERR,
STR_NO_B2_EXE_FOUND
STR_NO_B2_EXE_FOUND,
STR_ABOUT_COPYRIGHT,
STR_ABOUT_LICENSE,
STR_ABOUT_COMMENTS,
STR_ABOUT_WEBSITE,
STR_ABOUT_WEBSITE_LABEL
};
#endif