ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/prefs_editor_gtk.cpp
Revision: 1.23
Committed: 2002-09-17T16:06:37Z (21 years, 8 months ago) by gbeauche
Branch: MAIN
Changes since 1.22: +115 -0 lines
Log Message:
Update prefs editor with "JIT Compiler" pane

File Contents

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