ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/prefs_editor_gtk.cpp
Revision: 1.32
Committed: 2006-04-16T16:32:45Z (18 years, 2 months ago) by gbeauche
Branch: MAIN
Changes since 1.31: +107 -0 lines
Log Message:
Enable build of a standalone GUI (first step).

File Contents

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