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

Comparing BasiliskII/src/Windows/prefs_editor_gtk.cpp (file contents):
Revision 1.1 by gbeauche, 2005-06-20T08:40:34Z vs.
Revision 1.10 by gbeauche, 2005-11-29T22:59:44Z

# Line 20 | Line 20
20  
21   #include "sysdeps.h"
22  
23 #include <gtk/gtk.h>
23   #include <stdlib.h>
24 + #include <string.h>
25 + #include <fcntl.h>
26 + #include <sys/stat.h>
27 + #include <gtk/gtk.h>
28  
29   #include "user_strings.h"
30   #include "version.h"
# Line 29 | Line 32
32   #include "xpram.h"
33   #include "prefs.h"
34   #include "prefs_editor.h"
35 + #include "b2ether/inc/b2ether_hl.h"
36  
37  
38   // Global variables
# Line 49 | Line 53 | static void read_settings(void);
53  
54  
55   /*
56 + *  SheepShaver glue
57 + */
58 +
59 + #ifdef SHEEPSHAVER
60 + #define DISABLE_SCSI 1
61 + #define PROGRAM_NAME "SheepShaver"
62 + enum {
63 +        STR_WINDOW_LAB = STR_WINDOW_CTRL,
64 +        STR_FULLSCREEN_LAB = STR_FULLSCREEN_CTRL,
65 +        STR_SERIALA_CTRL = STR_SERPORTA_CTRL,
66 +        STR_SERIALB_CTRL = STR_SERPORTB_CTRL,
67 + };
68 + #else
69 + #define PROGRAM_NAME "BasiliskII"
70 + #endif
71 +
72 +
73 + /*
74   *  Utility functions
75   */
76  
# Line 157 | Line 179 | static GtkWidget *make_table(GtkWidget *
179          return table;
180   }
181  
182 + static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active)
183 + {
184 +        GtkWidget *label, *opt, *menu;
185 +
186 +        label = gtk_label_new(GetString(label_id));
187 +        gtk_widget_show(label);
188 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
189 +
190 +        opt = gtk_option_menu_new();
191 +        gtk_widget_show(opt);
192 +        menu = gtk_menu_new();
193 +
194 +        while (options->label_id) {
195 +                add_menu_item(menu, options->label_id, options->func);
196 +                options++;
197 +        }
198 +        gtk_menu_set_active(GTK_MENU(menu), active);
199 +
200 +        gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
201 +        gtk_table_attach(GTK_TABLE(table), opt, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
202 +        return menu;
203 + }
204 +
205 + static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, GList *glist)
206 + {
207 +        GtkWidget *label, *combo;
208 +        char str[32];
209 +
210 +        label = gtk_label_new(GetString(label_id));
211 +        gtk_widget_show(label);
212 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
213 +        
214 +        combo = gtk_combo_new();
215 +        gtk_widget_show(combo);
216 +        gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
217 +
218 +        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value);
219 +        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
220 +        
221 +        return combo;
222 + }
223 +
224 + static GtkWidget *table_make_combobox(GtkWidget *table, int row, int label_id, const char *default_value, const combo_desc *options)
225 + {
226 +        GList *glist = NULL;
227 +        while (options->label_id) {
228 +                glist = g_list_append(glist, (void *)GetString(options->label_id));
229 +                options++;
230 +        }
231 +
232 +        return table_make_combobox(table, row, label_id, default_value, glist);
233 + }
234 +
235 + static GtkWidget *table_make_file_entry(GtkWidget *table, int row, int label_id, const char *prefs_item, bool only_dirs = false)
236 + {
237 +        GtkWidget *box, *label, *entry, *button;
238 +
239 +        label = gtk_label_new(GetString(label_id));
240 +        gtk_widget_show(label);
241 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
242 +
243 +        const char *str = PrefsFindString(prefs_item);
244 +        if (str == NULL)
245 +                str = "";
246 +
247 +        box = gtk_hbox_new(FALSE, 4);
248 +        gtk_widget_show(box);
249 +        gtk_table_attach(GTK_TABLE(table), box, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
250 +
251 +        entry = gtk_entry_new();
252 +        gtk_entry_set_text(GTK_ENTRY(entry), str);
253 +        gtk_widget_show(entry);
254 +        gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
255 +
256 +        button = make_browse_button(entry);
257 +        gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
258 +        g_object_set_data(G_OBJECT(entry), "chooser_button", button);
259 +        return entry;
260 + }
261 +
262   static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active)
263   {
264          GtkWidget *box, *label, *opt, *menu;
# Line 222 | Line 324 | static GtkWidget *make_checkbox(GtkWidge
324          return button;
325   }
326  
327 < static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *prefs_item, const combo_desc *options)
327 > static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *default_value, GList *glist)
328   {
329          GtkWidget *box, *label, *combo;
228        char str[32];
330  
331          box = gtk_hbox_new(FALSE, 4);
332          gtk_widget_show(box);
# Line 234 | Line 335 | static GtkWidget *make_combobox(GtkWidge
335          label = gtk_label_new(GetString(label_id));
336          gtk_widget_show(label);
337          gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
237
238        GList *glist = NULL;
239        while (options->label_id) {
240                glist = g_list_append(glist, (void *)GetString(options->label_id));
241                options++;
242        }
338          
339          combo = gtk_combo_new();
340          gtk_widget_show(combo);
341          gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
342          
343 <        sprintf(str, "%d", PrefsFindInt32(prefs_item));
249 <        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
343 >        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), default_value);
344          gtk_box_pack_start(GTK_BOX(box), combo, TRUE, TRUE, 0);
345          
346          return combo;
347   }
348  
349 + static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *default_value, const combo_desc *options)
350 + {
351 +        GList *glist = NULL;
352 +        while (options->label_id) {
353 +                glist = g_list_append(glist, (void *)GetString(options->label_id));
354 +                options++;
355 +        }
356 +
357 +        return make_combobox(top, label_id, default_value, glist);
358 + }
359 +
360  
361   /*
362   *  Show preferences editor
# Line 307 | Line 412 | static void cb_about(...)
412  
413          char str[512];
414          sprintf(str,
415 <                "Basilisk II\nVersion %d.%d\n\n"
415 >                PROGRAM_NAME "\nVersion %d.%d\n\n"
416                  "Copyright (C) 1997-2005 Christian Bauer et al.\n"
417 <                "E-mail: Christian.Bauer@uni-mainz.de\n"
418 <                "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n"
419 <                "Basilisk II comes with ABSOLUTELY NO\n"
417 >                "E-mail: cb@cebix.net\n"
418 > #ifdef SHEEPSHAVER
419 >                "http://sheepshaver.cebix.net/\n\n"
420 > #else
421 >                "http://basilisk.cebix.net/\n\n"
422 > #endif
423 >                PROGRAM_NAME " comes with ABSOLUTELY NO\n"
424                  "WARRANTY. This is free software, and\n"
425                  "you are welcome to redistribute it\n"
426                  "under the terms of the GNU General\n"
# Line 341 | Line 450 | static void cb_about(...)
450   // Menu item descriptions
451   static GtkItemFactoryEntry menu_items[] = {
452          {(gchar *)GetString(STR_PREFS_MENU_FILE_GTK),           NULL,                   NULL,                                                   0, "<Branch>"},
453 <        {(gchar *)GetString(STR_PREFS_ITEM_START_GTK),          NULL,                   GTK_SIGNAL_FUNC(cb_start),              0, NULL},
453 >        {(gchar *)GetString(STR_PREFS_ITEM_START_GTK),          "<control>S",   GTK_SIGNAL_FUNC(cb_start),              0, NULL},
454          {(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK),       NULL,                   GTK_SIGNAL_FUNC(cb_zap_pram),   0, NULL},
455          {(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK),           NULL,                   NULL,                                                   0, "<Separator>"},
456          {(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK),           "<control>Q",   GTK_SIGNAL_FUNC(cb_quit),               0, NULL},
457          {(gchar *)GetString(STR_HELP_MENU_GTK),                         NULL,                   NULL,                                                   0, "<LastBranch>"},
458 <        {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK),           NULL,                   GTK_SIGNAL_FUNC(cb_about),              0, NULL}
458 >        {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK),           "<control>H",   GTK_SIGNAL_FUNC(cb_about),              0, NULL}
459   };
460  
461   bool PrefsEditor(void)
# Line 381 | Line 490 | bool PrefsEditor(void)
490          gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
491  
492          create_volumes_pane(notebook);
493 <        create_scsi_pane(notebook);
493 > //      create_scsi_pane(notebook); XXX not ready yet (merge scsi_windows.cpp from original B2/Win)
494          create_graphics_pane(notebook);
495          create_input_pane(notebook);
496          create_serial_pane(notebook);
# Line 391 | Line 500 | bool PrefsEditor(void)
500  
501          static const opt_desc buttons[] = {
502                  {STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
394                {STR_PREFS_ITEM_ZAP_PRAM, GTK_SIGNAL_FUNC(cb_zap_pram)},
395                {STR_ABOUT_BUTTON, GTK_SIGNAL_FUNC(cb_about)},
503                  {STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)},
504                  {0, NULL}
505          };
# Line 409 | Line 516 | bool PrefsEditor(void)
516   *  "Volumes" pane
517   */
518  
519 + static GtkWidget *w_enableextfs, *w_extdrives, *w_cdrom_drive;
520   static GtkWidget *volume_list;
521   static int selected_volume;
522  
523 + // Set sensitivity of widgets
524 + static void set_volumes_sensitive(void)
525 + {
526 +        const bool enable_extfs = PrefsFindBool("enableextfs");
527 +        gtk_widget_set_sensitive(w_extdrives, enable_extfs);
528 +        const bool no_cdrom = PrefsFindBool("nocdrom");
529 +        gtk_widget_set_sensitive(w_cdrom_drive, !no_cdrom);
530 + }
531 +
532   // Volume in list selected
533   static void cl_selected(GtkWidget *list, int row, int column)
534   {
# Line 433 | Line 550 | static void create_volume_ok(GtkWidget *
550          gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
551  
552          const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
553 <        int size = atoi(str);
553 >        size_t size = atoi(str) << 20;
554  
555 <        char cmd[1024];
556 <        sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", file, size);
557 <        int ret = system(cmd);
441 <        if (ret == 0)
555 >        int fd = _open(file, _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC, _S_IREAD | _S_IWRITE);
556 >        if (fd >= 0) {
557 >          if (_chsize(fd, size) == 0)
558                  gtk_clist_append(GTK_CLIST(volume_list), &file);
559 +          _close(fd);
560 +        }
561          gtk_widget_destroy(GTK_WIDGET(assoc->req));
562          delete assoc;
563   }
# Line 488 | Line 606 | static void cb_remove_volume(...)
606   static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);}
607   static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);}
608  
609 + // "Enable external file system" button toggled
610 + static void tb_enableextfs(GtkWidget *widget)
611 + {
612 +        PrefsReplaceBool("enableextfs", GTK_TOGGLE_BUTTON(widget)->active);
613 +        set_volumes_sensitive();
614 + }
615 +
616   // "No CD-ROM Driver" button toggled
617   static void tb_nocdrom(GtkWidget *widget)
618   {
619          PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active);
620 +        set_volumes_sensitive();
621 + }
622 +
623 + // Add names of CD-ROM devices
624 + static GList *add_cdrom_names(void)
625 + {
626 +        GList *glist = NULL;
627 +
628 +        char rootdir[4] = "X:\\";
629 +        for (char letter = 'C'; letter <= 'Z'; letter++) {
630 +                rootdir[0] = letter;
631 +                if (GetDriveType(rootdir) == DRIVE_CDROM)
632 +                        glist = g_list_append(glist, strdup(rootdir));
633 +        }
634 +
635 +        return glist;
636 + }
637 +
638 + // "Enable polling" button toggled
639 + static void tb_pollmedia(GtkWidget *widget)
640 + {
641 +        PrefsReplaceBool("pollmedia", GTK_TOGGLE_BUTTON(widget)->active);
642   }
643  
644   // Read settings from widgets and set preferences
# Line 505 | Line 652 | static void read_volumes_settings(void)
652                  gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str);
653                  PrefsAddString("disk", str);
654          }
655 +
656 +        const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_cdrom_drive)->entry));
657 +        if (str && strlen(str))
658 +                PrefsReplaceString("cdrom", str);
659 +        else
660 +                PrefsRemoveItem("cdrom");
661 +
662 +        PrefsReplaceString("extdrives", get_file_entry_path(w_extdrives));
663   }
664  
665   // Create "Volumes" pane
# Line 553 | Line 708 | static void create_volumes_pane(GtkWidge
708          menu = make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active);
709  
710          make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
711 +
712 +        GList *glist = add_cdrom_names();
713 +        str = const_cast<char *>(PrefsFindString("cdrom"));
714 +        if (str == NULL)
715 +                str = "";
716 +        w_cdrom_drive = make_combobox(box, STR_CDROM_DRIVE_CTRL, str, glist);
717 +
718 +        make_checkbox(box, STR_POLLMEDIA_CTRL, "pollmedia", GTK_SIGNAL_FUNC(tb_pollmedia));
719 +
720 +        make_separator(box);
721 +        w_enableextfs = make_checkbox(box, STR_EXTFS_ENABLE_CTRL, "enableextfs", GTK_SIGNAL_FUNC(tb_enableextfs));
722 +        w_extdrives = make_file_entry(box, STR_EXTFS_DRIVES_CTRL, "extdrives", true);
723 +
724 +        set_volumes_sensitive();
725   }
726  
727  
# Line 560 | Line 729 | static void create_volumes_pane(GtkWidge
729   *  "JIT Compiler" pane
730   */
731  
732 + #ifndef SHEEPSHAVER
733   static GtkWidget *w_jit_fpu;
734   static GtkWidget *w_jit_atraps;
735   static GtkWidget *w_jit_cache_size;
736   static GtkWidget *w_jit_lazy_flush;
737   static GtkWidget *w_jit_follow_const_jumps;
738 + #endif
739  
740   // Set sensitivity of widgets
741   static void set_jit_sensitive(void)
742   {
743 + #ifndef SHEEPSHAVER
744          const bool jit_enabled = PrefsFindBool("jit");
745          gtk_widget_set_sensitive(w_jit_fpu, jit_enabled);
746          gtk_widget_set_sensitive(w_jit_cache_size, jit_enabled);
747          gtk_widget_set_sensitive(w_jit_lazy_flush, jit_enabled);
748          gtk_widget_set_sensitive(w_jit_follow_const_jumps, jit_enabled);
749 + #endif
750   }
751  
752   // "Use JIT Compiler" button toggled
# Line 584 | Line 757 | static void tb_jit(GtkWidget *widget)
757   }
758  
759   // "Compile FPU Instructions" button toggled
760 + #ifndef SHEEPSHAVER
761   static void tb_jit_fpu(GtkWidget *widget)
762   {
763          PrefsReplaceBool("jitfpu", GTK_TOGGLE_BUTTON(widget)->active);
764   }
765 + #endif
766  
767   // "Lazy translation cache invalidation" button toggled
768 + #ifndef SHEEPSHAVER
769   static void tb_jit_lazy_flush(GtkWidget *widget)
770   {
771          PrefsReplaceBool("jitlazyflush", GTK_TOGGLE_BUTTON(widget)->active);
772   }
773 + #endif
774  
775   // "Translate through constant jumps (inline blocks)" button toggled
776 + #ifndef SHEEPSHAVER
777   static void tb_jit_follow_const_jumps(GtkWidget *widget)
778   {
779          PrefsReplaceBool("jitinline", GTK_TOGGLE_BUTTON(widget)->active);
780   }
781 + #endif
782  
783   // Read settings from widgets and set preferences
784   static void read_jit_settings(void)
# Line 607 | Line 786 | static void read_jit_settings(void)
786   #if USE_JIT
787          bool jit_enabled = PrefsFindBool("jit");
788          if (jit_enabled) {
789 + #ifndef SHEEPSHAVER
790                  const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_jit_cache_size)->entry));
791                  PrefsReplaceInt32("jitcachesize", atoi(str));
792 + #endif
793          }
794   #endif
795   }
796  
797 + // "Use built-in 68k DR emulator" button toggled
798 + #ifdef SHEEPSHAVER
799 + static void tb_jit_68k(GtkWidget *widget)
800 + {
801 +        PrefsReplaceBool("jit68k", GTK_TOGGLE_BUTTON(widget)->active);
802 + }
803 + #endif
804 +
805   // Create "JIT Compiler" pane
806   static void create_jit_pane(GtkWidget *top)
807   {
# Line 623 | Line 812 | static void create_jit_pane(GtkWidget *t
812          box = make_pane(top, STR_JIT_PANE_TITLE);
813          make_checkbox(box, STR_JIT_CTRL, "jit", GTK_SIGNAL_FUNC(tb_jit));
814          
815 + #ifndef SHEEPSHAVER
816          w_jit_fpu = make_checkbox(box, STR_JIT_FPU_CTRL, "jitfpu", GTK_SIGNAL_FUNC(tb_jit_fpu));
817          
818          // Translation cache size
# Line 633 | Line 823 | static void create_jit_pane(GtkWidget *t
823                  STR_JIT_CACHE_SIZE_16MB_LAB,
824                  0
825          };
826 <        w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, "jitcachesize", options);
826 >        sprintf(str, "%d", PrefsFindInt32("jitcachesize"));
827 >        w_jit_cache_size = make_combobox(box, STR_JIT_CACHE_SIZE_CTRL, str, options);
828          
829          // Lazy translation cache invalidation
830          w_jit_lazy_flush = make_checkbox(box, STR_JIT_LAZY_CINV_CTRL, "jitlazyflush", GTK_SIGNAL_FUNC(tb_jit_lazy_flush));
831  
832          // Follow constant jumps (inline basic blocks)
833          w_jit_follow_const_jumps = make_checkbox(box, STR_JIT_FOLLOW_CONST_JUMPS, "jitinline", GTK_SIGNAL_FUNC(tb_jit_follow_const_jumps));
834 + #endif
835  
836          set_jit_sensitive();
837   #endif
838 +
839 + #ifdef SHEEPSHAVER
840 +        make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k));
841 + #endif
842   }
843  
844   /*
# Line 654 | Line 850 | static GtkWidget *w_scsi[7];
850   // Read settings from widgets and set preferences
851   static void read_scsi_settings(void)
852   {
853 + #ifndef DISABLE_SCSI
854          for (int id=0; id<7; id++) {
855                  char prefs_name[32];
856                  sprintf(prefs_name, "scsi%d", id);
# Line 663 | Line 860 | static void read_scsi_settings(void)
860                  else
861                          PrefsRemoveItem(prefs_name);
862          }
863 + #endif
864   }
865  
866   // Create "SCSI" pane
867   static void create_scsi_pane(GtkWidget *top)
868   {
869 + #ifndef DISABLE_SCSI
870          GtkWidget *box;
871  
872          box = make_pane(top, STR_SCSI_PANE_TITLE);
# Line 677 | Line 876 | static void create_scsi_pane(GtkWidget *
876                  sprintf(prefs_name, "scsi%d", id);
877                  w_scsi[id] = make_file_entry(box, STR_SCSI_ID_0 + id, prefs_name);
878          }
879 + #endif
880   }
881  
882  
# Line 720 | Line 920 | static void mn_fullscreen(...)
920   {
921          display_type = DISPLAY_SCREEN;
922          hide_show_graphics_widgets();
923 +        PrefsReplaceInt32("frameskip", 1);
924   }
925  
926   // "5 Hz".."60Hz" selected
# Line 731 | Line 932 | static void mn_30hz(...) {PrefsReplaceIn
932   static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);}
933   static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);}
934  
935 + // QuickDraw acceleration
936 + #ifdef SHEEPSHAVER
937 + static void tb_gfxaccel(GtkWidget *widget)
938 + {
939 +        PrefsReplaceBool("gfxaccel", GTK_TOGGLE_BUTTON(widget)->active);
940 + }
941 + #endif
942 +
943   // Set sensitivity of widgets
944   static void set_graphics_sensitive(void)
945   {
# Line 748 | Line 957 | static void tb_nosound(GtkWidget *widget
957   static void parse_graphics_prefs(void)
958   {
959          display_type = DISPLAY_WINDOW;
960 + #ifdef SHEEPSHAVER
961 +        dis_width = 640;
962 +        dis_height = 480;
963 + #else
964          dis_width = 512;
965          dis_height = 384;
966 + #endif
967  
968          const char *str = PrefsFindString("screen");
969          if (str) {
# Line 889 | Line 1103 | static void create_graphics_pane(GtkWidg
1103          gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
1104          w_display_y = GTK_COMBO(combo)->entry;
1105  
1106 + #ifdef SHEEPSHAVER
1107 +        make_checkbox(box, STR_GFXACCEL_CTRL, "gfxaccel", GTK_SIGNAL_FUNC(tb_gfxaccel));
1108 + #endif
1109 +
1110          make_separator(box);
1111          make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
1112  
# Line 908 | Line 1126 | static GtkWidget *w_mouse_wheel_lines;
1126   // Set sensitivity of widgets
1127   static void set_input_sensitive(void)
1128   {
1129 <        gtk_widget_set_sensitive(w_keycode_file, PrefsFindBool("keycodes"));
1129 >        const bool use_keycodes = PrefsFindBool("keycodes");
1130 >        gtk_widget_set_sensitive(w_keycode_file, use_keycodes);
1131 >        gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_keycode_file), "chooser_button")), use_keycodes);
1132          gtk_widget_set_sensitive(w_mouse_wheel_lines, PrefsFindInt32("mousewheelmode") == 1);
1133   }
1134  
# Line 938 | Line 1158 | static void read_input_settings(void)
1158   // Create "Input" pane
1159   static void create_input_pane(GtkWidget *top)
1160   {
1161 <        GtkWidget *box, *hbox, *menu, *label;
1161 >        GtkWidget *box, *hbox, *menu, *label, *button;
1162          GtkObject *adj;
1163  
1164          box = make_pane(top, STR_INPUT_PANE_TITLE);
1165  
1166          make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
1167 <        w_keycode_file = make_file_entry(box, STR_KEYCODE_FILE_CTRL, "keycodefile");
1167 >
1168 >        hbox = gtk_hbox_new(FALSE, 4);
1169 >        gtk_widget_show(hbox);
1170 >        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1171 >
1172 >        label = gtk_label_new(GetString(STR_KEYCODES_CTRL));
1173 >        gtk_widget_show(label);
1174 >        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1175 >
1176 >        const char *str = PrefsFindString("keycodefile");
1177 >        if (str == NULL)
1178 >                str = "";
1179 >
1180 >        w_keycode_file = gtk_entry_new();
1181 >        gtk_entry_set_text(GTK_ENTRY(w_keycode_file), str);
1182 >        gtk_widget_show(w_keycode_file);
1183 >        gtk_box_pack_start(GTK_BOX(hbox), w_keycode_file, TRUE, TRUE, 0);
1184 >
1185 >        button = make_browse_button(w_keycode_file);
1186 >        gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1187 >        g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button);
1188  
1189          make_separator(box);
1190  
# Line 978 | Line 1218 | static void create_input_pane(GtkWidget
1218  
1219  
1220   /*
1221 < *  "Ports" pane
1221 > *  "Serial" pane
1222   */
1223  
1224 < static GtkWidget *w_seriala, *w_portfile0, *w_portfile0_browse;
1225 < static GtkWidget *w_serialb, *w_portfile1, *w_portfile1_browse;
1224 > static GtkWidget *w_seriala, *w_portfile0;
1225 > static GtkWidget *w_serialb, *w_portfile1;
1226  
1227   // Set sensitivity of widgets
1228   static void set_serial_sensitive(void)
# Line 993 | Line 1233 | static void set_serial_sensitive(void)
1233          str = gtk_entry_get_text(GTK_ENTRY(w_seriala));
1234          is_file = strcmp(str, "FILE") == 0;
1235          gtk_widget_set_sensitive(w_portfile0, is_file);
1236 <        gtk_widget_set_sensitive(w_portfile0_browse, is_file);
1236 >        gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_portfile0), "chooser_button")), is_file);
1237  
1238          str = gtk_entry_get_text(GTK_ENTRY(w_serialb));
1239          is_file = strcmp(str, "FILE") == 0;
1240          gtk_widget_set_sensitive(w_portfile1, is_file);
1241 <        gtk_widget_set_sensitive(w_portfile1_browse, is_file);
1241 >        gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data(G_OBJECT(w_portfile1), "chooser_button")), is_file);
1242   }
1243  
1244   // Read settings from widgets and set preferences
# Line 1022 | Line 1262 | static void read_serial_settings(void)
1262   // Port changed in combo
1263   static void cb_serial_port_changed(...)
1264   {
1025        printf("serial port changed\n");
1265          set_serial_sensitive();
1266   }
1267  
# Line 1044 | Line 1283 | static GList *add_serial_names(void)
1283          return glist;
1284   }
1285  
1286 < // Create "Ports" pane
1286 > // Create "Serial" pane
1287   static void create_serial_pane(GtkWidget *top)
1288   {
1289          GtkWidget *box, *hbox, *table, *label, *combo, *sep, *entry;
# Line 1053 | Line 1292 | static void create_serial_pane(GtkWidget
1292          box = make_pane(top, STR_SERIAL_PANE_TITLE);
1293          table = make_table(box, 2, 5);
1294  
1056        label = gtk_label_new(GetString(STR_SERIALA_CTRL));
1057        gtk_widget_show(label);
1058        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1059
1295          GList *glist = add_serial_names();
1061        combo = gtk_combo_new();
1062        gtk_widget_show(combo);
1063        gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
1296          const char *str = PrefsFindString("seriala");
1297 <        if (str == NULL)
1066 <                str = "";
1067 <        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1068 <        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1297 >        combo = table_make_combobox(table, 0, STR_SERIALA_CTRL, str, glist);
1298          w_seriala = GTK_COMBO(combo)->entry;
1299          gtk_signal_connect(GTK_OBJECT(w_seriala), "changed", GTK_SIGNAL_FUNC(cb_serial_port_changed), NULL);
1300  
1301 <        label = gtk_label_new(GetString(STR_FILE_CTRL));
1073 <        gtk_widget_show(label);
1074 <        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1075 <
1076 <        hbox = gtk_hbox_new(FALSE, 4);
1077 <        gtk_widget_show(hbox);
1078 <        gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1079 <
1080 <        w_portfile0 = gtk_entry_new();
1081 <        str = PrefsFindString("portfile0");
1082 <        if (str == NULL)
1083 <                str = "C:\\B2TEMP0.OUT";
1084 <        gtk_entry_set_text(GTK_ENTRY(w_portfile0), str);
1085 <        gtk_widget_show(w_portfile0);
1086 <        gtk_box_pack_start(GTK_BOX(hbox), w_portfile0, TRUE, TRUE, 0);
1087 <
1088 <        w_portfile0_browse = make_browse_button(w_portfile0);
1089 <        gtk_box_pack_start(GTK_BOX(hbox), w_portfile0_browse, FALSE, FALSE, 0);
1301 >        w_portfile0 = table_make_file_entry(table, 1, STR_FILE_CTRL, "portfile0");
1302  
1303          sep = gtk_hseparator_new();
1304          gtk_widget_show(sep);
1305          gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1306  
1095        label = gtk_label_new(GetString(STR_SERIALB_CTRL));
1096        gtk_widget_show(label);
1097        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1098
1099        combo = gtk_combo_new();
1100        gtk_widget_show(combo);
1101        gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
1307          str = PrefsFindString("serialb");
1308 <        if (str == NULL)
1104 <                str = "";
1105 <        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1106 <        gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1308 >        combo = table_make_combobox(table, 3, STR_SERIALB_CTRL, str, glist);
1309          w_serialb = GTK_COMBO(combo)->entry;
1310          gtk_signal_connect(GTK_OBJECT(w_serialb), "changed", GTK_SIGNAL_FUNC(cb_serial_port_changed), NULL);
1311  
1312 <        label = gtk_label_new(GetString(STR_FILE_CTRL));
1111 <        gtk_widget_show(label);
1112 <        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1113 <
1114 <        hbox = gtk_hbox_new(FALSE, 4);
1115 <        gtk_widget_show(hbox);
1116 <        gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 4, 5, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1117 <
1118 <        w_portfile1 = gtk_entry_new();
1119 <        str = PrefsFindString("portfile1");
1120 <        if (str == NULL)
1121 <                str = "C:\\B2TEMP1.OUT";
1122 <        gtk_entry_set_text(GTK_ENTRY(w_portfile1), str);
1123 <        gtk_widget_show(w_portfile1);
1124 <        gtk_box_pack_start(GTK_BOX(hbox), w_portfile1, TRUE, TRUE, 0);
1125 <
1126 <        w_portfile1_browse = make_browse_button(w_portfile1);
1127 <        gtk_box_pack_start(GTK_BOX(hbox), w_portfile1_browse, FALSE, FALSE, 0);
1312 >        w_portfile1 = table_make_file_entry(table, 4, STR_FILE_CTRL, "portfile1");
1313  
1314          set_serial_sensitive();
1315   }
# Line 1134 | Line 1319 | static void create_serial_pane(GtkWidget
1319   *  "Ethernet" pane
1320   */
1321  
1322 < static GtkWidget *w_ether, *w_udp_port;
1322 > static GtkWidget *w_ether;
1323 > static GtkWidget *w_ftp_port_list, *w_tcp_port_list;
1324 > static const char s_nat_router[] = "NAT/Router module";
1325 > static const char s_ndis_tag[] = "NDIS ";
1326  
1327   // Set sensitivity of widgets
1328   static void set_ethernet_sensitive(void)
1329   {
1330 +        const char *str = gtk_entry_get_text(GTK_ENTRY(w_ether));
1331 +
1332 +        bool is_nat_router = strcmp(str, s_nat_router) == 0;
1333 +        gtk_widget_set_sensitive(w_ftp_port_list, is_nat_router);
1334 +        gtk_widget_set_sensitive(w_tcp_port_list, is_nat_router);
1335   }
1336  
1337   // Read settings from widgets and set preferences
1338   static void read_ethernet_settings(void)
1339   {
1340          const char *str = gtk_entry_get_text(GTK_ENTRY(w_ether));
1341 <        if (str && strlen(str))
1342 <                PrefsReplaceString("ether", str);
1341 >        if (str && strlen(str) > sizeof(s_ndis_tag) && strncmp(str, s_ndis_tag, sizeof(s_ndis_tag) - 1) == 0)
1342 >                PrefsReplaceString("ether", &str[sizeof(s_ndis_tag) - 1]);
1343          else
1344                  PrefsRemoveItem("ether");
1345 +
1346 +        const bool router_enabled = str && strcmp(str, s_nat_router) == 0;
1347 +        PrefsReplaceBool("routerenabled", router_enabled);
1348 +        if (router_enabled) {
1349 +                str = gtk_entry_get_text(GTK_ENTRY(w_ftp_port_list));
1350 +                PrefsReplaceString("ftp_port_list", str);
1351 +                str = gtk_entry_get_text(GTK_ENTRY(w_tcp_port_list));
1352 +                PrefsReplaceString("tcp_port", str);
1353 +        }
1354 + }
1355 +
1356 + // Ethernet emulation type changed in menulist
1357 + static void cb_ether_changed(...)
1358 + {
1359 +        set_ethernet_sensitive();
1360   }
1361  
1362   // Add names of ethernet interfaces
1363 + // XXX use radio buttons instead (None/NDIS/NAT)
1364   static GList *add_ether_names(void)
1365   {
1366          GList *glist = NULL;
1367  
1368 <        // TODO: Get list of all Ethernet interfaces
1369 < #ifdef HAVE_SLIRP
1370 <        static char s_slirp[] = "slirp";
1371 <        glist = g_list_append(glist, s_slirp);
1372 < #endif
1373 < #if 0
1374 <        if (glist)
1375 <                g_list_sort(glist, gl_str_cmp);
1376 <        else
1377 < #endif
1378 <                glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB));
1368 >        glist = g_list_append(glist, (void *)GetString(STR_NONE_LAB));
1369 >        glist = g_list_append(glist, (void *)s_nat_router);
1370 >
1371 >        {       // Get NDIS ethernet adapters (XXX handle "ethermulticastmode")
1372 >                PacketOpenAdapter("", 0);
1373 >                {
1374 >                        ULONG sz;
1375 >                        char names[1024];
1376 >                        sz = sizeof(names);
1377 >                        if (PacketGetAdapterNames(NULL, names, &sz) == ERROR_SUCCESS) {
1378 >                                char *p = names;
1379 >                                while (*p) {
1380 >                                        const char DEVICE_HEADER[] = "\\Device\\B2ether_";
1381 >                                        if (strnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) {
1382 >                                                LPADAPTER fd = PacketOpenAdapter(p + sizeof(DEVICE_HEADER) - 1, 0);
1383 >                                                if (fd) {
1384 >                                                        char str[256];
1385 >                                                        sprintf(str, "%s%s", s_ndis_tag, p + sizeof(DEVICE_HEADER) - 1);
1386 >                                                        glist = g_list_append(glist, strdup(str));
1387 >                                                        PacketCloseAdapter(fd);
1388 >                                                }
1389 >                                        }
1390 >                                        p += strlen(p) + 1;
1391 >                                }
1392 >                        }
1393 >                }
1394 >                PacketCloseAdapter(NULL);
1395 >        }
1396          return glist;
1397   }
1398  
# Line 1188 | Line 1414 | static void create_ethernet_pane(GtkWidg
1414          gtk_widget_show(combo);
1415          gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
1416          const char *str = PrefsFindString("ether");
1417 <        if (str == NULL)
1418 <                str = "";
1417 >        if (str == NULL || str[0] == '\0') {
1418 >                if (PrefsFindBool("routerenabled"))
1419 >                        str = s_nat_router;
1420 >                else
1421 >                        str = GetString(STR_NONE_LAB);
1422 >        }
1423 >        else if (str[0] == '{') {
1424 >                static char s_device[256];
1425 >                sprintf(s_device, "%s%s", s_ndis_tag, str);
1426 >                str = s_device;
1427 >        }
1428          gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
1429          gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1430          w_ether = GTK_COMBO(combo)->entry;
1431 +        gtk_signal_connect(GTK_OBJECT(w_ether), "changed", GTK_SIGNAL_FUNC(cb_ether_changed), NULL);
1432 +
1433 +        sep = gtk_hseparator_new();
1434 +        gtk_widget_show(sep);
1435 +        gtk_table_attach(GTK_TABLE(table), sep, 0, 2, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1436 +
1437 +        label = gtk_label_new(GetString(STR_ETHER_FTP_PORT_LIST_CTRL));
1438 +        gtk_widget_show(label);
1439 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1440 +
1441 +        entry = gtk_entry_new();
1442 +        str = PrefsFindString("ftp_port_list");
1443 +        if (str == NULL)
1444 +                str = "";
1445 +        gtk_entry_set_text(GTK_ENTRY(entry), str);
1446 +        gtk_widget_show(entry);
1447 +        gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 2, 3, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1448 +        w_ftp_port_list = entry;
1449 +
1450 +        label = gtk_label_new(GetString(STR_ETHER_TCP_PORT_LIST_CTRL));
1451 +        gtk_widget_show(label);
1452 +        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
1453 +
1454 +        entry = gtk_entry_new();
1455 +        str = PrefsFindString("tcp_port");
1456 +        if (str == NULL)
1457 +                str = "";
1458 +        gtk_entry_set_text(GTK_ENTRY(entry), str);
1459 +        gtk_widget_show(entry);
1460 +        gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 3, 4, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
1461 +        w_tcp_port_list = entry;
1462  
1463          set_ethernet_sensitive();
1464   }
# Line 1202 | Line 1468 | static void create_ethernet_pane(GtkWidg
1468   *  "Memory/Misc" pane
1469   */
1470  
1471 < static GtkObject *w_ramsize_adj;
1471 > static GtkWidget *w_ramsize;
1472   static GtkWidget *w_rom_file;
1473  
1474 + // Don't use CPU when idle?
1475 + #ifdef SHEEPSHAVER
1476 + static void tb_idlewait(GtkWidget *widget)
1477 + {
1478 +        PrefsReplaceBool("idlewait", GTK_TOGGLE_BUTTON(widget)->active);
1479 + }
1480 + #endif
1481 +
1482   // "Ignore SEGV" button toggled
1483   #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1484   static void tb_ignoresegv(GtkWidget *widget)
# Line 1227 | Line 1501 | static void mn_cpu_68040(...) {PrefsRepl
1501   // Read settings from widgets and set preferences
1502   static void read_memory_settings(void)
1503   {
1504 <        PrefsReplaceInt32("ramsize", int(GTK_ADJUSTMENT(w_ramsize_adj)->value) << 20);
1504 >        const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_ramsize)->entry));
1505 >        PrefsReplaceInt32("ramsize", atoi(str) << 20);
1506  
1507 <        const char *str = get_file_entry_path(w_rom_file);
1507 >        str = get_file_entry_path(w_rom_file);
1508          if (str && strlen(str))
1509                  PrefsReplaceString("rom", str);
1510          else
# Line 1240 | Line 1515 | static void read_memory_settings(void)
1515   // Create "Memory/Misc" pane
1516   static void create_memory_pane(GtkWidget *top)
1517   {
1518 <        GtkWidget *box, *hbox, *vbox, *hbox2, *label, *scale;
1518 >        GtkWidget *box, *hbox, *table, *label, *scale, *menu;
1519  
1520          box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE);
1521 +        table = make_table(box, 2, 5);
1522  
1523 <        hbox = gtk_hbox_new(FALSE, 4);
1524 <        gtk_widget_show(hbox);
1525 <
1526 <        label = gtk_label_new(GetString(STR_RAMSIZE_SLIDER));
1527 <        gtk_widget_show(label);
1528 <        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1529 <
1530 <        vbox = gtk_vbox_new(FALSE, 4);
1531 <        gtk_widget_show(vbox);
1532 <
1533 <        gfloat min, max;
1534 <        min = 1;
1535 <        max = 1024;
1536 <        w_ramsize_adj = gtk_adjustment_new(min, min, max, 1, 16, 0);
1537 <        gtk_adjustment_set_value(GTK_ADJUSTMENT(w_ramsize_adj), PrefsFindInt32("ramsize") >> 20);
1538 <
1539 <        scale = gtk_hscale_new(GTK_ADJUSTMENT(w_ramsize_adj));
1540 <        gtk_widget_show(scale);
1541 <        gtk_scale_set_digits(GTK_SCALE(scale), 0);
1542 <        gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0);
1267 <
1268 <        hbox2 = gtk_hbox_new(FALSE, 4);
1269 <        gtk_widget_show(hbox2);
1270 <
1271 <        char val[32];
1272 <        sprintf(val, GetString(STR_RAMSIZE_FMT), int(min));
1273 <        label = gtk_label_new(val);
1274 <        gtk_widget_show(label);
1275 <        gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1276 <
1277 <        sprintf(val, GetString(STR_RAMSIZE_FMT), int(max));
1278 <        label = gtk_label_new(val);
1279 <        gtk_widget_show(label);
1280 <        gtk_box_pack_end(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1281 <        gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, TRUE, 0);
1282 <        gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
1283 <        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1523 >        static const combo_desc options[] = {
1524 > #ifndef SHEEPSHAVER
1525 >                STR_RAMSIZE_2MB_LAB,
1526 > #endif
1527 >                STR_RAMSIZE_4MB_LAB,
1528 >                STR_RAMSIZE_8MB_LAB,
1529 >                STR_RAMSIZE_16MB_LAB,
1530 >                STR_RAMSIZE_32MB_LAB,
1531 >                STR_RAMSIZE_64MB_LAB,
1532 >                STR_RAMSIZE_128MB_LAB,
1533 >                STR_RAMSIZE_256MB_LAB,
1534 >                STR_RAMSIZE_512MB_LAB,
1535 > #ifndef SHEEPSHAVER
1536 >                STR_RAMSIZE_1024MB_LAB,
1537 > #endif
1538 >                0
1539 >        };
1540 >        char default_ramsize[10];
1541 >        sprintf(default_ramsize, "%d", PrefsFindInt32("ramsize") >> 20);
1542 >        w_ramsize = table_make_combobox(table, 0, STR_RAMSIZE_CTRL, default_ramsize, options);
1543  
1544 + #ifndef SHEEPSHAVER
1545          static const opt_desc model_options[] = {
1546                  {STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)},
1547                  {STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)},
# Line 1292 | Line 1552 | static void create_memory_pane(GtkWidget
1552                  case 5: active = 0; break;
1553                  case 14: active = 1; break;
1554          }
1555 <        make_option_menu(box, STR_MODELID_CTRL, model_options, active);
1555 >        table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active);
1556 > #endif
1557  
1558   #if EMULATED_68K
1559          static const opt_desc cpu_options[] = {
# Line 1311 | Line 1572 | static void create_memory_pane(GtkWidget
1572                  case 3: active = fpu ? 3 : 2; break;
1573                  case 4: active = 4;
1574          }
1575 <        make_option_menu(box, STR_CPU_CTRL, cpu_options, active);
1575 >        table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active);
1576   #endif
1577  
1578 <        w_rom_file = make_file_entry(box, STR_ROM_FILE_CTRL, "rom");
1578 >        w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom");
1579  
1580   #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
1581          make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
1582   #endif
1583 +
1584 + #ifdef SHEEPSHAVER
1585 +        make_checkbox(box, STR_IDLEWAIT_CTRL, "idlewait", GTK_SIGNAL_FUNC(tb_idlewait));
1586 + #endif
1587   }
1588  
1589  
# Line 1347 | Line 1612 | uint8 XPRAM[XPRAM_SIZE];
1612   void MountVolume(void *fh) { }
1613   void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size) { }
1614   void WarningAlert(const char *text) { }
1615 + void recycle_write_packet(LPPACKET) { }
1616 + VOID CALLBACK packet_read_completion(DWORD, DWORD, LPOVERLAPPED) { }
1617  
1618  
1619   /*
# Line 1361 | Line 1628 | void SysAddSerialPrefs(void)
1628  
1629  
1630   /*
1631 + *  Display alerts
1632 + */
1633 +
1634 + static void display_alert(int title_id, const char *text, int flags)
1635 + {
1636 +        MessageBox(NULL, text, GetString(title_id), MB_OK | flags);
1637 + }
1638 +
1639 + static void ErrorAlert(const char *text)
1640 + {
1641 +        display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
1642 + }
1643 +
1644 +
1645 + /*
1646   *  Start standalone GUI
1647   */
1648  
# Line 1379 | Line 1661 | int main(int argc, char *argv[])
1661          // Exit preferences
1662          PrefsExit();
1663  
1664 <        // Transfer control to the Basilisk II executable
1664 >        // Transfer control to the executable
1665          if (start) {
1666 <                printf("Start Basilisk II\n");
1666 >                char path[_MAX_PATH];
1667 >                bool ok = GetModuleFileName(NULL, path, sizeof(path)) != 0;
1668 >                if (ok) {
1669 >                        char b2_path[_MAX_PATH];
1670 >                        char *p = strrchr(path, '\\');
1671 >                        *++p = '\0';
1672 >                        SetCurrentDirectory(path);
1673 >                        strcpy(b2_path, path);
1674 >                        strcat(b2_path, PROGRAM_NAME);
1675 >                        strcat(b2_path, ".exe");
1676 >                        HINSTANCE h = ShellExecute(GetDesktopWindow(), "open",
1677 >                                                                           b2_path, "", path, SW_SHOWNORMAL);
1678 >                        if ((int)h <= 32)
1679 >                                ok = false;
1680 >                }
1681 >                if (!ok) {
1682 >                        ErrorAlert("Coult not start " PROGRAM_NAME " executable");
1683 >                        return 1;
1684 >                }
1685          }
1686  
1687          return 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines