ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/prefs_editor_gtk.cpp
Revision: 1.8
Committed: 2005-11-27T23:51:47Z (18 years, 6 months ago) by gbeauche
Branch: MAIN
Changes since 1.7: +95 -11 lines
Log Message:
SheepShaver GUI, remove extraneous "slirp" currently inexistent for Windows

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