ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/prefs_editor_gtk.cpp
Revision: 1.12
Committed: 2005-03-19T09:35:01Z (19 years, 3 months ago) by gbeauche
Branch: MAIN
Changes since 1.11: +8 -4 lines
Log Message:
let it build against gtk2

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * prefs_editor_linux.cpp - Preferences editor, Linux implementation using GTK+
3     *
4 gbeauche 1.11 * SheepShaver (C) 1997-2005 Christian Bauer and Marc Hellwig
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     #include "user_strings.h"
32     #include "version.h"
33     #include "cdrom.h"
34     #include "xpram.h"
35     #include "prefs.h"
36     #include "prefs_editor.h"
37    
38    
39     // Global variables
40     static GtkWidget *win; // Preferences window
41     static bool start_clicked = true; // Return value of PrefsEditor() function
42    
43    
44     // Prototypes
45     static void create_volumes_pane(GtkWidget *top);
46     static void create_graphics_pane(GtkWidget *top);
47 gbeauche 1.2 static void create_input_pane(GtkWidget *top);
48 cebix 1.1 static void create_serial_pane(GtkWidget *top);
49     static void create_memory_pane(GtkWidget *top);
50 gbeauche 1.3 static void create_jit_pane(GtkWidget *top);
51 cebix 1.1 static void read_settings(void);
52    
53    
54     /*
55     * Utility functions
56     */
57    
58     struct opt_desc {
59     int label_id;
60     GtkSignalFunc func;
61     };
62    
63     static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
64     {
65     GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id));
66     gtk_widget_show(item);
67     gtk_signal_connect(GTK_OBJECT(item), "activate", func, NULL);
68     gtk_menu_append(GTK_MENU(menu), item);
69     }
70    
71     static GtkWidget *make_pane(GtkWidget *notebook, int title_id)
72     {
73     GtkWidget *frame, *label, *box;
74    
75     frame = gtk_frame_new(NULL);
76     gtk_widget_show(frame);
77     gtk_container_border_width(GTK_CONTAINER(frame), 4);
78    
79     label = gtk_label_new(GetString(title_id));
80     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
81    
82     box = gtk_vbox_new(FALSE, 4);
83     gtk_widget_show(box);
84     gtk_container_set_border_width(GTK_CONTAINER(box), 4);
85     gtk_container_add(GTK_CONTAINER(frame), box);
86     return box;
87     }
88    
89     static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons)
90     {
91     GtkWidget *bb, *button;
92    
93     bb = gtk_hbutton_box_new();
94     gtk_widget_show(bb);
95     gtk_container_set_border_width(GTK_CONTAINER(bb), border);
96     gtk_button_box_set_layout(GTK_BUTTON_BOX(bb), GTK_BUTTONBOX_DEFAULT_STYLE);
97     gtk_button_box_set_spacing(GTK_BUTTON_BOX(bb), 4);
98     gtk_box_pack_start(GTK_BOX(top), bb, FALSE, FALSE, 0);
99    
100     while (buttons->label_id) {
101     button = gtk_button_new_with_label(GetString(buttons->label_id));
102     gtk_widget_show(button);
103     gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL);
104     gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0);
105     buttons++;
106     }
107     return bb;
108     }
109    
110     static GtkWidget *make_separator(GtkWidget *top)
111     {
112     GtkWidget *sep = gtk_hseparator_new();
113     gtk_box_pack_start(GTK_BOX(top), sep, FALSE, FALSE, 0);
114     gtk_widget_show(sep);
115     return sep;
116     }
117    
118     static GtkWidget *make_table(GtkWidget *top, int x, int y)
119     {
120     GtkWidget *table = gtk_table_new(x, y, FALSE);
121     gtk_widget_show(table);
122     gtk_box_pack_start(GTK_BOX(top), table, FALSE, FALSE, 0);
123     return table;
124     }
125    
126     static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active)
127     {
128     GtkWidget *box, *label, *opt, *menu;
129    
130     box = gtk_hbox_new(FALSE, 4);
131     gtk_widget_show(box);
132     gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
133    
134     label = gtk_label_new(GetString(label_id));
135     gtk_widget_show(label);
136     gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
137    
138     opt = gtk_option_menu_new();
139     gtk_widget_show(opt);
140     menu = gtk_menu_new();
141    
142     while (options->label_id) {
143     add_menu_item(menu, options->label_id, options->func);
144     options++;
145     }
146     gtk_menu_set_active(GTK_MENU(menu), active);
147    
148     gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
149     gtk_box_pack_start(GTK_BOX(box), opt, FALSE, FALSE, 0);
150     return menu;
151     }
152    
153     static GtkWidget *make_entry(GtkWidget *top, int label_id, const char *prefs_item)
154     {
155     GtkWidget *box, *label, *entry;
156    
157     box = gtk_hbox_new(FALSE, 4);
158     gtk_widget_show(box);
159     gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
160    
161     label = gtk_label_new(GetString(label_id));
162     gtk_widget_show(label);
163     gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
164    
165     entry = gtk_entry_new();
166     gtk_widget_show(entry);
167     const char *str = PrefsFindString(prefs_item);
168     if (str == NULL)
169     str = "";
170     gtk_entry_set_text(GTK_ENTRY(entry), str);
171     gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
172     return entry;
173     }
174    
175 gbeauche 1.12 static const gchar *get_file_entry_path(GtkWidget *entry)
176 gbeauche 1.2 {
177     return gtk_entry_get_text(GTK_ENTRY(entry));
178     }
179    
180 cebix 1.1 static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func)
181     {
182     GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
183     gtk_widget_show(button);
184     gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item));
185     gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
186     gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
187     return button;
188     }
189    
190     static GtkWidget *make_checkbox(GtkWidget *top, int label_id, bool active, GtkSignalFunc func)
191     {
192     GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
193     gtk_widget_show(button);
194     gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), active);
195     gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
196     gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
197     return button;
198     }
199    
200    
201     /*
202     * Show preferences editor
203     * Returns true when user clicked on "Start", false otherwise
204     */
205    
206     // Window closed
207     static gint window_closed(void)
208     {
209     return FALSE;
210     }
211    
212     // Window destroyed
213     static void window_destroyed(void)
214     {
215     gtk_main_quit();
216     }
217    
218     // "Start" button clicked
219     static void cb_start(...)
220     {
221     start_clicked = true;
222     read_settings();
223     SavePrefs();
224     gtk_widget_destroy(win);
225     }
226    
227     // "Quit" button clicked
228     static void cb_quit(...)
229     {
230     start_clicked = false;
231     gtk_widget_destroy(win);
232     }
233    
234     // "OK" button of "About" dialog clicked
235     static void dl_quit(GtkWidget *dialog)
236     {
237     gtk_widget_destroy(dialog);
238     }
239    
240     // "About" selected
241     static void mn_about(...)
242     {
243     GtkWidget *dialog, *label, *button;
244    
245     char str[512];
246     sprintf(str,
247     "SheepShaver\nVersion %d.%d\n\n"
248 cebix 1.6 "Copyright (C) 1997-2004 Christian Bauer and Marc Hellwig\n"
249 cebix 1.1 "E-mail: Christian.Bauer@uni-mainz.de\n"
250     "http://www.uni-mainz.de/~bauec002/\n\n"
251     "SheepShaver comes with ABSOLUTELY NO\n"
252     "WARRANTY. This is free software, and\n"
253     "you are welcome to redistribute it\n"
254     "under the terms of the GNU General\n"
255     "Public License.\n",
256     VERSION_MAJOR, VERSION_MINOR
257     );
258    
259     dialog = gtk_dialog_new();
260     gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE));
261     gtk_container_border_width(GTK_CONTAINER(dialog), 5);
262     gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
263    
264     label = gtk_label_new(str);
265     gtk_widget_show(label);
266     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
267    
268     button = gtk_button_new_with_label(GetString(STR_OK_BUTTON));
269     gtk_widget_show(button);
270     gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
271     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
272     GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
273     gtk_widget_grab_default(button);
274     gtk_widget_show(dialog);
275     }
276    
277     // "Zap NVRAM" selected
278     static void mn_zap_pram(...)
279     {
280     ZapPRAM();
281     }
282    
283     // Menu item descriptions
284     static GtkItemFactoryEntry menu_items[] = {
285     {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, "<Branch>"},
286     {(gchar *)GetString(STR_PREFS_ITEM_START_GTK), NULL, GTK_SIGNAL_FUNC(cb_start), 0, NULL},
287     {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, GTK_SIGNAL_FUNC(mn_zap_pram), 0, NULL},
288     {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, "<Separator>"},
289     {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL},
290     {(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, "<LastBranch>"},
291     {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, GTK_SIGNAL_FUNC(mn_about), 0, NULL}
292     };
293    
294     bool PrefsEditor(void)
295     {
296     // Create window
297     win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
298     gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE));
299     gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL);
300     gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL);
301    
302     // Create window contents
303     GtkWidget *box = gtk_vbox_new(FALSE, 4);
304     gtk_widget_show(box);
305     gtk_container_add(GTK_CONTAINER(win), box);
306    
307     GtkAccelGroup *accel_group = gtk_accel_group_new();
308     GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
309     gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL);
310 gbeauche 1.12 #if GTK_CHECK_VERSION(1,3,15)
311     gtk_window_add_accel_group(GTK_WINDOW(win), accel_group);
312     #else
313 cebix 1.1 gtk_accel_group_attach(accel_group, GTK_OBJECT(win));
314 gbeauche 1.12 #endif
315 cebix 1.1 GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "<main>");
316     gtk_widget_show(menu_bar);
317     gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);
318    
319     GtkWidget *notebook = gtk_notebook_new();
320     gtk_widget_show(notebook);
321     gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
322     gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE);
323     gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
324    
325     create_volumes_pane(notebook);
326     create_graphics_pane(notebook);
327 gbeauche 1.2 create_input_pane(notebook);
328 cebix 1.1 create_serial_pane(notebook);
329     create_memory_pane(notebook);
330 gbeauche 1.3 create_jit_pane(notebook);
331 cebix 1.1
332     static const opt_desc buttons[] = {
333     {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
334     {STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)},
335     {0, NULL}
336     };
337     make_button_box(box, 4, buttons);
338    
339     // Show window and enter main loop
340     gtk_widget_show(win);
341     gtk_main();
342     return start_clicked;
343     }
344    
345    
346     /*
347     * "Volumes" pane
348     */
349    
350     static GtkWidget *volume_list, *w_extfs;
351     static int selected_volume;
352    
353     // Volume in list selected
354     static void cl_selected(GtkWidget *list, int row, int column)
355     {
356     selected_volume = row;
357     }
358    
359     struct file_req_assoc {
360     file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
361     GtkWidget *req;
362     GtkWidget *entry;
363     };
364    
365     // Volume selected for addition
366     static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
367     {
368 gbeauche 1.12 gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
369 cebix 1.1 gtk_clist_append(GTK_CLIST(volume_list), &file);
370     gtk_widget_destroy(assoc->req);
371     delete assoc;
372     }
373    
374     // Volume selected for creation
375     static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
376     {
377 gbeauche 1.12 gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
378 cebix 1.1
379 gbeauche 1.12 const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
380 cebix 1.1 int size = atoi(str);
381    
382     char cmd[1024];
383     sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", file, size);
384     int ret = system(cmd);
385     if (ret == 0)
386     gtk_clist_append(GTK_CLIST(volume_list), &file);
387     gtk_widget_destroy(GTK_WIDGET(assoc->req));
388     delete assoc;
389     }
390    
391     // "Add Volume" button clicked
392     static void cb_add_volume(...)
393     {
394     GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_TITLE));
395     gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
396     gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL));
397     gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
398     gtk_widget_show(req);
399     }
400    
401     // "Create Hardfile" button clicked
402     static void cb_create_volume(...)
403     {
404     GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE));
405    
406     GtkWidget *box = gtk_hbox_new(FALSE, 4);
407     gtk_widget_show(box);
408     GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL));
409     gtk_widget_show(label);
410     GtkWidget *entry = gtk_entry_new();
411     gtk_widget_show(entry);
412     char str[32];
413     sprintf(str, "%d", 40);
414     gtk_entry_set_text(GTK_ENTRY(entry), str);
415     gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
416     gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0);
417     gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0);
418    
419     gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
420     gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry));
421     gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
422     gtk_widget_show(req);
423     }
424    
425     // "Remove Volume" button clicked
426     static void cb_remove_volume(...)
427     {
428     gtk_clist_remove(GTK_CLIST(volume_list), selected_volume);
429     }
430    
431     // "Boot From" selected
432     static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);}
433     static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);}
434    
435     // "No CD-ROM Driver" button toggled
436     static void tb_nocdrom(GtkWidget *widget)
437     {
438     PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active);
439     }
440    
441     // Read settings from widgets and set preferences
442     static void read_volumes_settings(void)
443     {
444     while (PrefsFindString("disk"))
445     PrefsRemoveItem("disk");
446    
447     for (int i=0; i<GTK_CLIST(volume_list)->rows; i++) {
448     char *str;
449     gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str);
450     PrefsAddString("disk", str);
451     }
452    
453     PrefsReplaceString("extfs", gtk_entry_get_text(GTK_ENTRY(w_extfs)));
454     }
455    
456     // Create "Volumes" pane
457     static void create_volumes_pane(GtkWidget *top)
458     {
459     GtkWidget *box, *scroll, *menu;
460    
461     box = make_pane(top, STR_VOLUMES_PANE_TITLE);
462    
463     scroll = gtk_scrolled_window_new(NULL, NULL);
464     gtk_widget_show(scroll);
465     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
466     volume_list = gtk_clist_new(1);
467     gtk_widget_show(volume_list);
468     gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
469     gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
470     gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
471     gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
472     char *str;
473     int32 index = 0;
474     while ((str = (char *)PrefsFindString("disk", index++)) != NULL)
475     gtk_clist_append(GTK_CLIST(volume_list), &str);
476     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list);
477     gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0);
478     selected_volume = 0;
479    
480     static const opt_desc buttons[] = {
481     {STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)},
482     {STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)},
483     {STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)},
484     {0, NULL},
485     };
486     make_button_box(box, 0, buttons);
487     make_separator(box);
488    
489     w_extfs = make_entry(box, STR_EXTFS_CTRL, "extfs");
490    
491     static const opt_desc options[] = {
492     {STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)},
493     {STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)},
494     {0, NULL}
495     };
496     int bootdriver = PrefsFindInt32("bootdriver"), active = 0;
497     switch (bootdriver) {
498     case 0: active = 0; break;
499     case CDROMRefNum: active = 1; break;
500     }
501     menu = make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active);
502    
503     make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
504     }
505    
506    
507     /*
508 gbeauche 1.3 * "JIT Compiler" pane
509     */
510    
511     // Set sensitivity of widgets
512     static void set_jit_sensitive(void)
513     {
514     const bool jit_enabled = PrefsFindBool("jit");
515     }
516    
517     // "Use JIT Compiler" button toggled
518     static void tb_jit(GtkWidget *widget)
519     {
520     PrefsReplaceBool("jit", GTK_TOGGLE_BUTTON(widget)->active);
521     set_jit_sensitive();
522     }
523    
524     // Read settings from widgets and set preferences
525     static void read_jit_settings(void)
526     {
527     #if USE_JIT
528     bool jit_enabled = PrefsFindBool("jit");
529     #endif
530     }
531    
532 gbeauche 1.10 // "Use built-in 68k DR emulator" button toggled
533     static void tb_jit_68k(GtkWidget *widget)
534     {
535     PrefsReplaceBool("jit68k", GTK_TOGGLE_BUTTON(widget)->active);
536     }
537    
538 gbeauche 1.3 // Create "JIT Compiler" pane
539     static void create_jit_pane(GtkWidget *top)
540     {
541     GtkWidget *box, *table, *label, *menu;
542     char str[32];
543    
544     box = make_pane(top, STR_JIT_PANE_TITLE);
545 gbeauche 1.10 #if USE_JIT
546 gbeauche 1.3 make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit));
547     set_jit_sensitive();
548     #endif
549 gbeauche 1.10 make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k));
550 gbeauche 1.3 }
551    
552    
553     /*
554 cebix 1.1 * "Graphics/Sound" pane
555     */
556    
557     static GtkWidget *w_frameskip;
558    
559 gbeauche 1.4 static GtkWidget *w_dspdevice_file, *w_mixerdevice_file;
560    
561 cebix 1.1 // "5 Hz".."60Hz" selected
562     static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);}
563     static void mn_7hz(...) {PrefsReplaceInt32("frameskip", 8);}
564     static void mn_10hz(...) {PrefsReplaceInt32("frameskip", 6);}
565     static void mn_15hz(...) {PrefsReplaceInt32("frameskip", 4);}
566     static void mn_30hz(...) {PrefsReplaceInt32("frameskip", 2);}
567     static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);}
568    
569 gbeauche 1.9 // QuickDraw acceleration
570     static void tb_gfxaccel(GtkWidget *widget)
571     {
572     PrefsReplaceBool("gfxaccel", GTK_TOGGLE_BUTTON(widget)->active);
573     }
574    
575 cebix 1.1 // Video modes
576     static void tb_w640x480(GtkWidget *widget)
577     {
578     if (GTK_TOGGLE_BUTTON(widget)->active)
579     PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") | 1);
580     else
581     PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") & ~1);
582     }
583    
584     static void tb_w800x600(GtkWidget *widget)
585     {
586     if (GTK_TOGGLE_BUTTON(widget)->active)
587     PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") | 2);
588     else
589     PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") & ~2);
590     }
591    
592     static void tb_fs640x480(GtkWidget *widget)
593     {
594     if (GTK_TOGGLE_BUTTON(widget)->active)
595     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 1);
596     else
597     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~1);
598     }
599    
600     static void tb_fs800x600(GtkWidget *widget)
601     {
602     if (GTK_TOGGLE_BUTTON(widget)->active)
603     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 2);
604     else
605     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~2);
606     }
607    
608     static void tb_fs1024x768(GtkWidget *widget)
609     {
610     if (GTK_TOGGLE_BUTTON(widget)->active)
611     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 4);
612     else
613     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~4);
614     }
615    
616 gbeauche 1.8 static void tb_fs1152x768(GtkWidget *widget)
617     {
618     if (GTK_TOGGLE_BUTTON(widget)->active)
619     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 64);
620     else
621     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~64);
622     }
623    
624 cebix 1.1 static void tb_fs1152x900(GtkWidget *widget)
625     {
626     if (GTK_TOGGLE_BUTTON(widget)->active)
627     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 8);
628     else
629     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~8);
630     }
631    
632     static void tb_fs1280x1024(GtkWidget *widget)
633     {
634     if (GTK_TOGGLE_BUTTON(widget)->active)
635     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 16);
636     else
637     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~16);
638     }
639    
640     static void tb_fs1600x1200(GtkWidget *widget)
641     {
642     if (GTK_TOGGLE_BUTTON(widget)->active)
643     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 32);
644     else
645     PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~32);
646     }
647    
648 gbeauche 1.4 // Set sensitivity of widgets
649     static void set_graphics_sensitive(void)
650     {
651     const bool sound_enabled = !PrefsFindBool("nosound");
652     gtk_widget_set_sensitive(w_dspdevice_file, sound_enabled);
653     gtk_widget_set_sensitive(w_mixerdevice_file, sound_enabled);
654     }
655    
656 cebix 1.1 // "Disable Sound Output" button toggled
657     static void tb_nosound(GtkWidget *widget)
658     {
659     PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active);
660 gbeauche 1.4 set_graphics_sensitive();
661 cebix 1.1 }
662    
663     // Read settings from widgets and set preferences
664     static void read_graphics_settings(void)
665     {
666 gbeauche 1.4 PrefsReplaceString("dsp", get_file_entry_path(w_dspdevice_file));
667     PrefsReplaceString("mixer", get_file_entry_path(w_mixerdevice_file));
668 cebix 1.1 }
669    
670     // Create "Graphics/Sound" pane
671     static void create_graphics_pane(GtkWidget *top)
672     {
673     GtkWidget *box, *vbox, *frame;
674    
675     box = make_pane(top, STR_GRAPHICS_SOUND_PANE_TITLE);
676    
677     static const opt_desc options[] = {
678     {STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz)},
679     {STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz)},
680     {STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz)},
681     {STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz)},
682     {STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz)},
683     {STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz)},
684     {0, NULL}
685     };
686     int frameskip = PrefsFindInt32("frameskip"), active = 0;
687     switch (frameskip) {
688     case 12: active = 0; break;
689     case 8: active = 1; break;
690     case 6: active = 2; break;
691     case 4: active = 3; break;
692     case 2: active = 4; break;
693     case 1: active = 5; break;
694     }
695     w_frameskip = make_option_menu(box, STR_FRAMESKIP_CTRL, options, active);
696    
697 gbeauche 1.9 make_checkbox(box, STR_GFXACCEL_CTRL, PrefsFindBool("gfxaccel"), GTK_SIGNAL_FUNC(tb_gfxaccel));
698    
699 cebix 1.1 frame = gtk_frame_new (GetString(STR_VIDEO_MODE_CTRL));
700     gtk_widget_show(frame);
701     gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0);
702    
703     vbox = gtk_vbox_new(FALSE, 4);
704     gtk_widget_show(vbox);
705     gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
706     gtk_container_add(GTK_CONTAINER(frame), vbox);
707    
708     make_checkbox(vbox, STR_W_640x480_CTRL, PrefsFindInt32("windowmodes") & 1, GTK_SIGNAL_FUNC(tb_w640x480));
709     make_checkbox(vbox, STR_W_800x600_CTRL, PrefsFindInt32("windowmodes") & 2, GTK_SIGNAL_FUNC(tb_w800x600));
710     make_checkbox(vbox, STR_640x480_CTRL, PrefsFindInt32("screenmodes") & 1, GTK_SIGNAL_FUNC(tb_fs640x480));
711     make_checkbox(vbox, STR_800x600_CTRL, PrefsFindInt32("screenmodes") & 2, GTK_SIGNAL_FUNC(tb_fs800x600));
712     make_checkbox(vbox, STR_1024x768_CTRL, PrefsFindInt32("screenmodes") & 4, GTK_SIGNAL_FUNC(tb_fs1024x768));
713 gbeauche 1.8 make_checkbox(vbox, STR_1152x768_CTRL, PrefsFindInt32("screenmodes") & 64, GTK_SIGNAL_FUNC(tb_fs1152x768));
714 cebix 1.1 make_checkbox(vbox, STR_1152x900_CTRL, PrefsFindInt32("screenmodes") & 8, GTK_SIGNAL_FUNC(tb_fs1152x900));
715     make_checkbox(vbox, STR_1280x1024_CTRL, PrefsFindInt32("screenmodes") & 16, GTK_SIGNAL_FUNC(tb_fs1280x1024));
716     make_checkbox(vbox, STR_1600x1200_CTRL, PrefsFindInt32("screenmodes") & 32, GTK_SIGNAL_FUNC(tb_fs1600x1200));
717    
718 gbeauche 1.4 make_separator(box);
719 cebix 1.1 make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
720 gbeauche 1.4 w_dspdevice_file = make_entry(box, STR_DSPDEVICE_FILE_CTRL, "dsp");
721     w_mixerdevice_file = make_entry(box, STR_MIXERDEVICE_FILE_CTRL, "mixer");
722    
723     set_graphics_sensitive();
724 gbeauche 1.2 }
725    
726    
727     /*
728     * "Input" pane
729     */
730    
731     static GtkWidget *w_keycode_file;
732 gbeauche 1.5 static GtkWidget *w_mouse_wheel_lines;
733 gbeauche 1.2
734     // Set sensitivity of widgets
735     static void set_input_sensitive(void)
736     {
737     gtk_widget_set_sensitive(w_keycode_file, PrefsFindBool("keycodes"));
738 gbeauche 1.5 gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1);
739 gbeauche 1.2 }
740    
741     // "Use Raw Keycodes" button toggled
742     static void tb_keycodes(GtkWidget *widget)
743     {
744     PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active);
745     set_input_sensitive();
746     }
747    
748 gbeauche 1.5 // "Mouse Wheel Mode" selected
749     static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();}
750     static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();}
751    
752 gbeauche 1.2 // Read settings from widgets and set preferences
753     static void read_input_settings(void)
754     {
755     const char *str = get_file_entry_path(w_keycode_file);
756     if (str && strlen(str))
757     PrefsReplaceString("keycodefile", str);
758     else
759     PrefsRemoveItem("keycodefile");
760 gbeauche 1.5
761     PrefsReplaceInt32("mousewheellines", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_mouse_wheel_lines)));
762 gbeauche 1.2 }
763    
764     // Create "Input" pane
765     static void create_input_pane(GtkWidget *top)
766     {
767     GtkWidget *box, *hbox, *menu, *label;
768     GtkObject *adj;
769    
770     box = make_pane(top, STR_INPUT_PANE_TITLE);
771    
772     make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
773     w_keycode_file = make_entry(box, STR_KEYCODE_FILE_CTRL, "keycodefile");
774 gbeauche 1.5
775     make_separator(box);
776    
777     static const opt_desc options[] = {
778     {STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)},
779     {STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)},
780     {0, NULL}
781     };
782     int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0;
783     switch (wheelmode) {
784     case 0: active = 0; break;
785     case 1: active = 1; break;
786     }
787     menu = make_option_menu(box, STR_MOUSEWHEELMODE_CTRL, options, active);
788    
789     hbox = gtk_hbox_new(FALSE, 4);
790     gtk_widget_show(hbox);
791     gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
792    
793     label = gtk_label_new(GetString(STR_MOUSEWHEELLINES_CTRL));
794     gtk_widget_show(label);
795     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
796    
797     adj = gtk_adjustment_new(PrefsFindInt32("mousewheellines"), 1, 1000, 1, 5, 0);
798     w_mouse_wheel_lines = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0);
799     gtk_widget_show(w_mouse_wheel_lines);
800     gtk_box_pack_start(GTK_BOX(hbox), w_mouse_wheel_lines, FALSE, FALSE, 0);
801 gbeauche 1.2
802     set_input_sensitive();
803 cebix 1.1 }
804    
805    
806     /*
807     * "Serial/Network" pane
808     */
809    
810     static GtkWidget *w_seriala, *w_serialb, *w_ether;
811    
812     // Read settings from widgets and set preferences
813     static void read_serial_settings(void)
814     {
815     const char *str;
816    
817     str = gtk_entry_get_text(GTK_ENTRY(w_seriala));
818     PrefsReplaceString("seriala", str);
819    
820     str = gtk_entry_get_text(GTK_ENTRY(w_serialb));
821     PrefsReplaceString("serialb", str);
822    
823     str = gtk_entry_get_text(GTK_ENTRY(w_ether));
824     if (str && strlen(str))
825     PrefsReplaceString("ether", str);
826     else
827     PrefsRemoveItem("ether");
828     }
829    
830     // Add names of serial devices
831     static gint gl_str_cmp(gconstpointer a, gconstpointer b)
832     {
833     return strcmp((char *)a, (char *)b);
834     }
835    
836     static GList *add_serial_names(void)
837     {
838     GList *glist = NULL;
839    
840     // Search /dev for ttyS* and lp*
841     DIR *d = opendir("/dev");
842     if (d) {
843     struct dirent *de;
844     while ((de = readdir(d)) != NULL) {
845 gbeauche 1.7 #if defined(__linux__)
846 cebix 1.1 if (strncmp(de->d_name, "ttyS", 4) == 0 || strncmp(de->d_name, "lp", 2) == 0) {
847 gbeauche 1.7 #elif defined(__FreeBSD__)
848     if (strncmp(de->d_name, "cuaa", 4) == 0 || strncmp(de->d_name, "lpt", 3) == 0) {
849     #elif defined(__NetBSD__)
850     if (strncmp(de->d_name, "tty0", 4) == 0 || strncmp(de->d_name, "lpt", 3) == 0) {
851     #elif defined(sgi)
852     if (strncmp(de->d_name, "ttyf", 4) == 0 || strncmp(de->d_name, "plp", 3) == 0) {
853     #else
854     if (false) {
855     #endif
856 cebix 1.1 char *str = new char[64];
857     sprintf(str, "/dev/%s", de->d_name);
858     glist = g_list_append(glist, str);
859     }
860     }
861     closedir(d);
862     }
863     if (glist)
864     g_list_sort(glist, gl_str_cmp);
865     else
866     glist = g_list_append(glist, (void *)"<none>");
867     return glist;
868     }
869    
870     // Add names of ethernet interfaces
871     static GList *add_ether_names(void)
872     {
873     GList *glist = NULL;
874    
875     // Get list of all Ethernet interfaces
876     int s = socket(PF_INET, SOCK_DGRAM, 0);
877     if (s >= 0) {
878     char inbuf[8192];
879     struct ifconf ifc;
880     ifc.ifc_len = sizeof(inbuf);
881     ifc.ifc_buf = inbuf;
882     if (ioctl(s, SIOCGIFCONF, &ifc) == 0) {
883     struct ifreq req, *ifr = ifc.ifc_req;
884     for (int i=0; i<ifc.ifc_len; i+=sizeof(ifreq), ifr++) {
885     req = *ifr;
886 gbeauche 1.7 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(sgi)
887     if (ioctl(s, SIOCGIFADDR, &req) == 0 && (req.ifr_addr.sa_family == ARPHRD_ETHER || req.ifr_addr.sa_family == ARPHRD_ETHER+1)) {
888     #elif defined(__linux__)
889 cebix 1.1 if (ioctl(s, SIOCGIFHWADDR, &req) == 0 && req.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
890 gbeauche 1.7 #else
891     if (false) {
892     #endif
893 cebix 1.1 char *str = new char[64];
894     strncpy(str, ifr->ifr_name, 63);
895     glist = g_list_append(glist, str);
896     }
897     }
898     }
899     close(s);
900     }
901     if (glist)
902     g_list_sort(glist, gl_str_cmp);
903     else
904     glist = g_list_append(glist, (void *)"<none>");
905     return glist;
906     }
907    
908     // Create "Serial/Network" pane
909     static void create_serial_pane(GtkWidget *top)
910     {
911     GtkWidget *box, *table, *label, *combo;
912     GList *glist = add_serial_names();
913    
914     box = make_pane(top, STR_SERIAL_NETWORK_PANE_TITLE);
915     table = make_table(box, 2, 3);
916    
917     label = gtk_label_new(GetString(STR_SERPORTA_CTRL));
918     gtk_widget_show(label);
919     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
920    
921     combo = gtk_combo_new();
922     gtk_widget_show(combo);
923     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
924     const char *str = PrefsFindString("seriala");
925     if (str == NULL)
926     str = "";
927     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
928     gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
929     w_seriala = GTK_COMBO(combo)->entry;
930    
931     label = gtk_label_new(GetString(STR_SERPORTB_CTRL));
932     gtk_widget_show(label);
933     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
934    
935     combo = gtk_combo_new();
936     gtk_widget_show(combo);
937     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
938     str = PrefsFindString("serialb");
939     if (str == NULL)
940     str = "";
941     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
942     gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
943     w_serialb = GTK_COMBO(combo)->entry;
944    
945     label = gtk_label_new(GetString(STR_ETHERNET_IF_CTRL));
946     gtk_widget_show(label);
947     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
948    
949     glist = add_ether_names();
950     combo = gtk_combo_new();
951     gtk_widget_show(combo);
952     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
953     str = PrefsFindString("ether");
954     if (str == NULL)
955     str = "";
956     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
957     gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
958     w_ether = GTK_COMBO(combo)->entry;
959     }
960    
961    
962     /*
963     * "Memory/Misc" pane
964     */
965    
966     static GtkObject *w_ramsize_adj;
967     static GtkWidget *w_rom_file;
968    
969 gbeauche 1.9 // Don't use CPU when idle?
970     static void tb_idlewait(GtkWidget *widget)
971     {
972     PrefsReplaceBool("idlewait", GTK_TOGGLE_BUTTON(widget)->active);
973     }
974    
975 cebix 1.1 // "Ignore SEGV" button toggled
976     static void tb_ignoresegv(GtkWidget *widget)
977     {
978     PrefsReplaceBool("ignoresegv", GTK_TOGGLE_BUTTON(widget)->active);
979     }
980    
981     // Read settings from widgets and set preferences
982     static void read_memory_settings(void)
983     {
984     PrefsReplaceInt32("ramsize", int(GTK_ADJUSTMENT(w_ramsize_adj)->value) << 20);
985    
986     const char *str = gtk_entry_get_text(GTK_ENTRY(w_rom_file));
987     if (str && strlen(str))
988     PrefsReplaceString("rom", str);
989     else
990     PrefsRemoveItem("rom");
991     }
992    
993     // Create "Memory/Misc" pane
994     static void create_memory_pane(GtkWidget *top)
995     {
996     GtkWidget *box, *vbox, *hbox, *hbox2, *label, *scale;
997    
998     box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE);
999    
1000     hbox = gtk_hbox_new(FALSE, 4);
1001     gtk_widget_show(hbox);
1002    
1003     label = gtk_label_new(GetString(STR_RAMSIZE_SLIDER));
1004     gtk_widget_show(label);
1005     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1006    
1007     vbox = gtk_vbox_new(FALSE, 4);
1008     gtk_widget_show(vbox);
1009    
1010     gfloat min, max;
1011     min = 1;
1012     max = 256;
1013     w_ramsize_adj = gtk_adjustment_new(min, min, max, 1, 16, 0);
1014     gtk_adjustment_set_value(GTK_ADJUSTMENT(w_ramsize_adj), PrefsFindInt32("ramsize") >> 20);
1015    
1016     scale = gtk_hscale_new(GTK_ADJUSTMENT(w_ramsize_adj));
1017     gtk_widget_show(scale);
1018     gtk_scale_set_digits(GTK_SCALE(scale), 0);
1019     gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0);
1020    
1021     hbox2 = gtk_hbox_new(FALSE, 4);
1022     gtk_widget_show(hbox2);
1023    
1024     char val[32];
1025     sprintf(val, GetString(STR_RAMSIZE_FMT), int(min));
1026     label = gtk_label_new(val);
1027     gtk_widget_show(label);
1028     gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1029    
1030     sprintf(val, GetString(STR_RAMSIZE_FMT), int(max));
1031     label = gtk_label_new(val);
1032     gtk_widget_show(label);
1033     gtk_box_pack_end(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1034     gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, TRUE, 0);
1035     gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
1036     gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1037    
1038     w_rom_file = make_entry(box, STR_ROM_FILE_CTRL, "rom");
1039    
1040     make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
1041 gbeauche 1.9 make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", GTK_SIGNAL_FUNC(tb_idlewait));
1042 cebix 1.1 }
1043    
1044    
1045     /*
1046     * Read settings from widgets and set preferences
1047     */
1048    
1049     static void read_settings(void)
1050     {
1051     read_volumes_settings();
1052     read_graphics_settings();
1053     read_serial_settings();
1054     read_memory_settings();
1055 gbeauche 1.3 read_jit_settings();
1056 cebix 1.1 }