ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/prefs_editor_gtk.cpp
Revision: 1.16
Committed: 2001-06-30T20:18:36Z (23 years ago) by cebix
Branch: MAIN
Changes since 1.15: +13 -5 lines
Log Message:
- fixed compilation problems in fbdev DGA code
- nicer "about" dialog in GTK prefs editor
- display refresh is inhibited during mode switch if !HAVE_PTHREADS

File Contents

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