ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/prefs_editor_gtk.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/prefs_editor_gtk.cpp (file contents):
Revision 1.1 by cebix, 1999-10-03T14:16:25Z vs.
Revision 1.32 by gbeauche, 2006-04-16T16:32:45Z

# Line 1 | Line 1
1   /*
2   *  prefs_editor_gtk.cpp - Preferences editor, Unix implementation using GTK+
3   *
4 < *  Basilisk II (C) 1997-1999 Christian Bauer
4 > *  Basilisk II (C) 1997-2005 Christian Bauer
5   *
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
# Line 28 | Line 28
28   #include <net/if.h>
29   #include <net/if_arp.h>
30  
31 + #ifdef HAVE_GNOMEUI
32 + #include <gnome.h>
33 + #endif
34 +
35   #include "user_strings.h"
36   #include "version.h"
37   #include "cdrom.h"
# Line 45 | Line 49 | static bool start_clicked = true;      // Ret
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 + static void create_input_pane(GtkWidget *top);
53   static void create_serial_pane(GtkWidget *top);
54   static void create_memory_pane(GtkWidget *top);
55 + static void create_jit_pane(GtkWidget *top);
56   static void read_settings(void);
57  
58  
# Line 54 | Line 60 | static void read_settings(void);
60   *  Utility functions
61   */
62  
63 + #if ! GLIB_CHECK_VERSION(2,0,0)
64 + #define G_OBJECT(obj)                                                   GTK_OBJECT(obj)
65 + #define g_object_get_data(obj, key)                             gtk_object_get_data((obj), (key))
66 + #define g_object_set_data(obj, key, data)               gtk_object_set_data((obj), (key), (data))
67 + #endif
68 +
69   struct opt_desc {
70          int label_id;
71          GtkSignalFunc func;
72   };
73  
74 + struct combo_desc {
75 +        int label_id;
76 + };
77 +
78 + struct file_req_assoc {
79 +        file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
80 +        GtkWidget *req;
81 +        GtkWidget *entry;
82 + };
83 +
84 + static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc)
85 + {
86 +        gchar *file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
87 +        gtk_entry_set_text(GTK_ENTRY(assoc->entry), file);
88 +        gtk_widget_destroy(assoc->req);
89 +        delete assoc;
90 + }
91 +
92 + static void cb_browse(GtkWidget *widget, void *user_data)
93 + {
94 +        GtkWidget *req = gtk_file_selection_new(GetString(STR_BROWSE_TITLE));
95 +        gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
96 +        gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(cb_browse_ok), new file_req_assoc(req, (GtkWidget *)user_data));
97 +        gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
98 +        gtk_widget_show(req);
99 + }
100 +
101 + static GtkWidget *make_browse_button(GtkWidget *entry)
102 + {
103 +        GtkWidget *button;
104 +
105 +        button = gtk_button_new_with_label(GetString(STR_BROWSE_CTRL));
106 +        gtk_widget_show(button);
107 +        gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)cb_browse, (void *)entry);
108 +        return button;
109 + }
110 +
111   static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
112   {
113          GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id));
# Line 122 | Line 171 | static GtkWidget *make_table(GtkWidget *
171          return table;
172   }
173  
174 + static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active)
175 + {
176 +        GtkWidget *label, *opt, *menu;
177 +
178 +        label = gtk_label_new(GetString(label_id));
179 +        gtk_widget_show(label);
180 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
181 +
182 +        opt = gtk_option_menu_new();
183 +        gtk_widget_show(opt);
184 +        menu = gtk_menu_new();
185 +
186 +        while (options->label_id) {
187 +                add_menu_item(menu, options->label_id, options->func);
188 +                options++;
189 +        }
190 +        gtk_menu_set_active(GTK_MENU(menu), active);
191 +
192 +        gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
193 +        gtk_table_attach(GTK_TABLE(table), opt, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
194 +        return menu;
195 + }
196 +
197 + static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, GList *glist)
198 + {
199 +        GtkWidget *label, *combo;
200 +        char str[32];
201 +
202 +        label = gtk_label_new(GetString(label_id));
203 +        gtk_widget_show(label);
204 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
205 +        
206 +        combo = gtk_combo_new();
207 +        gtk_widget_show(combo);
208 +        gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
209 +
210 +        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value);
211 +        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
212 +        
213 +        return combo;
214 + }
215 +
216 + static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, const combo_desc *options)
217 + {
218 +        GList *glist = NULL;
219 +        while (options->label_id) {
220 +                glist = g_list_append(glist, (void *)GetString(options->label_id));
221 +                options++;
222 +        }
223 +
224 +        return table_make_combobox(table, row, label_id, default_value, glist);
225 + }
226 +
227 + static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id, const char *prefs_item, bool only_dirs = false)
228 + {
229 +        GtkWidget *box, *label, *entry, *button;
230 +
231 +        label = gtk_label_new(GetString(label_id));
232 +        gtk_widget_show(label);
233 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
234 +
235 +        const char *str = PrefsFindString(prefs_item);
236 +        if (str == NULL)
237 +                str = "";
238 +
239 +        box = gtk_hbox_new(FALSE, 4);
240 +        gtk_widget_show(box);
241 +        gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
242 +
243 +        entry = gtk_entry_new();
244 +        gtk_entry_set_text(GTK_ENTRY(entry), str);
245 +        gtk_widget_show(entry);
246 +        gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
247 +
248 +        button = make_browse_button(entry);
249 +        gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
250 +        g_object_set_data(G_OBJECT(entry), "chooser_button", button);
251 +        return entry;
252 + }
253 +
254   static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active)
255   {
256          GtkWidget *box, *label, *opt, *menu;
# Line 149 | Line 278 | static GtkWidget *make_option_menu(GtkWi
278          return menu;
279   }
280  
281 < static GtkWidget *make_entry(GtkWidget *top, int label_id, const char *prefs_item)
281 > static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false)
282   {
283          GtkWidget *box, *label, *entry;
284  
# Line 161 | Line 290 | static GtkWidget *make_entry(GtkWidget *
290          gtk_widget_show(label);
291          gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
292  
164        entry = gtk_entry_new();
165        gtk_widget_show(entry);
293          const char *str = PrefsFindString(prefs_item);
294          if (str == NULL)
295                  str = "";
296 +
297 + #ifdef HAVE_GNOMEUI
298 +        entry = gnome_file_entry_new(NULL, GetString(label_id));
299 +        if (only_dirs)
300 +                gnome_file_entry_set_directory(GNOME_FILE_ENTRY(entry), true);
301 +        gtk_entry_set_text(GTK_ENTRY(gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(entry))), str);
302 + #else
303 +        entry = gtk_entry_new();
304          gtk_entry_set_text(GTK_ENTRY(entry), str);
305 + #endif
306 +        gtk_widget_show(entry);
307          gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
308          return entry;
309   }
310  
311 + static const gchar *get_file_entry_path(GtkWidget *entry)
312 + {
313 + #ifdef HAVE_GNOMEUI
314 +        return gnome_file_entry_get_full_path(GNOME_FILE_ENTRY(entry), false);
315 + #else
316 +        return gtk_entry_get_text(GTK_ENTRY(entry));
317 + #endif
318 + }
319 +
320   static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func)
321   {
322          GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
# Line 181 | Line 327 | static GtkWidget *make_checkbox(GtkWidge
327          return button;
328   }
329  
330 + static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *prefs_item, const combo_desc *options)
331 + {
332 +        GtkWidget *box, *label, *combo;
333 +        char str[32];
334 +
335 +        box = gtk_hbox_new(FALSE, 4);
336 +        gtk_widget_show(box);
337 +        gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
338 +
339 +        label = gtk_label_new(GetString(label_id));
340 +        gtk_widget_show(label);
341 +        gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
342 +
343 +        GList *glist = NULL;
344 +        while (options->label_id) {
345 +                glist = g_list_append(glist, (void *)GetString(options->label_id));
346 +                options++;
347 +        }
348 +        
349 +        combo = gtk_combo_new();
350 +        gtk_widget_show(combo);
351 +        gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
352 +        
353 +        sprintf(str, "%d", PrefsFindInt32(prefs_item));
354 +        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
355 +        gtk_box_pack_start(GTK_BOX(box), combo, TRUE, TRUE, 0);
356 +        
357 +        return combo;
358 + }
359  
360 +
361   /*
362   *  Show preferences editor
363   *  Returns true when user clicked on "Start", false otherwise
# Line 224 | Line 400 | static void dl_quit(GtkWidget *dialog)
400   // "About" selected
401   static void mn_about(...)
402   {
403 <        GtkWidget *dialog, *label, *button;
403 >        GtkWidget *dialog;
404  
405 <        char str[256];
406 <        sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
407 <        strncat(str, "\n", 255);
408 <        strncat(str, GetString(STR_ABOUT_TEXT2), 255);
405 > #ifdef HAVE_GNOMEUI
406 >
407 >        char version[32];
408 >        sprintf(version, "Version %d.%d", VERSION_MAJOR, VERSION_MINOR);
409 >        const char *authors[] = {
410 >                "Christian Bauer",
411 >                "Orlando Bassotto",
412 >                "Gwenolé Beauchesne",
413 >                "Marc Chabanas",
414 >                "Marc Hellwig",
415 >                "Biill Huey",
416 >                "Brian J. Johnson",
417 >                "Jürgen Lachmann",
418 >                "Samuel Lander",
419 >                "David Lawrence",
420 >                "Lauri Pesonen",
421 >                "Bernd Schmidt",
422 >                "and others",
423 >                NULL
424 >        };
425 >        dialog = gnome_about_new(
426 >                "Basilisk II",
427 >                version,
428 >                "Copyright (C) 1997-2005 Christian Bauer",
429 >                authors,
430 >                "Basilisk II comes with ABSOLUTELY NO WARRANTY."
431 >                "This is free software, and you are welcome to redistribute it"
432 >                "under the terms of the GNU General Public License.",
433 >                NULL
434 >        );
435 >        gnome_dialog_set_parent(GNOME_DIALOG(dialog), GTK_WINDOW(win));
436 >
437 > #else
438 >
439 >        GtkWidget *label, *button;
440 >
441 >        char str[512];
442 >        sprintf(str,
443 >                "Basilisk II\nVersion %d.%d\n\n"
444 >                "Copyright (C) 1997-2005 Christian Bauer et al.\n"
445 >                "E-mail: Christian.Bauer@uni-mainz.de\n"
446 >                "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n"
447 >                "Basilisk II comes with ABSOLUTELY NO\n"
448 >                "WARRANTY. This is free software, and\n"
449 >                "you are welcome to redistribute it\n"
450 >                "under the terms of the GNU General\n"
451 >                "Public License.\n",
452 >                VERSION_MAJOR, VERSION_MINOR
453 >        );
454  
455          dialog = gtk_dialog_new();
235        gtk_widget_set_usize(GTK_WIDGET(dialog), strlen(GetString(STR_ABOUT_TEXT2)) + 200, 120);
456          gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE));
457          gtk_container_border_width(GTK_CONTAINER(dialog), 5);
458          gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
# Line 247 | Line 467 | static void mn_about(...)
467          gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
468          GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
469          gtk_widget_grab_default(button);
470 +
471 + #endif
472 +
473          gtk_widget_show(dialog);
474   }
475  
# Line 258 | Line 481 | static void mn_zap_pram(...)
481  
482   // Menu item descriptions
483   static GtkItemFactoryEntry menu_items[] = {
484 <        {GetString(STR_PREFS_MENU_FILE_GTK),            NULL,                   NULL,                                                   0, "<Branch>"},
485 <        {GetString(STR_PREFS_ITEM_START_GTK),           NULL,                   GTK_SIGNAL_FUNC(cb_start),              0, NULL},
486 <        {GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK),        NULL,                   GTK_SIGNAL_FUNC(mn_zap_pram),   0, NULL},
487 <        {GetString(STR_PREFS_ITEM_SEPL_GTK),            NULL,                   NULL,                                                   0, "<Separator>"},
488 <        {GetString(STR_PREFS_ITEM_QUIT_GTK),            "<control>Q",   GTK_SIGNAL_FUNC(cb_quit),               0, NULL},
489 <        {GetString(STR_HELP_MENU_GTK),                          NULL,                   NULL,                                                   0, "<LastBranch>"},
490 <        {GetString(STR_HELP_ITEM_ABOUT_GTK),            NULL,                   GTK_SIGNAL_FUNC(mn_about),              0, NULL}
484 >        {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK),           NULL,                   NULL,                                                   0, "<Branch>"},
485 >        {(gchar *)GetString(STR_PREFS_ITEM_START_GTK),          "<control>S",   GTK_SIGNAL_FUNC(cb_start),              0, NULL},
486 >        {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK),       NULL,                   GTK_SIGNAL_FUNC(mn_zap_pram),   0, NULL},
487 >        {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK),           NULL,                   NULL,                                                   0, "<Separator>"},
488 >        {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK),           "<control>Q",   GTK_SIGNAL_FUNC(cb_quit),               0, NULL},
489 >        {(gchar *)GetString(STR_HELP_MENU_GTK),                         NULL,                   NULL,                                                   0, "<LastBranch>"},
490 >        {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK),           NULL,                   GTK_SIGNAL_FUNC(mn_about),              0, NULL}
491   };
492  
493   bool PrefsEditor(void)
# Line 283 | Line 506 | bool PrefsEditor(void)
506          GtkAccelGroup *accel_group = gtk_accel_group_new();
507          GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
508          gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL);
509 + #if GTK_CHECK_VERSION(1,3,15)
510 +        gtk_window_add_accel_group(GTK_WINDOW(win), accel_group);
511 + #else
512          gtk_accel_group_attach(accel_group, GTK_OBJECT(win));
513 + #endif
514          GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "<main>");
515          gtk_widget_show(menu_bar);
516          gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);
# Line 291 | Line 518 | bool PrefsEditor(void)
518          GtkWidget *notebook = gtk_notebook_new();
519          gtk_widget_show(notebook);
520          gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
521 <        gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), TRUE);
521 >        gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE);
522          gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
523  
524          create_volumes_pane(notebook);
525          create_scsi_pane(notebook);
526          create_graphics_pane(notebook);
527 +        create_input_pane(notebook);
528          create_serial_pane(notebook);
529          create_memory_pane(notebook);
530 +        create_jit_pane(notebook);
531  
532          static const opt_desc buttons[] = {
533                  {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
# Line 318 | Line 547 | bool PrefsEditor(void)
547   *  "Volumes" pane
548   */
549  
550 < static GtkWidget *volume_list;
550 > static GtkWidget *volume_list, *w_extfs;
551   static int selected_volume;
552  
553   // Volume in list selected
# Line 327 | Line 556 | static void cl_selected(GtkWidget *list,
556          selected_volume = row;
557   }
558  
330 struct file_req_assoc {
331        file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
332        GtkWidget *req;
333        GtkWidget *entry;
334 };
335
559   // Volume selected for addition
560   static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
561   {
562 <        char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
562 >        gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
563          gtk_clist_append(GTK_CLIST(volume_list), &file);
564          gtk_widget_destroy(assoc->req);
565          delete assoc;
# Line 345 | Line 568 | static void add_volume_ok(GtkWidget *but
568   // Volume selected for creation
569   static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
570   {
571 <        char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
571 >        gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
572  
573 <        char *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
573 >        const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
574          int size = atoi(str);
575  
576          char cmd[1024];
# Line 400 | Line 623 | static void cb_remove_volume(...)
623   }
624  
625   // "Boot From" selected
626 < static void mn_boot_any(...) {PrefsReplaceInt16("bootdriver", 0);}
627 < static void mn_boot_cdrom(...) {PrefsReplaceInt16("bootdriver", CDROMRefNum);}
626 > static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);}
627 > static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);}
628  
629   // "No CD-ROM Driver" button toggled
630   static void tb_nocdrom(GtkWidget *widget)
# Line 420 | Line 643 | static void read_volumes_settings(void)
643                  gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str);
644                  PrefsAddString("disk", str);
645          }
646 +
647 +        PrefsReplaceString("extfs", get_file_entry_path(w_extfs));
648   }
649  
650   // Create "Volumes" pane
# Line 436 | Line 661 | static void create_volumes_pane(GtkWidge
661          gtk_widget_show(volume_list);
662          gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
663          gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
664 +        gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
665          gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
666          char *str;
667          int32 index = 0;
668 <        while ((str = (char *)PrefsFindString("disk", index++)) != NULL)
668 >        while ((str = const_cast<char *>(PrefsFindString("disk", index++))) != NULL)
669                  gtk_clist_append(GTK_CLIST(volume_list), &str);
670          gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list);
671          gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0);
# Line 454 | Line 680 | static void create_volumes_pane(GtkWidge
680          make_button_box(box, 0, buttons);
681          make_separator(box);
682  
683 +        w_extfs = make_file_entry(box, STR_EXTFS_CTRL, "extfs", true);
684 +
685          static const opt_desc options[] = {
686                  {STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)},
687                  {STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)},
688                  {0, NULL}
689          };
690 <        int bootdriver = PrefsFindInt16("bootdriver"), active = 0;
690 >        int bootdriver = PrefsFindInt32("bootdriver"), active = 0;
691          switch (bootdriver) {
692                  case 0: active = 0; break;
693                  case CDROMRefNum: active = 1; break;
# Line 471 | Line 699 | static void create_volumes_pane(GtkWidge
699  
700  
701   /*
702 + *  "JIT Compiler" pane
703 + */
704 +
705 + static GtkWidget *w_jit_fpu;
706 + static GtkWidget *w_jit_atraps;
707 + static GtkWidget *w_jit_cache_size;
708 + static GtkWidget *w_jit_lazy_flush;
709 + static GtkWidget *w_jit_follow_const_jumps;
710 +
711 + // Set sensitivity of widgets
712 + static void set_jit_sensitive(void)
713 + {
714 +        const bool jit_enabled = PrefsFindBool("jit");
715 +        gtk_widget_set_sensitive(w_jit_fpu, jit_enabled);
716 +        gtk_widget_set_sensitive(w_jit_cache_size, jit_enabled);
717 +        gtk_widget_set_sensitive(w_jit_lazy_flush, jit_enabled);
718 +        gtk_widget_set_sensitive(w_jit_follow_const_jumps, jit_enabled);
719 + }
720 +
721 + // "Use JIT Compiler" button toggled
722 + static void tb_jit(GtkWidget *widget)
723 + {
724 +        PrefsReplaceBool("jit", GTK_TOGGLE_BUTTON(widget)->active);
725 +        set_jit_sensitive();
726 + }
727 +
728 + // "Compile FPU Instructions" button toggled
729 + static void tb_jit_fpu(GtkWidget *widget)
730 + {
731 +        PrefsReplaceBool("jitfpu", GTK_TOGGLE_BUTTON(widget)->active);
732 + }
733 +
734 + // "Lazy translation cache invalidation" button toggled
735 + static void tb_jit_lazy_flush(GtkWidget *widget)
736 + {
737 +        PrefsReplaceBool("jitlazyflush", GTK_TOGGLE_BUTTON(widget)->active);
738 + }
739 +
740 + // "Translate through constant jumps (inline blocks)" button toggled
741 + static void tb_jit_follow_const_jumps(GtkWidget *widget)
742 + {
743 +        PrefsReplaceBool("jitinline", GTK_TOGGLE_BUTTON(widget)->active);
744 + }
745 +
746 + // Read settings from widgets and set preferences
747 + static void read_jit_settings(void)
748 + {
749 + #if USE_JIT
750 +        bool jit_enabled = PrefsFindBool("jit");
751 +        if (jit_enabled) {
752 +                const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry));
753 +                PrefsReplaceInt32("jitcachesize", atoi(str));
754 +        }
755 + #endif
756 + }
757 +
758 + // Create "JIT Compiler" pane
759 + static void create_jit_pane(GtkWidget *top)
760 + {
761 + #if USE_JIT
762 +        GtkWidget *box, *table, *label, *menu;
763 +        char str[32];
764 +        
765 +        box = make_pane(top, STR_JIT_PANE_TITLE);
766 +        make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit));
767 +        
768 +        w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", GTK_SIGNAL_FUNC(tb_jit_fpu));
769 +        
770 +        // Translation cache size
771 +        static const combo_desc options[] = {
772 +                STR_JIT_CACHE_SIZE_2MB_LAB,
773 +                STR_JIT_CACHE_SIZE_4MB_LAB,
774 +                STR_JIT_CACHE_SIZE_8MB_LAB,
775 +                STR_JIT_CACHE_SIZE_16MB_LAB,
776 +                0
777 +        };
778 +        w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, "jitcachesize", options);
779 +        
780 +        // Lazy translation cache invalidation
781 +        w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", GTK_SIGNAL_FUNC(tb_jit_lazy_flush));
782 +
783 +        // Follow constant jumps (inline basic blocks)
784 +        w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps));
785 +
786 +        set_jit_sensitive();
787 + #endif
788 + }
789 +
790 + /*
791   *  "SCSI" pane
792   */
793  
# Line 482 | Line 799 | static void read_scsi_settings(void)
799          for (int id=0; id<7; id++) {
800                  char prefs_name[32];
801                  sprintf(prefs_name, "scsi%d", id);
802 <                const char *str = gtk_entry_get_text(GTK_ENTRY(w_scsi[id]));
802 >                const char *str = get_file_entry_path(w_scsi[id]);
803                  if (str && strlen(str))
804                          PrefsReplaceString(prefs_name, str);
805                  else
# Line 500 | Line 817 | static void create_scsi_pane(GtkWidget *
817          for (int id=0; id<7; id++) {
818                  char prefs_name[32];
819                  sprintf(prefs_name, "scsi%d", id);
820 <                w_scsi[id] = make_entry(box, STR_SCSI_ID_0 + id, prefs_name);
820 >                w_scsi[id] = make_file_entry(box, STR_SCSI_ID_0 + id, prefs_name);
821          }
822   }
823  
# Line 520 | Line 837 | static GtkWidget *l_frameskip, *l_displa
837   static int display_type;
838   static int dis_width, dis_height;
839  
840 + #ifdef ENABLE_FBDEV_DGA
841 + static GtkWidget *w_fbdev_name, *w_fbdevice_file;
842 + static GtkWidget *l_fbdev_name, *l_fbdevice_file;
843 + static char fbdev_name[256];
844 + #endif
845 +
846 + static GtkWidget *w_dspdevice_file, *w_mixerdevice_file;
847 +
848   // Hide/show graphics widgets
849   static void hide_show_graphics_widgets(void)
850   {
851          switch (display_type) {
852                  case DISPLAY_WINDOW:
853                          gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip);
854 + #ifdef ENABLE_FBDEV_DGA
855                          gtk_widget_show(w_display_x); gtk_widget_show(l_display_x);
856                          gtk_widget_show(w_display_y); gtk_widget_show(l_display_y);
857 +                        gtk_widget_hide(w_fbdev_name); gtk_widget_hide(l_fbdev_name);
858 + #endif
859                          break;
860                  case DISPLAY_SCREEN:
861                          gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip);
862 + #ifdef ENABLE_FBDEV_DGA
863                          gtk_widget_hide(w_display_x); gtk_widget_hide(l_display_x);
864                          gtk_widget_hide(w_display_y); gtk_widget_hide(l_display_y);
865 +                        gtk_widget_show(w_fbdev_name); gtk_widget_show(l_fbdev_name);
866 + #endif
867                          break;
868          }
869   }
# Line 558 | Line 889 | static void mn_10hz(...) {PrefsReplaceIn
889   static void mn_15hz(...) {PrefsReplaceInt32("frameskip", 4);}
890   static void mn_30hz(...) {PrefsReplaceInt32("frameskip", 2);}
891   static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);}
892 + static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);}
893 +
894 + // Set sensitivity of widgets
895 + static void set_graphics_sensitive(void)
896 + {
897 +        const bool sound_enabled = !PrefsFindBool("nosound");
898 +        gtk_widget_set_sensitive(w_dspdevice_file, sound_enabled);
899 +        gtk_widget_set_sensitive(w_mixerdevice_file, sound_enabled);
900 + }
901  
902   // "Disable Sound Output" button toggled
903   static void tb_nosound(GtkWidget *widget)
904   {
905          PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active);
906 +        set_graphics_sensitive();
907   }
908  
909   // Read graphics preferences
# Line 571 | Line 912 | static void parse_graphics_prefs(void)
912          display_type = DISPLAY_WINDOW;
913          dis_width = 512;
914          dis_height = 384;
915 + #ifdef ENABLE_FBDEV_DGA
916 +        fbdev_name[0] = 0;
917 + #endif
918  
919          const char *str = PrefsFindString("screen");
920          if (str) {
921                  if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2)
922                          display_type = DISPLAY_WINDOW;
923 <                else if (strcmp(str, "dga") == 0)
923 > #ifdef ENABLE_FBDEV_DGA
924 >                else if (sscanf(str, "dga/%255s", fbdev_name) == 1)
925 > #else
926 >                else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2)
927 > #endif
928                          display_type = DISPLAY_SCREEN;
929          }
930   }
# Line 598 | Line 946 | static void read_graphics_settings(void)
946                          sprintf(pref, "win/%d/%d", dis_width, dis_height);
947                          break;
948                  case DISPLAY_SCREEN:
949 <                        strcpy(pref, "dga");
949 > #ifdef ENABLE_FBDEV_DGA
950 >                        str = gtk_entry_get_text(GTK_ENTRY(w_fbdev_name));
951 >                        sprintf(pref, "dga/%s", str);
952 > #else
953 >                        sprintf(pref, "dga/%d/%d", dis_width, dis_height);
954 > #endif
955                          break;
956                  default:
957                          PrefsRemoveItem("screen");
958                          return;
959          }
960          PrefsReplaceString("screen", pref);
961 +
962 + #ifdef ENABLE_FBDEV_DGA
963 +        str = get_file_entry_path(w_fbdevice_file);
964 +        if (str && strlen(str))
965 +                PrefsReplaceString("fbdevicefile", str);
966 +        else
967 +                PrefsRemoveItem("fbdevicefile");
968 + #endif
969 +        PrefsReplaceString("dsp", get_file_entry_path(w_dspdevice_file));
970 +        PrefsReplaceString("mixer", get_file_entry_path(w_mixerdevice_file));
971   }
972  
973   // Create "Graphics/Sound" pane
974   static void create_graphics_pane(GtkWidget *top)
975   {
976 <        GtkWidget *box, *table, *label, *opt, *menu;
976 >        GtkWidget *box, *table, *label, *opt, *menu, *combo;
977          char str[32];
978  
979          parse_graphics_prefs();
980  
981          box = make_pane(top, STR_GRAPHICS_SOUND_PANE_TITLE);
982 <        table = make_table(box, 2, 4);
982 >        table = make_table(box, 2, 5);
983  
984          label = gtk_label_new(GetString(STR_VIDEO_TYPE_CTRL));
985          gtk_widget_show(label);
# Line 651 | Line 1014 | static void create_graphics_pane(GtkWidg
1014          add_menu_item(menu, STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz));
1015          add_menu_item(menu, STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz));
1016          add_menu_item(menu, STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz));
1017 +        add_menu_item(menu, STR_REF_DYNAMIC_LAB, GTK_SIGNAL_FUNC(mn_dynamic));
1018          int frameskip = PrefsFindInt32("frameskip");
1019 +        int item = -1;
1020          switch (frameskip) {
1021 <                case 12:
1022 <                        gtk_menu_set_active(GTK_MENU(menu), 0);
1023 <                        break;
1024 <                case 8:
1025 <                        gtk_menu_set_active(GTK_MENU(menu), 1);
1026 <                        break;
1027 <                case 6:
663 <                        gtk_menu_set_active(GTK_MENU(menu), 2);
664 <                        break;
665 <                case 4:
666 <                        gtk_menu_set_active(GTK_MENU(menu), 3);
667 <                        break;
668 <                case 2:
669 <                        gtk_menu_set_active(GTK_MENU(menu), 4);
670 <                        break;
671 <                case 1:
672 <                        gtk_menu_set_active(GTK_MENU(menu), 5);
673 <                        break;
1021 >                case 12: item = 0; break;
1022 >                case 8: item = 1; break;
1023 >                case 6: item = 2; break;
1024 >                case 4: item = 3; break;
1025 >                case 2: item = 4; break;
1026 >                case 1: item = 5; break;
1027 >                case 0: item = 6; break;
1028          }
1029 +        if (item >= 0)
1030 +                gtk_menu_set_active(GTK_MENU(menu), item);
1031          gtk_option_menu_set_menu(GTK_OPTION_MENU(w_frameskip), menu);
1032          gtk_table_attach(GTK_TABLE(table), w_frameskip, 1, 2, 1, 2, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1033  
# Line 679 | Line 1035 | static void create_graphics_pane(GtkWidg
1035          gtk_widget_show(l_display_x);
1036          gtk_table_attach(GTK_TABLE(table), l_display_x, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1037  
1038 <        w_display_x = gtk_entry_new();
1039 <        gtk_widget_show(w_display_x);
1040 <        sprintf(str, "%d", dis_width);
1041 <        gtk_entry_set_text(GTK_ENTRY(w_display_x), str);
1042 <        gtk_table_attach(GTK_TABLE(table), w_display_x, 1, 2, 2, 3, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1038 >        combo = gtk_combo_new();
1039 >        gtk_widget_show(combo);
1040 >        GList *glist1 = NULL;
1041 >        glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_512_LAB));
1042 >        glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_640_LAB));
1043 >        glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_800_LAB));
1044 >        glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_1024_LAB));
1045 >        glist1 = g_list_append(glist1, (void *)GetString(STR_SIZE_MAX_LAB));
1046 >        gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist1);
1047 >        if (dis_width)
1048 >                sprintf(str, "%d", dis_width);
1049 >        else
1050 >                strcpy(str, GetString(STR_SIZE_MAX_LAB));
1051 >        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1052 >        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1053 >        w_display_x = GTK_COMBO(combo)->entry;
1054  
1055          l_display_y = gtk_label_new(GetString(STR_DISPLAY_Y_CTRL));
1056          gtk_widget_show(l_display_y);
1057          gtk_table_attach(GTK_TABLE(table), l_display_y, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1058  
1059 <        w_display_y = gtk_entry_new();
1060 <        gtk_widget_show(w_display_y);
1061 <        sprintf(str, "%d", dis_height);
1062 <        gtk_entry_set_text(GTK_ENTRY(w_display_y), str);
1063 <        gtk_table_attach(GTK_TABLE(table), w_display_y, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1059 >        combo = gtk_combo_new();
1060 >        gtk_widget_show(combo);
1061 >        GList *glist2 = NULL;
1062 >        glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_384_LAB));
1063 >        glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_480_LAB));
1064 >        glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_600_LAB));
1065 >        glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_768_LAB));
1066 >        glist2 = g_list_append(glist2, (void *)GetString(STR_SIZE_MAX_LAB));
1067 >        gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist2);
1068 >        if (dis_height)
1069 >                sprintf(str, "%d", dis_height);
1070 >        else
1071 >                strcpy(str, GetString(STR_SIZE_MAX_LAB));
1072 >        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1073 >        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1074 >        w_display_y = GTK_COMBO(combo)->entry;
1075 >
1076 > #ifdef ENABLE_FBDEV_DGA
1077 >        l_fbdev_name = gtk_label_new(GetString(STR_FBDEV_NAME_CTRL));
1078 >        gtk_widget_show(l_fbdev_name);
1079 >        gtk_table_attach(GTK_TABLE(table), l_fbdev_name, 0, 1, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1080 >
1081 >        w_fbdev_name = gtk_entry_new();
1082 >        gtk_widget_show(w_fbdev_name);
1083 >        gtk_entry_set_text(GTK_ENTRY(w_fbdev_name), fbdev_name);
1084 >        gtk_table_attach(GTK_TABLE(table), w_fbdev_name, 1, 2, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1085 >
1086 >        w_fbdevice_file = make_file_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile");
1087 > #endif
1088  
1089 +        make_separator(box);
1090          make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
1091 +        w_dspdevice_file = make_file_entry(box, STR_DSPDEVICE_FILE_CTRL, "dsp");
1092 +        w_mixerdevice_file = make_file_entry(box, STR_MIXERDEVICE_FILE_CTRL, "mixer");
1093 +
1094 +        set_graphics_sensitive();
1095  
1096          hide_show_graphics_widgets();
1097   }
1098  
1099  
1100   /*
1101 + *  "Input" pane
1102 + */
1103 +
1104 + static GtkWidget *w_keycode_file;
1105 + static GtkWidget *w_mouse_wheel_lines;
1106 +
1107 + // Set sensitivity of widgets
1108 + static void set_input_sensitive(void)
1109 + {
1110 +        const bool use_keycodes = PrefsFindBool("keycodes");
1111 +        gtk_widget_set_sensitive(w_keycode_file, use_keycodes);
1112 +        gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_keycode_file), "chooser_button")), use_keycodes);
1113 +        gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1);
1114 + }
1115 +
1116 + // "Use Raw Keycodes" button toggled
1117 + static void tb_keycodes(GtkWidget *widget)
1118 + {
1119 +        PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active);
1120 +        set_input_sensitive();
1121 + }
1122 +
1123 + // "Mouse Wheel Mode" selected
1124 + static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();}
1125 + static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();}
1126 +
1127 + // Read settings from widgets and set preferences
1128 + static void read_input_settings(void)
1129 + {
1130 +        const char *str = get_file_entry_path(w_keycode_file);
1131 +        if (str && strlen(str))
1132 +                PrefsReplaceString("keycodefile", str);
1133 +        else
1134 +                PrefsRemoveItem("keycodefile");
1135 +
1136 +        PrefsReplaceInt32("mousewheellines", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_mouse_wheel_lines)));
1137 + }
1138 +
1139 + // Create "Input" pane
1140 + static void create_input_pane(GtkWidget *top)
1141 + {
1142 +        GtkWidget *box, *hbox, *menu, *label, *button;
1143 +        GtkObject *adj;
1144 +
1145 +        box = make_pane(top, STR_INPUT_PANE_TITLE);
1146 +
1147 +        make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
1148 +
1149 +        hbox = gtk_hbox_new(FALSE, 4);
1150 +        gtk_widget_show(hbox);
1151 +        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1152 +
1153 +        label = gtk_label_new(GetString(STR_KEYCODES_CTRL));
1154 +        gtk_widget_show(label);
1155 +        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1156 +
1157 +        const char *str = PrefsFindString("keycodefile");
1158 +        if (str == NULL)
1159 +                str = "";
1160 +
1161 +        w_keycode_file = gtk_entry_new();
1162 +        gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
1163 +        gtk_widget_show(w_keycode_file);
1164 +        gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0);
1165 +
1166 +        button = make_browse_button(w_keycode_file);
1167 +        gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1168 +        g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button);
1169 +
1170 +        make_separator(box);
1171 +
1172 +        static const opt_desc options[] = {
1173 +                {STR_MOUSEWHEELMODE_PAGE_LAB, GTK_SIGNAL_FUNC(mn_wheel_page)},
1174 +                {STR_MOUSEWHEELMODE_CURSOR_LAB, GTK_SIGNAL_FUNC(mn_wheel_cursor)},
1175 +                {0, NULL}
1176 +        };
1177 +        int wheelmode = PrefsFindInt32("mousewheelmode"), active = 0;
1178 +        switch (wheelmode) {
1179 +                case 0: active = 0; break;
1180 +                case 1: active = 1; break;
1181 +        }
1182 +        menu = make_option_menu(box, STR_MOUSEWHEELMODE_CTRL, options, active);
1183 +
1184 +        hbox = gtk_hbox_new(FALSE, 4);
1185 +        gtk_widget_show(hbox);
1186 +        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1187 +
1188 +        label = gtk_label_new(GetString(STR_MOUSEWHEELLINES_CTRL));
1189 +        gtk_widget_show(label);
1190 +        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1191 +
1192 +        adj = gtk_adjustment_new(PrefsFindInt32("mousewheellines"), 1, 1000, 1, 5, 0);
1193 +        w_mouse_wheel_lines = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0);
1194 +        gtk_widget_show(w_mouse_wheel_lines);
1195 +        gtk_box_pack_start(GTK_BOX(hbox), w_mouse_wheel_lines, FALSE, FALSE, 0);
1196 +
1197 +        set_input_sensitive();
1198 + }
1199 +
1200 +
1201 + /*
1202   *  "Serial/Network" pane
1203   */
1204  
1205 < static GtkWidget *w_seriala, *w_serialb, *w_ether;
1205 > static GtkWidget *w_seriala, *w_serialb, *w_ether, *w_udp_port;
1206 >
1207 > // Set sensitivity of widgets
1208 > static void set_serial_sensitive(void)
1209 > {
1210 > #if SUPPORTS_UDP_TUNNEL
1211 >        gtk_widget_set_sensitive(w_ether, !PrefsFindBool("udptunnel"));
1212 >        gtk_widget_set_sensitive(w_udp_port, PrefsFindBool("udptunnel"));
1213 > #endif
1214 > }
1215 >
1216 > // "Tunnel AppleTalk over IP" button toggled
1217 > static void tb_udptunnel(GtkWidget *widget)
1218 > {
1219 >        PrefsReplaceBool("udptunnel", GTK_TOGGLE_BUTTON(widget)->active);
1220 >        set_serial_sensitive();
1221 > }
1222  
1223   // Read settings from widgets and set preferences
1224   static void read_serial_settings(void)
# Line 723 | Line 1236 | static void read_serial_settings(void)
1236                  PrefsReplaceString("ether", str);
1237          else
1238                  PrefsRemoveItem("ether");
1239 +
1240 + #if SUPPORTS_UDP_TUNNEL
1241 +        PrefsReplaceInt32("udpport", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w_udp_port)));
1242 + #endif
1243   }
1244  
1245   // Add names of serial devices
# Line 744 | Line 1261 | static GList *add_serial_names(void)
1261                          if (strncmp(de->d_name, "ttyS", 4) == 0 || strncmp(de->d_name, "lp", 2) == 0) {
1262   #elif defined(__FreeBSD__)
1263                          if (strncmp(de->d_name, "cuaa", 4) == 0 || strncmp(de->d_name, "lpt", 3) == 0) {
1264 + #elif defined(__NetBSD__)
1265 +                        if (strncmp(de->d_name, "tty0", 4) == 0 || strncmp(de->d_name, "lpt", 3) == 0) {
1266   #elif defined(sgi)
1267                          if (strncmp(de->d_name, "ttyf", 4) == 0 || strncmp(de->d_name, "plp", 3) == 0) {
1268   #else
# Line 759 | Line 1278 | static GList *add_serial_names(void)
1278          if (glist)
1279                  g_list_sort(glist, gl_str_cmp);
1280          else
1281 <                glist = g_list_append(glist, "<none>");
1281 >                glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB));
1282          return glist;
1283   }
1284  
# Line 779 | Line 1298 | static GList *add_ether_names(void)
1298                          struct ifreq req, *ifr = ifc.ifc_req;
1299                          for (int i=0; i<ifc.ifc_len; i+=sizeof(ifreq), ifr++) {
1300                                  req = *ifr;
1301 < #if defined(__FreeBSD__) || defined(sgi)
1301 > #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(sgi)
1302                                  if (ioctl(s, SIOCGIFADDR, &req) == 0 && (req.ifr_addr.sa_family == ARPHRD_ETHER || req.ifr_addr.sa_family == ARPHRD_ETHER+1)) {
1303 < #else
1303 > #elif defined(__linux__)
1304                                  if (ioctl(s, SIOCGIFHWADDR, &req) == 0 && req.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
1305 + #else
1306 +                                if (false) {
1307   #endif
1308                                          char *str = new char[64];
1309                                          strncpy(str, ifr->ifr_name, 63);
# Line 792 | Line 1313 | static GList *add_ether_names(void)
1313                  }
1314                  close(s);
1315          }
1316 + #ifdef HAVE_SLIRP
1317 +        static char s_slirp[] = "slirp";
1318 +        glist = g_list_append(glist, s_slirp);
1319 + #endif
1320          if (glist)
1321                  g_list_sort(glist, gl_str_cmp);
1322          else
1323 <                glist = g_list_append(glist, "<none>");
1323 >                glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB));
1324          return glist;
1325   }
1326  
1327   // Create "Serial/Network" pane
1328   static void create_serial_pane(GtkWidget *top)
1329   {
1330 <        GtkWidget *box, *table, *label, *combo;
1331 <        GList *glist = add_serial_names();
1330 >        GtkWidget *box, *hbox, *table, *label, *combo, *sep;
1331 >        GtkObject *adj;
1332  
1333          box = make_pane(top, STR_SERIAL_NETWORK_PANE_TITLE);
1334 <        table = make_table(box, 2, 3);
1334 >        table = make_table(box, 2, 4);
1335  
1336          label = gtk_label_new(GetString(STR_SERIALA_CTRL));
1337          gtk_widget_show(label);
1338          gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1339  
1340 +        GList *glist = add_serial_names();
1341          combo = gtk_combo_new();
1342          gtk_widget_show(combo);
1343          gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
# Line 836 | Line 1362 | static void create_serial_pane(GtkWidget
1362          gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1363          w_serialb = GTK_COMBO(combo)->entry;
1364  
1365 +        sep = gtk_hseparator_new();
1366 +        gtk_widget_show(sep);
1367 +        gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1368 +
1369          label = gtk_label_new(GetString(STR_ETHERNET_IF_CTRL));
1370          gtk_widget_show(label);
1371 <        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1371 >        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1372  
1373          glist = add_ether_names();
1374          combo = gtk_combo_new();
# Line 848 | Line 1378 | static void create_serial_pane(GtkWidget
1378          if (str == NULL)
1379                  str = "";
1380          gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1381 <        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1381 >        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1382          w_ether = GTK_COMBO(combo)->entry;
1383 +
1384 + #if SUPPORTS_UDP_TUNNEL
1385 +        make_checkbox(box, STR_UDPTUNNEL_CTRL, "udptunnel", GTK_SIGNAL_FUNC(tb_udptunnel));
1386 +
1387 +        hbox = gtk_hbox_new(FALSE, 4);
1388 +        gtk_widget_show(hbox);
1389 +        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1390 +
1391 +        label = gtk_label_new(GetString(STR_UDPPORT_CTRL));
1392 +        gtk_widget_show(label);
1393 +        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1394 +
1395 +        adj = gtk_adjustment_new(PrefsFindInt32("udpport"), 1, 65535, 1, 5, 0);
1396 +        w_udp_port = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.0, 0);
1397 +        gtk_widget_show(w_udp_port);
1398 +        gtk_box_pack_start(GTK_BOX(hbox), w_udp_port, FALSE, FALSE, 0);
1399 + #endif
1400 +
1401 +        set_serial_sensitive();
1402   }
1403  
1404  
# Line 857 | Line 1406 | static void create_serial_pane(GtkWidget
1406   *  "Memory/Misc" pane
1407   */
1408  
1409 < static GtkObject *w_ramsize_adj;
1409 > static GtkWidget *w_ramsize;
1410   static GtkWidget *w_rom_file;
1411 < static GtkWidget *w_keycode_file;
1411 >
1412 > // "Ignore SEGV" button toggled
1413 > #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1414 > static void tb_ignoresegv(GtkWidget *widget)
1415 > {
1416 >        PrefsReplaceBool("ignoresegv", GTK_TOGGLE_BUTTON(widget)->active);
1417 > }
1418 > #endif
1419  
1420   // Model ID selected
1421   static void mn_modelid_5(...) {PrefsReplaceInt32("modelid", 5);}
1422   static void mn_modelid_14(...) {PrefsReplaceInt32("modelid", 14);}
1423  
1424 < // "Use Raw Keycodes" button toggled
1425 < static void tb_keycodes(GtkWidget *widget)
1426 < {
1427 <        PrefsReplaceBool("keycodes", GTK_TOGGLE_BUTTON(widget)->active);
1428 < }
1424 > // CPU/FPU type
1425 > static void mn_cpu_68020(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", false);}
1426 > static void mn_cpu_68020_fpu(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", true);}
1427 > static void mn_cpu_68030(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", false);}
1428 > static void mn_cpu_68030_fpu(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", true);}
1429 > static void mn_cpu_68040(...) {PrefsReplaceInt32("cpu", 4); PrefsReplaceBool("fpu", true);}
1430  
1431   // Read settings from widgets and set preferences
1432   static void read_memory_settings(void)
1433   {
1434 <        PrefsReplaceInt32("ramsize", int(GTK_ADJUSTMENT(w_ramsize_adj)->value) << 20);
1434 >        const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_ramsize)->entry));
1435 >        PrefsReplaceInt32("ramsize", atoi(str) << 20);
1436  
1437 <        const char *str = gtk_entry_get_text(GTK_ENTRY(w_rom_file));
1437 >        str = get_file_entry_path(w_rom_file);
1438          if (str && strlen(str))
1439                  PrefsReplaceString("rom", str);
1440          else
1441                  PrefsRemoveItem("rom");
1442  
885        str = gtk_entry_get_text(GTK_ENTRY(w_keycode_file));
886        if (str && strlen(str))
887                PrefsReplaceString("keycodefile", str);
888        else
889                PrefsRemoveItem("keycodefile");
1443   }
1444  
1445   // Create "Memory/Misc" pane
1446   static void create_memory_pane(GtkWidget *top)
1447   {
1448 <        GtkWidget *box, *vbox, *hbox, *hbox2, *label, *scale, *opt, *menu;
1448 >        GtkWidget *box, *hbox, *table, *label, *menu;
1449  
1450          box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE);
1451 +        table = make_table(box, 2, 5);
1452  
1453 <        hbox = gtk_hbox_new(FALSE, 4);
1454 <        gtk_widget_show(hbox);
1455 <
1456 <        label = gtk_label_new(GetString(STR_RAMSIZE_SLIDER));
1457 <        gtk_widget_show(label);
1458 <        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1459 <
1460 <        vbox = gtk_vbox_new(FALSE, 4);
1461 <        gtk_widget_show(vbox);
1462 <
1463 <        gfloat min, max;
1464 <        min = 1;
1465 <        max = 1024;
1466 <        w_ramsize_adj = gtk_adjustment_new(min, min, max, 1, 16, 0);
1467 <        gtk_adjustment_set_value(GTK_ADJUSTMENT(w_ramsize_adj), PrefsFindInt32("ramsize") >> 20);
1468 <
915 <        scale = gtk_hscale_new(GTK_ADJUSTMENT(w_ramsize_adj));
916 <        gtk_widget_show(scale);
917 <        gtk_scale_set_digits(GTK_SCALE(scale), 0);
918 <        gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0);
919 <
920 <        hbox2 = gtk_hbox_new(FALSE, 4);
921 <        gtk_widget_show(hbox2);
922 <
923 <        char val[32];
924 <        sprintf(val, GetString(STR_RAMSIZE_FMT), int(min));
925 <        label = gtk_label_new(val);
926 <        gtk_widget_show(label);
927 <        gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
928 <
929 <        sprintf(val, GetString(STR_RAMSIZE_FMT), int(max));
930 <        label = gtk_label_new(val);
931 <        gtk_widget_show(label);
932 <        gtk_box_pack_end(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
933 <        gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, TRUE, 0);
934 <        gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
935 <        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1453 >        static const combo_desc options[] = {
1454 >                STR_RAMSIZE_2MB_LAB,
1455 >                STR_RAMSIZE_4MB_LAB,
1456 >                STR_RAMSIZE_8MB_LAB,
1457 >                STR_RAMSIZE_16MB_LAB,
1458 >                STR_RAMSIZE_32MB_LAB,
1459 >                STR_RAMSIZE_64MB_LAB,
1460 >                STR_RAMSIZE_128MB_LAB,
1461 >                STR_RAMSIZE_256MB_LAB,
1462 >                STR_RAMSIZE_512MB_LAB,
1463 >                STR_RAMSIZE_1024MB_LAB,
1464 >                0
1465 >        };
1466 >        char default_ramsize[10];
1467 >        sprintf(default_ramsize, "%d", PrefsFindInt32("ramsize") >> 20);
1468 >        w_ramsize = table_make_combobox(table, 0, STR_RAMSIZE_CTRL, default_ramsize, options);
1469  
1470 <        static const opt_desc options[] = {
1470 >        static const opt_desc model_options[] = {
1471                  {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)},
1472                  {STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)},
1473                  {0, NULL}
# Line 944 | Line 1477 | static void create_memory_pane(GtkWidget
1477                  case 5: active = 0; break;
1478                  case 14: active = 1; break;
1479          }
1480 <        menu = make_option_menu(box, STR_MODELID_CTRL, options, active);
1480 >        table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active);
1481 >
1482 > #if EMULATED_68K
1483 >        static const opt_desc cpu_options[] = {
1484 >                {STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)},
1485 >                {STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)},
1486 >                {STR_CPU_68030_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030)},
1487 >                {STR_CPU_68030_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030_fpu)},
1488 >                {STR_CPU_68040_LAB, GTK_SIGNAL_FUNC(mn_cpu_68040)},
1489 >                {0, NULL}
1490 >        };
1491 >        int cpu = PrefsFindInt32("cpu");
1492 >        bool fpu = PrefsFindBool("fpu");
1493 >        active = 0;
1494 >        switch (cpu) {
1495 >                case 2: active = fpu ? 1 : 0; break;
1496 >                case 3: active = fpu ? 3 : 2; break;
1497 >                case 4: active = 4;
1498 >        }
1499 >        table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active);
1500 > #endif
1501  
1502 <        w_rom_file = make_entry(box, STR_ROM_FILE_CTRL, "rom");
1502 >        w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom");
1503  
1504 <        make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
1505 <        w_keycode_file = make_entry(box, STR_KEYCODE_FILE_CTRL, "keycodefile");
1504 > #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1505 >        make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
1506 > #endif
1507   }
1508  
1509  
# Line 962 | Line 1516 | static void read_settings(void)
1516          read_volumes_settings();
1517          read_scsi_settings();
1518          read_graphics_settings();
1519 +        read_input_settings();
1520          read_serial_settings();
1521          read_memory_settings();
1522 +        read_jit_settings();
1523 + }
1524 +
1525 +
1526 + #ifdef STANDALONE_GUI
1527 + #include <errno.h>
1528 +
1529 + /*
1530 + *  Fake unused data and functions
1531 + */
1532 +
1533 + uint8 XPRAM[XPRAM_SIZE];
1534 + void MountVolume(void *fh) { }
1535 + void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
1536 + void WarningAlert(const char *text) { }
1537 +
1538 +
1539 + /*
1540 + *  Display alert
1541 + */
1542 +
1543 + static void dl_destroyed(void)
1544 + {
1545 +        gtk_main_quit();
1546 + }
1547 +
1548 + static void display_alert(int title_id, int prefix_id, int button_id, const char *text)
1549 + {
1550 +        char str[256];
1551 +        sprintf(str, GetString(prefix_id), text);
1552 +
1553 +        GtkWidget *dialog = gtk_dialog_new();
1554 +        gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id));
1555 +        gtk_container_border_width(GTK_CONTAINER(dialog), 5);
1556 +        gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
1557 +        gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL);
1558 +
1559 +        GtkWidget *label = gtk_label_new(str);
1560 +        gtk_widget_show(label);
1561 +        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
1562 +
1563 +        GtkWidget *button = gtk_button_new_with_label(GetString(button_id));
1564 +        gtk_widget_show(button);
1565 +        gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
1566 +        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
1567 +        GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
1568 +        gtk_widget_grab_default(button);
1569 +        gtk_widget_show(dialog);
1570 +
1571 +        gtk_main();
1572 + }
1573 +
1574 +
1575 + /*
1576 + *  Display error alert
1577 + */
1578 +
1579 + static void ErrorAlert(const char *text)
1580 + {
1581 +        display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text);
1582 + }
1583 +
1584 +
1585 + /*
1586 + *  Start standalone GUI
1587 + */
1588 +
1589 + int main(int argc, char *argv[])
1590 + {
1591 + #ifdef HAVE_GNOMEUI
1592 +        // Init GNOME/GTK
1593 +        char version[16];
1594 +        sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR);
1595 +        gnome_init("Basilisk II", version, argc, argv);
1596 + #else
1597 +        // Init GTK
1598 +        gtk_set_locale();
1599 +        gtk_init(&argc, &argv);
1600 + #endif
1601 +
1602 +        // Read preferences
1603 +        PrefsInit(argc, argv);
1604 +
1605 +        // Show preferences editor
1606 +        bool start = PrefsEditor();
1607 +
1608 +        // Exit preferences
1609 +        PrefsExit();
1610 +
1611 +        // Transfer control to the executable
1612 +        if (start) {
1613 +                char b2_path[PATH_MAX];
1614 +                strcpy(b2_path, argv[0]);
1615 +                char *p = strrchr(b2_path, '/');
1616 +                p = p ? p + 1 : b2_path;
1617 +                *p = '\0';
1618 +                strcat(b2_path, "BasiliskII");
1619 +                argv[0] = b2_path;
1620 +                execv(b2_path, argv);
1621 +
1622 +                char str[256];
1623 +                sprintf(str, GetString(STR_NO_B2_EXE_FOUND), b2_path, strerror(errno));
1624 +                ErrorAlert(str);
1625 +                return 1;
1626 +        }
1627 +
1628 +        return 0;
1629   }
1630 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines