ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/prefs_editor_gtk.cpp
Revision: 1.21
Committed: 2002-01-22T17:15:10Z (22 years, 5 months ago) by cebix
Branch: MAIN
Changes since 1.20: +82 -14 lines
Log Message:
GNOME-style about box and GNOME file entries are used if libgnomeui is present

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