ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/prefs_editor_gtk.cpp
Revision: 1.10
Committed: 2005-11-29T22:59:44Z (18 years, 6 months ago) by gbeauche
Branch: MAIN
CVS Tags: nigel-build-17
Changes since 1.9: +39 -4 lines
Log Message:
Initial support for NDIS interfaces selection (very preliminary but working
for me on Windows XP, and actually faster than NAT/Router ethernet emulation)

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