ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/prefs_editor_gtk.cpp
Revision: 1.9
Committed: 2005-11-29T20:54:57Z (18 years, 6 months ago) by gbeauche
Branch: MAIN
Changes since 1.8: +46 -12 lines
Log Message:
add support for "cdrom" drive selection

File Contents

# User Rev Content
1 gbeauche 1.1 /*
2     * prefs_editor_gtk.cpp - Preferences editor, Unix implementation using GTK+
3     *
4     * Basilisk II (C) 1997-2005 Christian Bauer
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #include "sysdeps.h"
22    
23 gbeauche 1.5 #include <stdlib.h>
24     #include <string.h>
25 gbeauche 1.4 #include <fcntl.h>
26     #include <sys/stat.h>
27 gbeauche 1.1 #include <gtk/gtk.h>
28    
29     #include "user_strings.h"
30     #include "version.h"
31     #include "cdrom.h"
32     #include "xpram.h"
33     #include "prefs.h"
34     #include "prefs_editor.h"
35    
36    
37     // Global variables
38     static GtkWidget *win; // Preferences window
39     static bool start_clicked = true; // Return value of PrefsEditor() function
40    
41    
42     // Prototypes
43     static void create_volumes_pane(GtkWidget *top);
44     static void create_scsi_pane(GtkWidget *top);
45     static void create_graphics_pane(GtkWidget *top);
46     static void create_input_pane(GtkWidget *top);
47     static void create_serial_pane(GtkWidget *top);
48     static void create_ethernet_pane(GtkWidget *top);
49     static void create_memory_pane(GtkWidget *top);
50     static void create_jit_pane(GtkWidget *top);
51     static void read_settings(void);
52    
53    
54     /*
55 gbeauche 1.8 * SheepShaver glue
56     */
57    
58     #ifdef SHEEPSHAVER
59     #define DISABLE_SCSI 1
60     #define PROGRAM_NAME "SheepShaver"
61     enum {
62     STR_WINDOW_LAB = STR_WINDOW_CTRL,
63     STR_FULLSCREEN_LAB = STR_FULLSCREEN_CTRL,
64     STR_SERIALA_CTRL = STR_SERPORTA_CTRL,
65     STR_SERIALB_CTRL = STR_SERPORTB_CTRL,
66     };
67     #else
68     #define PROGRAM_NAME "BasiliskII"
69     #endif
70    
71    
72     /*
73 gbeauche 1.1 * Utility functions
74     */
75    
76     struct opt_desc {
77     int label_id;
78     GtkSignalFunc func;
79     };
80    
81     struct combo_desc {
82     int label_id;
83     };
84    
85     struct file_req_assoc {
86     file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
87     GtkWidget *req;
88     GtkWidget *entry;
89     };
90    
91     static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc)
92     {
93     gchar *file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
94     gtk_entry_set_text(GTK_ENTRY(assoc->entry), file);
95     gtk_widget_destroy(assoc->req);
96     delete assoc;
97     }
98    
99     static void cb_browse(GtkWidget *widget, void *user_data)
100     {
101     GtkWidget *req = gtk_file_selection_new(GetString(STR_BROWSE_TITLE));
102     gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
103     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));
104     gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
105     gtk_widget_show(req);
106     }
107    
108     static GtkWidget *make_browse_button(GtkWidget *entry)
109     {
110     GtkWidget *button;
111    
112     button = gtk_button_new_with_label(GetString(STR_BROWSE_CTRL));
113     gtk_widget_show(button);
114     gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)cb_browse, (void *)entry);
115     return button;
116     }
117    
118     static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
119     {
120     GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id));
121     gtk_widget_show(item);
122     gtk_signal_connect(GTK_OBJECT(item), "activate", func, NULL);
123     gtk_menu_append(GTK_MENU(menu), item);
124     }
125    
126     static GtkWidget *make_pane(GtkWidget *notebook, int title_id)
127     {
128     GtkWidget *frame, *label, *box;
129    
130     frame = gtk_frame_new(NULL);
131     gtk_widget_show(frame);
132     gtk_container_border_width(GTK_CONTAINER(frame), 4);
133    
134     label = gtk_label_new(GetString(title_id));
135     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
136    
137     box = gtk_vbox_new(FALSE, 4);
138     gtk_widget_show(box);
139     gtk_container_set_border_width(GTK_CONTAINER(box), 4);
140     gtk_container_add(GTK_CONTAINER(frame), box);
141     return box;
142     }
143    
144     static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons)
145     {
146     GtkWidget *bb, *button;
147    
148     bb = gtk_hbutton_box_new();
149     gtk_widget_show(bb);
150     gtk_container_set_border_width(GTK_CONTAINER(bb), border);
151     gtk_button_box_set_layout(GTK_BUTTON_BOX(bb), GTK_BUTTONBOX_DEFAULT_STYLE);
152     gtk_button_box_set_spacing(GTK_BUTTON_BOX(bb), 4);
153     gtk_box_pack_start(GTK_BOX(top), bb, FALSE, FALSE, 0);
154    
155     while (buttons->label_id) {
156     button = gtk_button_new_with_label(GetString(buttons->label_id));
157     gtk_widget_show(button);
158     gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL);
159     gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0);
160     buttons++;
161     }
162     return bb;
163     }
164    
165     static GtkWidget *make_separator(GtkWidget *top)
166     {
167     GtkWidget *sep = gtk_hseparator_new();
168     gtk_box_pack_start(GTK_BOX(top), sep, FALSE, FALSE, 0);
169     gtk_widget_show(sep);
170     return sep;
171     }
172    
173     static GtkWidget *make_table(GtkWidget *top, int x, int y)
174     {
175     GtkWidget *table = gtk_table_new(x, y, FALSE);
176     gtk_widget_show(table);
177     gtk_box_pack_start(GTK_BOX(top), table, FALSE, FALSE, 0);
178     return table;
179     }
180    
181 gbeauche 1.3 static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active)
182     {
183     GtkWidget *label, *opt, *menu;
184    
185     label = gtk_label_new(GetString(label_id));
186     gtk_widget_show(label);
187     gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
188    
189     opt = gtk_option_menu_new();
190     gtk_widget_show(opt);
191     menu = gtk_menu_new();
192    
193     while (options->label_id) {
194     add_menu_item(menu, options->label_id, options->func);
195     options++;
196     }
197     gtk_menu_set_active(GTK_MENU(menu), active);
198    
199     gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
200     gtk_table_attach(GTK_TABLE(table), opt, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
201     return menu;
202     }
203    
204     static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, GList *glist)
205     {
206     GtkWidget *label, *combo;
207     char str[32];
208    
209     label = gtk_label_new(GetString(label_id));
210     gtk_widget_show(label);
211     gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
212    
213     combo = gtk_combo_new();
214     gtk_widget_show(combo);
215     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
216    
217     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value);
218     gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
219    
220     return combo;
221     }
222    
223     static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, const combo_desc *options)
224     {
225     GList *glist = NULL;
226     while (options->label_id) {
227     glist = g_list_append(glist, (void *)GetString(options->label_id));
228     options++;
229     }
230    
231     return table_make_combobox(table, row, label_id, default_value, glist);
232     }
233    
234     static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id, const char *prefs_item, bool only_dirs = false)
235     {
236     GtkWidget *box, *label, *entry, *button;
237    
238     label = gtk_label_new(GetString(label_id));
239     gtk_widget_show(label);
240     gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
241    
242     const char *str = PrefsFindString(prefs_item);
243     if (str == NULL)
244     str = "";
245    
246     box = gtk_hbox_new(FALSE, 4);
247     gtk_widget_show(box);
248     gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
249    
250     entry = gtk_entry_new();
251     gtk_entry_set_text(GTK_ENTRY(entry), str);
252     gtk_widget_show(entry);
253     gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
254    
255     button = make_browse_button(entry);
256     gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
257     g_object_set_data(G_OBJECT(entry), "chooser_button", button);
258     return entry;
259     }
260    
261 gbeauche 1.1 static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active)
262     {
263     GtkWidget *box, *label, *opt, *menu;
264    
265     box = gtk_hbox_new(FALSE, 4);
266     gtk_widget_show(box);
267     gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
268    
269     label = gtk_label_new(GetString(label_id));
270     gtk_widget_show(label);
271     gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
272    
273     opt = gtk_option_menu_new();
274     gtk_widget_show(opt);
275     menu = gtk_menu_new();
276    
277     while (options->label_id) {
278     add_menu_item(menu, options->label_id, options->func);
279     options++;
280     }
281     gtk_menu_set_active(GTK_MENU(menu), active);
282    
283     gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
284     gtk_box_pack_start(GTK_BOX(box), opt, FALSE, FALSE, 0);
285     return menu;
286     }
287    
288     static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false)
289     {
290     GtkWidget *box, *label, *entry;
291    
292     box = gtk_hbox_new(FALSE, 4);
293     gtk_widget_show(box);
294     gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
295    
296     label = gtk_label_new(GetString(label_id));
297     gtk_widget_show(label);
298     gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
299    
300     const char *str = PrefsFindString(prefs_item);
301     if (str == NULL)
302     str = "";
303    
304     entry = gtk_entry_new();
305     gtk_entry_set_text(GTK_ENTRY(entry), str);
306     gtk_widget_show(entry);
307     gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
308     return entry;
309     }
310    
311     static const gchar *get_file_entry_path(GtkWidget *entry)
312     {
313     return gtk_entry_get_text(GTK_ENTRY(entry));
314     }
315    
316     static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func)
317     {
318     GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
319     gtk_widget_show(button);
320     gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item));
321     gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
322     gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
323     return button;
324     }
325    
326 gbeauche 1.9 static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *default_value, GList *glist)
327 gbeauche 1.1 {
328     GtkWidget *box, *label, *combo;
329    
330     box = gtk_hbox_new(FALSE, 4);
331     gtk_widget_show(box);
332     gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
333    
334     label = gtk_label_new(GetString(label_id));
335     gtk_widget_show(label);
336     gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
337    
338     combo = gtk_combo_new();
339     gtk_widget_show(combo);
340     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
341    
342 gbeauche 1.9 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value);
343 gbeauche 1.1 gtk_box_pack_start(GTK_BOX(box), combo, TRUE, TRUE, 0);
344    
345     return combo;
346     }
347    
348 gbeauche 1.9 static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *default_value, const combo_desc *options)
349     {
350     GList *glist = NULL;
351     while (options->label_id) {
352     glist = g_list_append(glist, (void *)GetString(options->label_id));
353     options++;
354     }
355    
356     return make_combobox(top, label_id, default_value, glist);
357     }
358    
359 gbeauche 1.1
360     /*
361     * Show preferences editor
362     * Returns true when user clicked on "Start", false otherwise
363     */
364    
365     // Window closed
366     static gint window_closed(void)
367     {
368     return FALSE;
369     }
370    
371     // Window destroyed
372     static void window_destroyed(void)
373     {
374     gtk_main_quit();
375     }
376    
377     // "Start" button clicked
378     static void cb_start(...)
379     {
380     start_clicked = true;
381     read_settings();
382     SavePrefs();
383     gtk_widget_destroy(win);
384     }
385    
386     // "Zap PRAM" button clicked
387     static void cb_zap_pram(...)
388     {
389     ZapPRAM();
390     }
391    
392     // "Quit" button clicked
393     static void cb_quit(...)
394     {
395     start_clicked = false;
396     gtk_widget_destroy(win);
397     }
398    
399     // "OK" button of "About" dialog clicked
400     static void dl_quit(GtkWidget *dialog)
401     {
402     gtk_widget_destroy(dialog);
403     }
404    
405     // "About" button clicked
406     static void cb_about(...)
407     {
408     GtkWidget *dialog;
409    
410     GtkWidget *label, *button;
411    
412     char str[512];
413     sprintf(str,
414 gbeauche 1.8 PROGRAM_NAME "\nVersion %d.%d\n\n"
415 gbeauche 1.1 "Copyright (C) 1997-2005 Christian Bauer et al.\n"
416 gbeauche 1.8 "E-mail: cb@cebix.net\n"
417     #ifdef SHEEPSHAVER
418     "http://sheepshaver.cebix.net/\n\n"
419     #else
420     "http://basilisk.cebix.net/\n\n"
421     #endif
422     PROGRAM_NAME " comes with ABSOLUTELY NO\n"
423 gbeauche 1.1 "WARRANTY. This is free software, and\n"
424     "you are welcome to redistribute it\n"
425     "under the terms of the GNU General\n"
426     "Public License.\n",
427     VERSION_MAJOR, VERSION_MINOR
428     );
429    
430     dialog = gtk_dialog_new();
431     gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE));
432     gtk_container_border_width(GTK_CONTAINER(dialog), 5);
433     gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
434    
435     label = gtk_label_new(str);
436     gtk_widget_show(label);
437     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
438    
439     button = gtk_button_new_with_label(GetString(STR_OK_BUTTON));
440     gtk_widget_show(button);
441     gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
442     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
443     GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
444     gtk_widget_grab_default(button);
445    
446     gtk_widget_show(dialog);
447     }
448    
449     // Menu item descriptions
450     static GtkItemFactoryEntry menu_items[] = {
451     {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, "<Branch>"},
452 gbeauche 1.6 {(gchar *)GetString(STR_PREFS_ITEM_START_GTK), "<control>S", GTK_SIGNAL_FUNC(cb_start), 0, NULL},
453 gbeauche 1.1 {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, GTK_SIGNAL_FUNC(cb_zap_pram), 0, NULL},
454     {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, "<Separator>"},
455     {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL},
456     {(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, "<LastBranch>"},
457 gbeauche 1.6 {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), "<control>H", GTK_SIGNAL_FUNC(cb_about), 0, NULL}
458 gbeauche 1.1 };
459    
460     bool PrefsEditor(void)
461     {
462     // Create window
463     win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
464     gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE));
465     gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL);
466     gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL);
467    
468     // Create window contents
469     GtkWidget *box = gtk_vbox_new(FALSE, 4);
470     gtk_widget_show(box);
471     gtk_container_add(GTK_CONTAINER(win), box);
472    
473     GtkAccelGroup *accel_group = gtk_accel_group_new();
474     GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
475     gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL);
476     #if GTK_CHECK_VERSION(1,3,15)
477     gtk_window_add_accel_group(GTK_WINDOW(win), accel_group);
478     #else
479     gtk_accel_group_attach(accel_group, GTK_OBJECT(win));
480     #endif
481     GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "<main>");
482     gtk_widget_show(menu_bar);
483     gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);
484    
485     GtkWidget *notebook = gtk_notebook_new();
486     gtk_widget_show(notebook);
487     gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
488     gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE);
489     gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
490    
491     create_volumes_pane(notebook);
492 gbeauche 1.5 // create_scsi_pane(notebook); XXX not ready yet (merge scsi_windows.cpp from original B2/Win)
493 gbeauche 1.1 create_graphics_pane(notebook);
494     create_input_pane(notebook);
495     create_serial_pane(notebook);
496     create_ethernet_pane(notebook);
497     create_memory_pane(notebook);
498     create_jit_pane(notebook);
499    
500     static const opt_desc buttons[] = {
501     {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
502     {STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)},
503     {0, NULL}
504     };
505     make_button_box(box, 4, buttons);
506    
507     // Show window and enter main loop
508     gtk_widget_show(win);
509     gtk_main();
510     return start_clicked;
511     }
512    
513    
514     /*
515     * "Volumes" pane
516     */
517    
518 gbeauche 1.9 static GtkWidget *w_enableextfs, *w_extdrives, *w_cdrom_drive;
519 gbeauche 1.1 static GtkWidget *volume_list;
520     static int selected_volume;
521    
522 gbeauche 1.4 // Set sensitivity of widgets
523     static void set_volumes_sensitive(void)
524     {
525     const bool enable_extfs = PrefsFindBool("enableextfs");
526     gtk_widget_set_sensitive(w_extdrives, enable_extfs);
527 gbeauche 1.9 const bool no_cdrom = PrefsFindBool("nocdrom");
528     gtk_widget_set_sensitive(w_cdrom_drive, !no_cdrom);
529 gbeauche 1.4 }
530    
531 gbeauche 1.1 // Volume in list selected
532     static void cl_selected(GtkWidget *list, int row, int column)
533     {
534     selected_volume = row;
535     }
536    
537     // Volume selected for addition
538     static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
539     {
540     gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
541     gtk_clist_append(GTK_CLIST(volume_list), &file);
542     gtk_widget_destroy(assoc->req);
543     delete assoc;
544     }
545    
546     // Volume selected for creation
547     static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
548     {
549     gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
550    
551     const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
552 gbeauche 1.4 size_t size = atoi(str) << 20;
553 gbeauche 1.1
554 gbeauche 1.4 int fd = _open(file, _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC, _S_IREAD | _S_IWRITE);
555     if (fd >= 0) {
556     if (_chsize(fd, size) == 0)
557 gbeauche 1.1 gtk_clist_append(GTK_CLIST(volume_list), &file);
558 gbeauche 1.4 _close(fd);
559     }
560 gbeauche 1.1 gtk_widget_destroy(GTK_WIDGET(assoc->req));
561     delete assoc;
562     }
563    
564     // "Add Volume" button clicked
565     static void cb_add_volume(...)
566     {
567     GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_TITLE));
568     gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
569     gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL));
570     gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
571     gtk_widget_show(req);
572     }
573    
574     // "Create Hardfile" button clicked
575     static void cb_create_volume(...)
576     {
577     GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE));
578    
579     GtkWidget *box = gtk_hbox_new(FALSE, 4);
580     gtk_widget_show(box);
581     GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL));
582     gtk_widget_show(label);
583     GtkWidget *entry = gtk_entry_new();
584     gtk_widget_show(entry);
585     char str[32];
586     sprintf(str, "%d", 40);
587     gtk_entry_set_text(GTK_ENTRY(entry), str);
588     gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
589     gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0);
590     gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0);
591    
592     gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
593     gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry));
594     gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
595     gtk_widget_show(req);
596     }
597    
598     // "Remove Volume" button clicked
599     static void cb_remove_volume(...)
600     {
601     gtk_clist_remove(GTK_CLIST(volume_list), selected_volume);
602     }
603    
604     // "Boot From" selected
605     static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);}
606     static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);}
607    
608 gbeauche 1.4 // "Enable external file system" button toggled
609     static void tb_enableextfs(GtkWidget *widget)
610     {
611     PrefsReplaceBool("enableextfs", GTK_TOGGLE_BUTTON(widget)->active);
612     set_volumes_sensitive();
613     }
614    
615 gbeauche 1.1 // "No CD-ROM Driver" button toggled
616     static void tb_nocdrom(GtkWidget *widget)
617     {
618     PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active);
619 gbeauche 1.9 set_volumes_sensitive();
620     }
621    
622     // Add names of CD-ROM devices
623     static GList *add_cdrom_names(void)
624     {
625     GList *glist = NULL;
626    
627     char rootdir[4] = "X:\\";
628     for (char letter = 'C'; letter <= 'Z'; letter++) {
629     rootdir[0] = letter;
630     if (GetDriveType(rootdir) == DRIVE_CDROM)
631     glist = g_list_append(glist, strdup(rootdir));
632     }
633    
634     return glist;
635 gbeauche 1.1 }
636    
637 gbeauche 1.4 // "Enable polling" button toggled
638     static void tb_pollmedia(GtkWidget *widget)
639     {
640     PrefsReplaceBool("pollmedia", GTK_TOGGLE_BUTTON(widget)->active);
641     }
642    
643 gbeauche 1.1 // Read settings from widgets and set preferences
644     static void read_volumes_settings(void)
645     {
646     while (PrefsFindString("disk"))
647     PrefsRemoveItem("disk");
648    
649     for (int i=0; i<GTK_CLIST(volume_list)->rows; i++) {
650     char *str;
651     gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str);
652     PrefsAddString("disk", str);
653     }
654 gbeauche 1.4
655 gbeauche 1.9 const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_cdrom_drive)->entry));
656     if (str && strlen(str))
657     PrefsReplaceString("cdrom", str);
658     else
659     PrefsRemoveItem("cdrom");
660    
661 gbeauche 1.4 PrefsReplaceString("extdrives", get_file_entry_path(w_extdrives));
662 gbeauche 1.1 }
663    
664     // Create "Volumes" pane
665     static void create_volumes_pane(GtkWidget *top)
666     {
667     GtkWidget *box, *scroll, *menu;
668    
669     box = make_pane(top, STR_VOLUMES_PANE_TITLE);
670    
671     scroll = gtk_scrolled_window_new(NULL, NULL);
672     gtk_widget_show(scroll);
673     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
674     volume_list = gtk_clist_new(1);
675     gtk_widget_show(volume_list);
676     gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
677     gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
678     gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
679     gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
680     char *str;
681     int32 index = 0;
682     while ((str = const_cast<char *>(PrefsFindString("disk", index++))) != NULL)
683     gtk_clist_append(GTK_CLIST(volume_list), &str);
684     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list);
685     gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0);
686     selected_volume = 0;
687    
688     static const opt_desc buttons[] = {
689     {STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)},
690     {STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)},
691     {STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)},
692     {0, NULL},
693     };
694     make_button_box(box, 0, buttons);
695     make_separator(box);
696    
697     static const opt_desc options[] = {
698     {STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)},
699     {STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)},
700     {0, NULL}
701     };
702     int bootdriver = PrefsFindInt32("bootdriver"), active = 0;
703     switch (bootdriver) {
704     case 0: active = 0; break;
705     case CDROMRefNum: active = 1; break;
706     }
707     menu = make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active);
708    
709     make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
710 gbeauche 1.4
711 gbeauche 1.9 GList *glist = add_cdrom_names();
712     str = const_cast<char *>(PrefsFindString("cdrom"));
713     if (str == NULL)
714     str = "";
715     w_cdrom_drive = make_combobox(box, STR_CDROM_DRIVE_CTRL, str, glist);
716    
717 gbeauche 1.4 make_checkbox(box, STR_POLLMEDIA_CTRL, "pollmedia", GTK_SIGNAL_FUNC(tb_pollmedia));
718    
719     make_separator(box);
720     w_enableextfs = make_checkbox(box, STR_EXTFS_ENABLE_CTRL, "enableextfs", GTK_SIGNAL_FUNC(tb_enableextfs));
721     w_extdrives = make_file_entry(box, STR_EXTFS_DRIVES_CTRL, "extdrives", true);
722    
723     set_volumes_sensitive();
724 gbeauche 1.1 }
725    
726    
727     /*
728     * "JIT Compiler" pane
729     */
730    
731 gbeauche 1.8 #ifndef SHEEPSHAVER
732 gbeauche 1.1 static GtkWidget *w_jit_fpu;
733     static GtkWidget *w_jit_atraps;
734     static GtkWidget *w_jit_cache_size;
735     static GtkWidget *w_jit_lazy_flush;
736     static GtkWidget *w_jit_follow_const_jumps;
737 gbeauche 1.8 #endif
738 gbeauche 1.1
739     // Set sensitivity of widgets
740     static void set_jit_sensitive(void)
741     {
742 gbeauche 1.8 #ifndef SHEEPSHAVER
743 gbeauche 1.1 const bool jit_enabled = PrefsFindBool("jit");
744     gtk_widget_set_sensitive(w_jit_fpu, jit_enabled);
745     gtk_widget_set_sensitive(w_jit_cache_size, jit_enabled);
746     gtk_widget_set_sensitive(w_jit_lazy_flush, jit_enabled);
747     gtk_widget_set_sensitive(w_jit_follow_const_jumps, jit_enabled);
748 gbeauche 1.8 #endif
749 gbeauche 1.1 }
750    
751     // "Use JIT Compiler" button toggled
752     static void tb_jit(GtkWidget *widget)
753     {
754     PrefsReplaceBool("jit", GTK_TOGGLE_BUTTON(widget)->active);
755     set_jit_sensitive();
756     }
757    
758     // "Compile FPU Instructions" button toggled
759 gbeauche 1.8 #ifndef SHEEPSHAVER
760 gbeauche 1.1 static void tb_jit_fpu(GtkWidget *widget)
761     {
762     PrefsReplaceBool("jitfpu", GTK_TOGGLE_BUTTON(widget)->active);
763     }
764 gbeauche 1.8 #endif
765 gbeauche 1.1
766     // "Lazy translation cache invalidation" button toggled
767 gbeauche 1.8 #ifndef SHEEPSHAVER
768 gbeauche 1.1 static void tb_jit_lazy_flush(GtkWidget *widget)
769     {
770     PrefsReplaceBool("jitlazyflush", GTK_TOGGLE_BUTTON(widget)->active);
771     }
772 gbeauche 1.8 #endif
773 gbeauche 1.1
774     // "Translate through constant jumps (inline blocks)" button toggled
775 gbeauche 1.8 #ifndef SHEEPSHAVER
776 gbeauche 1.1 static void tb_jit_follow_const_jumps(GtkWidget *widget)
777     {
778     PrefsReplaceBool("jitinline", GTK_TOGGLE_BUTTON(widget)->active);
779     }
780 gbeauche 1.8 #endif
781 gbeauche 1.1
782     // Read settings from widgets and set preferences
783     static void read_jit_settings(void)
784     {
785     #if USE_JIT
786     bool jit_enabled = PrefsFindBool("jit");
787     if (jit_enabled) {
788 gbeauche 1.8 #ifndef SHEEPSHAVER
789 gbeauche 1.1 const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry));
790     PrefsReplaceInt32("jitcachesize", atoi(str));
791 gbeauche 1.8 #endif
792 gbeauche 1.1 }
793     #endif
794     }
795    
796 gbeauche 1.8 // "Use built-in 68k DR emulator" button toggled
797     #ifdef SHEEPSHAVER
798     static void tb_jit_68k(GtkWidget *widget)
799     {
800     PrefsReplaceBool("jit68k", GTK_TOGGLE_BUTTON(widget)->active);
801     }
802     #endif
803    
804 gbeauche 1.1 // Create "JIT Compiler" pane
805     static void create_jit_pane(GtkWidget *top)
806     {
807     #if USE_JIT
808     GtkWidget *box, *table, *label, *menu;
809     char str[32];
810    
811     box = make_pane(top, STR_JIT_PANE_TITLE);
812     make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit));
813    
814 gbeauche 1.8 #ifndef SHEEPSHAVER
815 gbeauche 1.1 w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", GTK_SIGNAL_FUNC(tb_jit_fpu));
816    
817     // Translation cache size
818     static const combo_desc options[] = {
819     STR_JIT_CACHE_SIZE_2MB_LAB,
820     STR_JIT_CACHE_SIZE_4MB_LAB,
821     STR_JIT_CACHE_SIZE_8MB_LAB,
822     STR_JIT_CACHE_SIZE_16MB_LAB,
823     0
824     };
825 gbeauche 1.9 sprintf(str, "%d", PrefsFindInt32("jitcachesize"));
826     w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, str, options);
827 gbeauche 1.1
828     // Lazy translation cache invalidation
829     w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", GTK_SIGNAL_FUNC(tb_jit_lazy_flush));
830    
831     // Follow constant jumps (inline basic blocks)
832     w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps));
833 gbeauche 1.8 #endif
834 gbeauche 1.1
835     set_jit_sensitive();
836     #endif
837 gbeauche 1.8
838     #ifdef SHEEPSHAVER
839     make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k));
840     #endif
841 gbeauche 1.1 }
842    
843     /*
844     * "SCSI" pane
845     */
846    
847     static GtkWidget *w_scsi[7];
848    
849     // Read settings from widgets and set preferences
850     static void read_scsi_settings(void)
851     {
852 gbeauche 1.8 #ifndef DISABLE_SCSI
853 gbeauche 1.1 for (int id=0; id<7; id++) {
854     char prefs_name[32];
855     sprintf(prefs_name, "scsi%d", id);
856     const char *str = get_file_entry_path(w_scsi[id]);
857     if (str && strlen(str))
858     PrefsReplaceString(prefs_name, str);
859     else
860     PrefsRemoveItem(prefs_name);
861     }
862 gbeauche 1.8 #endif
863 gbeauche 1.1 }
864    
865     // Create "SCSI" pane
866     static void create_scsi_pane(GtkWidget *top)
867     {
868 gbeauche 1.8 #ifndef DISABLE_SCSI
869 gbeauche 1.1 GtkWidget *box;
870    
871     box = make_pane(top, STR_SCSI_PANE_TITLE);
872    
873     for (int id=0; id<7; id++) {
874     char prefs_name[32];
875     sprintf(prefs_name, "scsi%d", id);
876     w_scsi[id] = make_file_entry(box, STR_SCSI_ID_0 + id, prefs_name);
877     }
878 gbeauche 1.8 #endif
879 gbeauche 1.1 }
880    
881    
882     /*
883     * "Graphics/Sound" pane
884     */
885    
886     // Display types
887     enum {
888     DISPLAY_WINDOW,
889     DISPLAY_SCREEN
890     };
891    
892     static GtkWidget *w_frameskip, *w_display_x, *w_display_y;
893     static GtkWidget *l_frameskip, *l_display_x, *l_display_y;
894     static int display_type;
895     static int dis_width, dis_height;
896    
897     // Hide/show graphics widgets
898     static void hide_show_graphics_widgets(void)
899     {
900     switch (display_type) {
901     case DISPLAY_WINDOW:
902     gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip);
903     break;
904     case DISPLAY_SCREEN:
905     gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip);
906     break;
907     }
908     }
909    
910     // "Window" video type selected
911     static void mn_window(...)
912     {
913     display_type = DISPLAY_WINDOW;
914     hide_show_graphics_widgets();
915     }
916    
917     // "Fullscreen" video type selected
918     static void mn_fullscreen(...)
919     {
920     display_type = DISPLAY_SCREEN;
921     hide_show_graphics_widgets();
922 gbeauche 1.7 PrefsReplaceInt32("frameskip", 1);
923 gbeauche 1.1 }
924    
925     // "5 Hz".."60Hz" selected
926     static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);}
927     static void mn_7hz(...) {PrefsReplaceInt32("frameskip", 8);}
928     static void mn_10hz(...) {PrefsReplaceInt32("frameskip", 6);}
929     static void mn_15hz(...) {PrefsReplaceInt32("frameskip", 4);}
930     static void mn_30hz(...) {PrefsReplaceInt32("frameskip", 2);}
931     static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);}
932     static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);}
933    
934 gbeauche 1.8 // QuickDraw acceleration
935     #ifdef SHEEPSHAVER
936     static void tb_gfxaccel(GtkWidget *widget)
937     {
938     PrefsReplaceBool("gfxaccel", GTK_TOGGLE_BUTTON(widget)->active);
939     }
940     #endif
941    
942 gbeauche 1.1 // Set sensitivity of widgets
943     static void set_graphics_sensitive(void)
944     {
945     const bool sound_enabled = !PrefsFindBool("nosound");
946     }
947    
948     // "Disable Sound Output" button toggled
949     static void tb_nosound(GtkWidget *widget)
950     {
951     PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active);
952     set_graphics_sensitive();
953     }
954    
955     // Read graphics preferences
956     static void parse_graphics_prefs(void)
957     {
958     display_type = DISPLAY_WINDOW;
959 gbeauche 1.8 #ifdef SHEEPSHAVER
960     dis_width = 640;
961     dis_height = 480;
962     #else
963 gbeauche 1.1 dis_width = 512;
964     dis_height = 384;
965 gbeauche 1.8 #endif
966 gbeauche 1.1
967     const char *str = PrefsFindString("screen");
968     if (str) {
969     if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2)
970     display_type = DISPLAY_WINDOW;
971     else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2)
972     display_type = DISPLAY_SCREEN;
973     }
974     }
975    
976     // Read settings from widgets and set preferences
977     static void read_graphics_settings(void)
978     {
979     const char *str;
980    
981     str = gtk_entry_get_text(GTK_ENTRY(w_display_x));
982     dis_width = atoi(str);
983    
984     str = gtk_entry_get_text(GTK_ENTRY(w_display_y));
985     dis_height = atoi(str);
986    
987     char pref[256];
988     switch (display_type) {
989     case DISPLAY_WINDOW:
990     sprintf(pref, "win/%d/%d", dis_width, dis_height);
991     break;
992     case DISPLAY_SCREEN:
993     sprintf(pref, "dga/%d/%d", dis_width, dis_height);
994     break;
995     default:
996     PrefsRemoveItem("screen");
997     return;
998     }
999     PrefsReplaceString("screen", pref);
1000     }
1001    
1002     // Create "Graphics/Sound" pane
1003     static void create_graphics_pane(GtkWidget *top)
1004     {
1005     GtkWidget *box, *table, *label, *opt, *menu, *combo;
1006     char str[32];
1007    
1008     parse_graphics_prefs();
1009    
1010     box = make_pane(top, STR_GRAPHICS_SOUND_PANE_TITLE);
1011     table = make_table(box, 2, 5);
1012    
1013     label = gtk_label_new(GetString(STR_VIDEO_TYPE_CTRL));
1014     gtk_widget_show(label);
1015     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1016    
1017     opt = gtk_option_menu_new();
1018     gtk_widget_show(opt);
1019     menu = gtk_menu_new();
1020     add_menu_item(menu, STR_WINDOW_LAB, GTK_SIGNAL_FUNC(mn_window));
1021     add_menu_item(menu, STR_FULLSCREEN_LAB, GTK_SIGNAL_FUNC(mn_fullscreen));
1022     switch (display_type) {
1023     case DISPLAY_WINDOW:
1024     gtk_menu_set_active(GTK_MENU(menu), 0);
1025     break;
1026     case DISPLAY_SCREEN:
1027     gtk_menu_set_active(GTK_MENU(menu), 1);
1028     break;
1029     }
1030     gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
1031     gtk_table_attach(GTK_TABLE(table), opt, 1, 2, 0, 1, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1032    
1033     l_frameskip = gtk_label_new(GetString(STR_FRAMESKIP_CTRL));
1034     gtk_widget_show(l_frameskip);
1035     gtk_table_attach(GTK_TABLE(table), l_frameskip, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1036    
1037     w_frameskip = gtk_option_menu_new();
1038     gtk_widget_show(w_frameskip);
1039     menu = gtk_menu_new();
1040     add_menu_item(menu, STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz));
1041     add_menu_item(menu, STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz));
1042     add_menu_item(menu, STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz));
1043     add_menu_item(menu, STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz));
1044     add_menu_item(menu, STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz));
1045     add_menu_item(menu, STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz));
1046     add_menu_item(menu, STR_REF_DYNAMIC_LAB, GTK_SIGNAL_FUNC(mn_dynamic));
1047     int frameskip = PrefsFindInt32("frameskip");
1048     int item = -1;
1049     switch (frameskip) {
1050     case 12: item = 0; break;
1051     case 8: item = 1; break;
1052     case 6: item = 2; break;
1053     case 4: item = 3; break;
1054     case 2: item = 4; break;
1055     case 1: item = 5; break;
1056     case 0: item = 6; break;
1057     }
1058     if (item >= 0)
1059     gtk_menu_set_active(GTK_MENU(menu), item);
1060     gtk_option_menu_set_menu(GTK_OPTION_MENU(w_frameskip), menu);
1061     gtk_table_attach(GTK_TABLE(table), w_frameskip, 1, 2, 1, 2, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1062    
1063     l_display_x = gtk_label_new(GetString(STR_DISPLAY_X_CTRL));
1064     gtk_widget_show(l_display_x);
1065     gtk_table_attach(GTK_TABLE(table), l_display_x, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1066    
1067     combo = gtk_combo_new();
1068     gtk_widget_show(combo);
1069     GList *glist1 = NULL;
1070     glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_512_LAB));
1071     glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_640_LAB));
1072     glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_800_LAB));
1073     glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_1024_LAB));
1074     glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_MAX_LAB));
1075     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist1);
1076     if (dis_width)
1077     sprintf(str, "%d", dis_width);
1078     else
1079     strcpy(str, GetString(STR_SIZE_MAX_LAB));
1080     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1081     gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1082     w_display_x = GTK_COMBO(combo)->entry;
1083    
1084     l_display_y = gtk_label_new(GetString(STR_DISPLAY_Y_CTRL));
1085     gtk_widget_show(l_display_y);
1086     gtk_table_attach(GTK_TABLE(table), l_display_y, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1087    
1088     combo = gtk_combo_new();
1089     gtk_widget_show(combo);
1090     GList *glist2 = NULL;
1091     glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_384_LAB));
1092     glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_480_LAB));
1093     glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_600_LAB));
1094     glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_768_LAB));
1095     glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_MAX_LAB));
1096     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist2);
1097     if (dis_height)
1098     sprintf(str, "%d", dis_height);
1099     else
1100     strcpy(str, GetString(STR_SIZE_MAX_LAB));
1101     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1102     gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1103     w_display_y = GTK_COMBO(combo)->entry;
1104    
1105 gbeauche 1.8 #ifdef SHEEPSHAVER
1106     make_checkbox(box, STR_GFXACCEL_CTRL, "gfxaccel", GTK_SIGNAL_FUNC(tb_gfxaccel));
1107     #endif
1108    
1109 gbeauche 1.1 make_separator(box);
1110     make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
1111    
1112     set_graphics_sensitive();
1113    
1114     hide_show_graphics_widgets();
1115     }
1116    
1117    
1118     /*
1119     * "Input" pane
1120     */
1121    
1122     static GtkWidget *w_keycode_file;
1123     static GtkWidget *w_mouse_wheel_lines;
1124    
1125     // Set sensitivity of widgets
1126     static void set_input_sensitive(void)
1127     {
1128 gbeauche 1.4 const bool use_keycodes = PrefsFindBool("keycodes");
1129     gtk_widget_set_sensitive(w_keycode_file, use_keycodes);
1130     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_keycode_file), "chooser_button")), use_keycodes);
1131 gbeauche 1.1 gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1);
1132     }
1133    
1134     // "Use Raw Keycodes" button toggled
1135     static void tb_keycodes(GtkWidget *widget)
1136     {
1137     PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active);
1138     set_input_sensitive();
1139     }
1140    
1141     // "Mouse Wheel Mode" selected
1142     static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();}
1143     static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();}
1144    
1145     // Read settings from widgets and set preferences
1146     static void read_input_settings(void)
1147     {
1148     const char *str = get_file_entry_path(w_keycode_file);
1149     if (str && strlen(str))
1150     PrefsReplaceString("keycodefile", str);
1151     else
1152     PrefsRemoveItem("keycodefile");
1153    
1154     PrefsReplaceInt32("mousewheellines", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_mouse_wheel_lines)));
1155     }
1156    
1157     // Create "Input" pane
1158     static void create_input_pane(GtkWidget *top)
1159     {
1160 gbeauche 1.4 GtkWidget *box, *hbox, *menu, *label, *button;
1161 gbeauche 1.1 GtkObject *adj;
1162    
1163     box = make_pane(top, STR_INPUT_PANE_TITLE);
1164    
1165     make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
1166 gbeauche 1.4
1167     hbox = gtk_hbox_new(FALSE, 4);
1168     gtk_widget_show(hbox);
1169     gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1170    
1171     label = gtk_label_new(GetString(STR_KEYCODES_CTRL));
1172     gtk_widget_show(label);
1173     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1174    
1175     const char *str = PrefsFindString("keycodefile");
1176     if (str == NULL)
1177     str = "";
1178    
1179     w_keycode_file = gtk_entry_new();
1180     gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
1181     gtk_widget_show(w_keycode_file);
1182     gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0);
1183    
1184     button = make_browse_button(w_keycode_file);
1185     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1186     g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button);
1187 gbeauche 1.1
1188     make_separator(box);
1189    
1190     static const opt_desc options[] = {
1191     {STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)},
1192     {STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)},
1193     {0, NULL}
1194     };
1195     int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0;
1196     switch (wheelmode) {
1197     case 0: active = 0; break;
1198     case 1: active = 1; break;
1199     }
1200     menu = make_option_menu(box, STR_MOUSEWHEELMODE_CTRL, options, active);
1201    
1202     hbox = gtk_hbox_new(FALSE, 4);
1203     gtk_widget_show(hbox);
1204     gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1205    
1206     label = gtk_label_new(GetString(STR_MOUSEWHEELLINES_CTRL));
1207     gtk_widget_show(label);
1208     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1209    
1210     adj = gtk_adjustment_new(PrefsFindInt32("mousewheellines"), 1, 1000, 1, 5, 0);
1211     w_mouse_wheel_lines = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0);
1212     gtk_widget_show(w_mouse_wheel_lines);
1213     gtk_box_pack_start(GTK_BOX(hbox), w_mouse_wheel_lines, FALSE, FALSE, 0);
1214    
1215     set_input_sensitive();
1216     }
1217    
1218    
1219     /*
1220 gbeauche 1.2 * "Serial" pane
1221 gbeauche 1.1 */
1222    
1223 gbeauche 1.3 static GtkWidget *w_seriala, *w_portfile0;
1224     static GtkWidget *w_serialb, *w_portfile1;
1225 gbeauche 1.1
1226     // Set sensitivity of widgets
1227     static void set_serial_sensitive(void)
1228     {
1229     const char *str;
1230     bool is_file;
1231    
1232     str = gtk_entry_get_text(GTK_ENTRY(w_seriala));
1233     is_file = strcmp(str, "FILE") == 0;
1234     gtk_widget_set_sensitive(w_portfile0, is_file);
1235 gbeauche 1.3 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_portfile0), "chooser_button")), is_file);
1236 gbeauche 1.1
1237     str = gtk_entry_get_text(GTK_ENTRY(w_serialb));
1238     is_file = strcmp(str, "FILE") == 0;
1239     gtk_widget_set_sensitive(w_portfile1, is_file);
1240 gbeauche 1.3 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_portfile1), "chooser_button")), is_file);
1241 gbeauche 1.1 }
1242    
1243     // Read settings from widgets and set preferences
1244     static void read_serial_settings(void)
1245     {
1246     const char *str;
1247    
1248     str = gtk_entry_get_text(GTK_ENTRY(w_seriala));
1249     PrefsReplaceString("seriala", str);
1250    
1251     str = gtk_entry_get_text(GTK_ENTRY(w_serialb));
1252     PrefsReplaceString("serialb", str);
1253    
1254     str = gtk_entry_get_text(GTK_ENTRY(w_portfile0));
1255     PrefsReplaceString("portfile0", str);
1256    
1257     str = gtk_entry_get_text(GTK_ENTRY(w_portfile1));
1258     PrefsReplaceString("portfile1", str);
1259     }
1260    
1261     // Port changed in combo
1262     static void cb_serial_port_changed(...)
1263     {
1264     set_serial_sensitive();
1265     }
1266    
1267     // Add names of serial devices
1268     static GList *add_serial_names(void)
1269     {
1270     GList *glist = NULL;
1271    
1272     static const char *port_names[] = {
1273     "COM1", "COM2", "COM3", "COM4", "COM5", "COM6",
1274     "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6",
1275     "FILE",
1276     NULL
1277     };
1278    
1279     for (int i = 0; port_names[i] != NULL; i++)
1280     glist = g_list_append(glist, (void *)port_names[i]);
1281    
1282     return glist;
1283     }
1284    
1285 gbeauche 1.2 // Create "Serial" pane
1286 gbeauche 1.1 static void create_serial_pane(GtkWidget *top)
1287     {
1288     GtkWidget *box, *hbox, *table, *label, *combo, *sep, *entry;
1289     GtkObject *adj;
1290    
1291     box = make_pane(top, STR_SERIAL_PANE_TITLE);
1292     table = make_table(box, 2, 5);
1293    
1294     GList *glist = add_serial_names();
1295     const char *str = PrefsFindString("seriala");
1296 gbeauche 1.3 combo = table_make_combobox(table, 0, STR_SERIALA_CTRL, str, glist);
1297 gbeauche 1.1 w_seriala = GTK_COMBO(combo)->entry;
1298     gtk_signal_connect(GTK_OBJECT(w_seriala), "changed", GTK_SIGNAL_FUNC(cb_serial_port_changed), NULL);
1299    
1300 gbeauche 1.3 w_portfile0 = table_make_file_entry(table, 1, STR_FILE_CTRL, "portfile0");
1301 gbeauche 1.1
1302     sep = gtk_hseparator_new();
1303     gtk_widget_show(sep);
1304     gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1305    
1306     str = PrefsFindString("serialb");
1307 gbeauche 1.3 combo = table_make_combobox(table, 3, STR_SERIALB_CTRL, str, glist);
1308 gbeauche 1.1 w_serialb = GTK_COMBO(combo)->entry;
1309     gtk_signal_connect(GTK_OBJECT(w_serialb), "changed", GTK_SIGNAL_FUNC(cb_serial_port_changed), NULL);
1310    
1311 gbeauche 1.3 w_portfile1 = table_make_file_entry(table, 4, STR_FILE_CTRL, "portfile1");
1312 gbeauche 1.1
1313     set_serial_sensitive();
1314     }
1315    
1316    
1317     /*
1318     * "Ethernet" pane
1319     */
1320    
1321 gbeauche 1.5 static GtkWidget *w_ether;
1322     static GtkWidget *w_ftp_port_list, *w_tcp_port_list;
1323     static const char s_nat_router[] = "NAT/Router module";
1324 gbeauche 1.1
1325     // Set sensitivity of widgets
1326     static void set_ethernet_sensitive(void)
1327     {
1328 gbeauche 1.5 const char *str = gtk_entry_get_text(GTK_ENTRY(w_ether));
1329    
1330     bool is_nat_router = strcmp(str, s_nat_router) == 0;
1331     gtk_widget_set_sensitive(w_ftp_port_list, is_nat_router);
1332     gtk_widget_set_sensitive(w_tcp_port_list, is_nat_router);
1333 gbeauche 1.1 }
1334    
1335     // Read settings from widgets and set preferences
1336     static void read_ethernet_settings(void)
1337     {
1338     const char *str = gtk_entry_get_text(GTK_ENTRY(w_ether));
1339 gbeauche 1.5 if (str && strlen(str) > 6 && strncmp(str, "NDIS: ", 6) == 0)
1340     PrefsReplaceString("ether", &str[6]);
1341 gbeauche 1.1 else
1342     PrefsRemoveItem("ether");
1343 gbeauche 1.5
1344     const bool router_enabled = str && strcmp(str, s_nat_router) == 0;
1345     PrefsReplaceBool("routerenabled", router_enabled);
1346     if (router_enabled) {
1347     str = gtk_entry_get_text(GTK_ENTRY(w_ftp_port_list));
1348     PrefsReplaceString("ftp_port_list", str);
1349     str = gtk_entry_get_text(GTK_ENTRY(w_tcp_port_list));
1350     PrefsReplaceString("tcp_port", str);
1351     }
1352     }
1353    
1354     // Ethernet emulation type changed in menulist
1355     static void cb_ether_changed(...)
1356     {
1357     set_ethernet_sensitive();
1358 gbeauche 1.1 }
1359    
1360     // Add names of ethernet interfaces
1361     static GList *add_ether_names(void)
1362     {
1363     GList *glist = NULL;
1364    
1365     // TODO: Get list of all Ethernet interfaces
1366 gbeauche 1.5 glist = g_list_append(glist, (void *)s_nat_router);
1367     glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB));
1368 gbeauche 1.1 return glist;
1369     }
1370    
1371    
1372     // Create "Ethernet" pane
1373     static void create_ethernet_pane(GtkWidget *top)
1374     {
1375     GtkWidget *box, *hbox, *table, *label, *combo, *sep, *entry;
1376    
1377     box = make_pane(top, STR_NETWORK_PANE_TITLE);
1378     table = make_table(box, 2, 5);
1379    
1380     label = gtk_label_new(GetString(STR_ETHERNET_IF_CTRL));
1381     gtk_widget_show(label);
1382     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1383    
1384     GList *glist = add_ether_names();
1385     combo = gtk_combo_new();
1386     gtk_widget_show(combo);
1387     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
1388     const char *str = PrefsFindString("ether");
1389 gbeauche 1.5 if (str == NULL || str[0] == '\0') {
1390     if (PrefsFindBool("routerenabled"))
1391     str = s_nat_router;
1392     else
1393     str = GetString(STR_NONE_LAB);
1394     }
1395 gbeauche 1.1 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1396     gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1397     w_ether = GTK_COMBO(combo)->entry;
1398 gbeauche 1.5 gtk_signal_connect(GTK_OBJECT(w_ether), "changed", GTK_SIGNAL_FUNC(cb_ether_changed), NULL);
1399    
1400     sep = gtk_hseparator_new();
1401     gtk_widget_show(sep);
1402     gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1403    
1404     label = gtk_label_new(GetString(STR_ETHER_FTP_PORT_LIST_CTRL));
1405     gtk_widget_show(label);
1406     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1407    
1408     entry = gtk_entry_new();
1409     str = PrefsFindString("ftp_port_list");
1410     if (str == NULL)
1411     str = "";
1412     gtk_entry_set_text(GTK_ENTRY(entry), str);
1413     gtk_widget_show(entry);
1414     gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 2, 3, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1415     w_ftp_port_list = entry;
1416    
1417     label = gtk_label_new(GetString(STR_ETHER_TCP_PORT_LIST_CTRL));
1418     gtk_widget_show(label);
1419     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1420    
1421     entry = gtk_entry_new();
1422     str = PrefsFindString("tcp_port");
1423     if (str == NULL)
1424     str = "";
1425     gtk_entry_set_text(GTK_ENTRY(entry), str);
1426     gtk_widget_show(entry);
1427     gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 3, 4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1428     w_tcp_port_list = entry;
1429 gbeauche 1.1
1430     set_ethernet_sensitive();
1431     }
1432    
1433    
1434     /*
1435     * "Memory/Misc" pane
1436     */
1437    
1438 gbeauche 1.3 static GtkWidget *w_ramsize;
1439 gbeauche 1.1 static GtkWidget *w_rom_file;
1440    
1441 gbeauche 1.8 // Don't use CPU when idle?
1442     #ifdef SHEEPSHAVER
1443     static void tb_idlewait(GtkWidget *widget)
1444     {
1445     PrefsReplaceBool("idlewait", GTK_TOGGLE_BUTTON(widget)->active);
1446     }
1447     #endif
1448    
1449 gbeauche 1.1 // "Ignore SEGV" button toggled
1450     #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1451     static void tb_ignoresegv(GtkWidget *widget)
1452     {
1453     PrefsReplaceBool("ignoresegv", GTK_TOGGLE_BUTTON(widget)->active);
1454     }
1455     #endif
1456    
1457     // Model ID selected
1458     static void mn_modelid_5(...) {PrefsReplaceInt32("modelid", 5);}
1459     static void mn_modelid_14(...) {PrefsReplaceInt32("modelid", 14);}
1460    
1461     // CPU/FPU type
1462     static void mn_cpu_68020(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", false);}
1463     static void mn_cpu_68020_fpu(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", true);}
1464     static void mn_cpu_68030(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", false);}
1465     static void mn_cpu_68030_fpu(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", true);}
1466     static void mn_cpu_68040(...) {PrefsReplaceInt32("cpu", 4); PrefsReplaceBool("fpu", true);}
1467    
1468     // Read settings from widgets and set preferences
1469     static void read_memory_settings(void)
1470     {
1471 gbeauche 1.3 const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_ramsize)->entry));
1472     PrefsReplaceInt32("ramsize", atoi(str) << 20);
1473 gbeauche 1.1
1474 gbeauche 1.3 str = get_file_entry_path(w_rom_file);
1475 gbeauche 1.1 if (str && strlen(str))
1476     PrefsReplaceString("rom", str);
1477     else
1478     PrefsRemoveItem("rom");
1479    
1480     }
1481    
1482     // Create "Memory/Misc" pane
1483     static void create_memory_pane(GtkWidget *top)
1484     {
1485 gbeauche 1.3 GtkWidget *box, *hbox, *table, *label, *scale, *menu;
1486 gbeauche 1.1
1487     box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE);
1488 gbeauche 1.3 table = make_table(box, 2, 5);
1489 gbeauche 1.1
1490 gbeauche 1.3 static const combo_desc options[] = {
1491 gbeauche 1.8 #ifndef SHEEPSHAVER
1492 gbeauche 1.3 STR_RAMSIZE_2MB_LAB,
1493 gbeauche 1.8 #endif
1494 gbeauche 1.3 STR_RAMSIZE_4MB_LAB,
1495     STR_RAMSIZE_8MB_LAB,
1496     STR_RAMSIZE_16MB_LAB,
1497     STR_RAMSIZE_32MB_LAB,
1498     STR_RAMSIZE_64MB_LAB,
1499     STR_RAMSIZE_128MB_LAB,
1500     STR_RAMSIZE_256MB_LAB,
1501     STR_RAMSIZE_512MB_LAB,
1502 gbeauche 1.8 #ifndef SHEEPSHAVER
1503 gbeauche 1.3 STR_RAMSIZE_1024MB_LAB,
1504 gbeauche 1.8 #endif
1505 gbeauche 1.3 0
1506     };
1507     char default_ramsize[10];
1508     sprintf(default_ramsize, "%d", PrefsFindInt32("ramsize") >> 20);
1509     w_ramsize = table_make_combobox(table, 0, STR_RAMSIZE_CTRL, default_ramsize, options);
1510 gbeauche 1.1
1511 gbeauche 1.8 #ifndef SHEEPSHAVER
1512 gbeauche 1.1 static const opt_desc model_options[] = {
1513     {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)},
1514     {STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)},
1515     {0, NULL}
1516     };
1517     int modelid = PrefsFindInt32("modelid"), active = 0;
1518     switch (modelid) {
1519     case 5: active = 0; break;
1520     case 14: active = 1; break;
1521     }
1522 gbeauche 1.3 table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active);
1523 gbeauche 1.8 #endif
1524 gbeauche 1.1
1525     #if EMULATED_68K
1526     static const opt_desc cpu_options[] = {
1527     {STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)},
1528     {STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)},
1529     {STR_CPU_68030_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030)},
1530     {STR_CPU_68030_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030_fpu)},
1531     {STR_CPU_68040_LAB, GTK_SIGNAL_FUNC(mn_cpu_68040)},
1532     {0, NULL}
1533     };
1534     int cpu = PrefsFindInt32("cpu");
1535     bool fpu = PrefsFindBool("fpu");
1536     active = 0;
1537     switch (cpu) {
1538     case 2: active = fpu ? 1 : 0; break;
1539     case 3: active = fpu ? 3 : 2; break;
1540     case 4: active = 4;
1541     }
1542 gbeauche 1.3 table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active);
1543 gbeauche 1.1 #endif
1544    
1545 gbeauche 1.3 w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom");
1546 gbeauche 1.1
1547     #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1548     make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
1549     #endif
1550 gbeauche 1.8
1551     #ifdef SHEEPSHAVER
1552     make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", GTK_SIGNAL_FUNC(tb_idlewait));
1553     #endif
1554 gbeauche 1.1 }
1555    
1556    
1557     /*
1558     * Read settings from widgets and set preferences
1559     */
1560    
1561     static void read_settings(void)
1562     {
1563     read_volumes_settings();
1564     read_scsi_settings();
1565     read_graphics_settings();
1566     read_input_settings();
1567     read_serial_settings();
1568     read_ethernet_settings();
1569     read_memory_settings();
1570     read_jit_settings();
1571     }
1572    
1573    
1574     /*
1575     * Fake unused data and functions
1576     */
1577    
1578     uint8 XPRAM[XPRAM_SIZE];
1579     void MountVolume(void *fh) { }
1580     void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
1581     void WarningAlert(const char *text) { }
1582    
1583    
1584     /*
1585     * Add default serial prefs (must be added, even if no ports present)
1586     */
1587    
1588     void SysAddSerialPrefs(void)
1589     {
1590     PrefsAddString("seriala", "COM1");
1591     PrefsAddString("serialb", "COM2");
1592     }
1593    
1594    
1595     /*
1596 gbeauche 1.5 * Display alerts
1597     */
1598    
1599     static void display_alert(int title_id, const char *text, int flags)
1600     {
1601     MessageBox(NULL, text, GetString(title_id), MB_OK | flags);
1602     }
1603    
1604     static void ErrorAlert(const char *text)
1605     {
1606     display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
1607     }
1608    
1609    
1610     /*
1611 gbeauche 1.1 * Start standalone GUI
1612     */
1613    
1614     int main(int argc, char *argv[])
1615     {
1616     // Init GTK
1617     gtk_set_locale();
1618     gtk_init(&argc, &argv);
1619    
1620     // Read preferences
1621     PrefsInit(argc, argv);
1622    
1623     // Show preferences editor
1624     bool start = PrefsEditor();
1625    
1626     // Exit preferences
1627     PrefsExit();
1628    
1629 gbeauche 1.8 // Transfer control to the executable
1630 gbeauche 1.1 if (start) {
1631 gbeauche 1.5 char path[_MAX_PATH];
1632     bool ok = GetModuleFileName(NULL, path, sizeof(path)) != 0;
1633     if (ok) {
1634     char b2_path[_MAX_PATH];
1635     char *p = strrchr(path, '\\');
1636     *++p = '\0';
1637     SetCurrentDirectory(path);
1638     strcpy(b2_path, path);
1639 gbeauche 1.8 strcat(b2_path, PROGRAM_NAME);
1640     strcat(b2_path, ".exe");
1641 gbeauche 1.5 HINSTANCE h = ShellExecute(GetDesktopWindow(), "open",
1642     b2_path, "", path, SW_SHOWNORMAL);
1643     if ((int)h <= 32)
1644     ok = false;
1645     }
1646     if (!ok) {
1647 gbeauche 1.8 ErrorAlert("Coult not start " PROGRAM_NAME " executable");
1648 gbeauche 1.5 return 1;
1649     }
1650 gbeauche 1.1 }
1651    
1652     return 0;
1653     }