Annotation of uae/src/gui-gtk/gtkui.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * UAE - the Un*x Amiga Emulator
                      3:  *
                      4:  * Yet Another User Interface for the X11 version
                      5:  *
                      6:  * Copyright 1997, 1998 Bernd Schmidt
                      7:  * Copyright 1998 Michael Krause
                      8:  *
                      9:  * The Tk GUI doesn't work.
                     10:  * The X Forms Library isn't available as source, and there aren't any
                     11:  * binaries compiled against glibc
                     12:  *
                     13:  * So let's try this...
                     14:  */
                     15: 
                     16: #include "sysconfig.h"
                     17: #include "sysdeps.h"
                     18: 
                     19: #include "options.h"
                     20: #include "uae.h"
                     21: #include "memory.h"
                     22: #include "custom.h"
                     23: #include "audio.h"
                     24: #include "gui.h"
                     25: #include "newcpu.h"
                     26: #include "autoconf.h"
                     27: #include "filesys.h"
                     28: #include "threaddep/thread.h"
                     29: #include "sounddep/sound.h"
                     30: #include "savestate.h"
                     31: #include "debug.h"
                     32: #include "inputdevice.h"
                     33: #include "romlist.h"
                     34: #include "zfile.h"
                     35: 
                     36: #include <gtk/gtk.h>
                     37: #include <gdk/gdk.h>
                     38: 
                     39: /* One of the 1.1.6 "features" is a gratuitous name change */
                     40: #ifndef HAVE_GTK_FEATURES_1_1_6
                     41: #define gtk_container_set_border_width gtk_container_border_width
                     42: #endif
                     43: /* Likewise for 1.1.8.  */
                     44: #ifndef HAVE_GTK_FEATURES_1_1_8
                     45: #define gtk_label_set_text gtk_label_set
                     46: #endif
                     47: /* This is beginning to suck... */
                     48: #ifndef HAVE_GTK_FEATURES_1_1_13
                     49: #define gtk_toggle_button_set_active gtk_toggle_button_set_state
                     50: #endif
                     51: 
                     52: #include "util.h"
                     53: 
                     54: static int gui_active, gui_available;
                     55: 
                     56: static GtkWidget *gui_window;
                     57: 
                     58: static GtkWidget *pause_uae_widget, *snap_save_widget, *snap_load_widget;
                     59: 
                     60: static GtkWidget *chipsize_widget[5];
                     61: static GtkWidget *bogosize_widget[4];
                     62: static GtkWidget *fastsize_widget[5];
                     63: static GtkWidget *z3size_widget[10];
                     64: static GtkWidget *p96size_widget[7];
                     65: static GtkWidget *rom_text_widget, *rom_path_widget, *key_text_widget;
                     66: static GtkWidget *romlist_widget, *romsel_button;
                     67: static int romlist_nr_entries;
                     68: 
                     69: static GtkWidget *disk_insert_widget[4], *disk_eject_widget[4], *disk_text_widget[4];
                     70: static GtkWidget *dftype_widget[4];
                     71: static GtkWidget *disk_type_widget[4];
                     72: 
                     73: static GtkAdjustment *cpuspeed_adj;
                     74: static GtkWidget *cpuspeed_widgets[4], *cpuspeed_scale;
                     75: static GtkWidget *cpu_widget[7], *fpu_widget[5];
                     76: static GtkWidget *sound_widget[4], *sound_ch_widget[3], *sound_interpol_widget[5];
                     77: static GtkWidget *sound_filter_widget[5];
                     78: static GtkAdjustment *stereo_sep_adj, *stereo_delay_adj;
                     79: static GtkWidget *stereo_sep_scale, *stereo_delay_scale;
                     80: 
                     81: static GtkWidget *coll_widget[4], *cslevel_widget[4], *ntsc_widget[2];
                     82: static GtkWidget *mbtype_widget, *mbtype_labelled;
                     83: static GtkWidget *fcop_widget;
                     84: 
                     85: static GtkAdjustment *framerate_adj;
                     86: static GtkWidget *bimm_widget, *b32_widget, *afscr_widget, *pfscr_widget;
                     87: 
                     88: struct scrmode_widgets
                     89: {
                     90:     GtkWidget *frame, *modelist;
                     91:     GtkWidget *hcenter, *vcenter, *aspect, *linedbl, *leds;
                     92:     GtkWidget *hc_label, *vc_label, *ld_label;
                     93: };
                     94: 
                     95: static struct scrmode_widgets gw_windowed, gw_fullscreen;
                     96: 
                     97: static GtkWidget *joy_widget[2][6], *legacy_widget, *kbdlang_widget;
                     98: 
                     99: static GtkWidget *led_widgets[5];
                    100: static GdkColor led_on[5], led_off[5];
                    101: static unsigned int prevledstate;
                    102: 
                    103: static GtkListStore *hd_store;
                    104: static GtkWidget *hdlist_widget, *bootrom_widget;
                    105: static GtkWidget *hdchange_button, *hddel_button;
                    106: static GtkTreeSelection *hd_selection;
                    107: 
                    108: static GtkWidget *preset_list, *preset_button;
                    109: static GtkTreeSelection *preset_selection;
                    110: 
                    111: static GtkWidget *req68020, *req68ec020, *req68030, *reqa4000, *reqa1000;
                    112: static int rom_req;
                    113: 
                    114: static GtkWidget *lab_info;
                    115: static GtkWidget *notebook;
                    116: 
                    117: GtkWidget *disk_selector;
                    118: 
                    119: static uae_sem_t gui_sem;
                    120: 
                    121: /* Copies of certain changed_prefs elements, local to the GUI thread and
                    122:    protected by the gui_sem.  */
                    123: static struct gfx_params gfx_w, gfx_f;
                    124: static char *gui_snapname, *gui_romname, *gui_keyname;
                    125: static char *new_disk_string[4];
                    126: 
                    127: 
                    128: static smp_comm_pipe to_gui_pipe, from_gui_pipe;
                    129: 
                    130: /* Set to ignore the widget callbacks while we're in the process of updating
                    131:    them with new data.  */
                    132: static int ignore_gui_changes;
                    133: 
                    134: /*
                    135:  * Messages sent to GUI from UAE via to_gui_pipe
                    136:  */
                    137: enum gui_commands {
                    138:     GUICMD_SHOW,                 // Show yourself
                    139:     GUICMD_UPDATE,               // Refresh your state from changed preferences
                    140:     GUICMD_DISKCHANGE,           // Hey! A disk has been changed. Do something!
                    141:     GUICMD_MSGBOX,               // Display a message box for me, please
                    142:     GUICMD_NEW_ROMLIST,          // The ROM list has been updated.
                    143:     GUICMD_FLOPPYDLG,            // Open a floppy insert dialog
                    144:     GUICMD_FULLSCREEN,           // Fullscreen mode was toggled; update checkboxes
                    145:     GUICMD_PAUSE,                // We're now paused, in case you didn't notice
                    146:     GUICMD_UNPAUSE               // We're now running.
                    147: };
                    148: 
                    149: static uae_sem_t gui_sem, gui_init_sem, gui_quit_sem; /* gui_sem protects the DFx fields */
                    150: 
                    151: static volatile int quit_gui = 0;
                    152: 
                    153: /* Message box functions.  */
                    154: 
                    155: 
                    156: static GtkWidget *make_labelled_button (guchar *label, GtkAccelGroup *accel_group)
                    157: {
                    158:     return gtk_button_new_with_mnemonic (label);
                    159: }
                    160: 
                    161: static int find_current_toggle (GtkWidget **widgets, int count)
                    162: {
                    163:     int i;
                    164:     for (i = 0; i < count; i++)
                    165:        if (GTK_TOGGLE_BUTTON (*widgets++)->active)
                    166:            return i;
                    167:     write_log ("GTKUI: Can't happen!\n");
                    168:     return -1;
                    169: }
                    170: 
                    171: /*
                    172:  * make_message_box()
                    173:  *
                    174:  * This does the actual work of constructing the message dialog.
                    175:  *
                    176:  * title   - displayed in the dialog's titlebar
                    177:  * message - the message itself
                    178:  * modal   - whether the dialog should block input to the rest of the GUI
                    179:  * sem     - semaphore used for signalling that the dialog's finished
                    180:  *
                    181:  * TODO: Make that semaphore go away. We shouldn't need to know about it here.
                    182:  */
                    183: 
                    184: static void make_message_box (const char *title, const char *message, int modal)
                    185: {
                    186:     GtkWidget *dialog;
                    187:     GtkWidget *vbox, *hbox;
                    188:     GtkWidget *label;
                    189: 
                    190:     if (title == NULL || strlen (title) == 0)
                    191:        title = PACKAGE_NAME " information";
                    192:     dialog = gtk_dialog_new_with_buttons (title, NULL,
                    193:                                          (modal ? GTK_DIALOG_MODAL : 0),
                    194:                                          GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
                    195:                                          NULL);
                    196: 
                    197:     gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
                    198: 
                    199:     vbox = GTK_DIALOG (dialog)->vbox;
                    200: 
                    201:     hbox = gtk_hbox_new (FALSE, 0);
                    202:     gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 20);
                    203:     gtk_widget_show (hbox);
                    204: 
                    205:     label = gtk_label_new (message);
                    206:     gtk_widget_show (label);
                    207:     gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 20);
                    208:     gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
                    209: 
                    210:     gtk_dialog_run (GTK_DIALOG (dialog));
                    211: 
                    212:     gtk_widget_destroy (dialog);
                    213: }
                    214: 
                    215: static void mkmsgbox (const char *title, const char *message)
                    216: {
                    217:     make_message_box (title, message, 1);
                    218: }
                    219: 
                    220: /*
                    221:  * handle_message_box_request()
                    222:  *
                    223:  * This is called from the GUI's context in repsonse to do_message_box()
                    224:  * to actually create the dialog box
                    225:  */
                    226: static void handle_message_box_request (smp_comm_pipe *msg_pipe)
                    227: {
                    228:     const char *title = (const char *) read_comm_pipe_pvoid_blocking (msg_pipe);
                    229:     const char *msg = (const char *) read_comm_pipe_pvoid_blocking (msg_pipe);
                    230:     int modal = read_comm_pipe_int_blocking (msg_pipe);
                    231:     uae_sem_t *msg_quit_sem = (uae_sem_t *) read_comm_pipe_pvoid_blocking (msg_pipe);
                    232: 
                    233:     make_message_box (title, msg, modal);
                    234:     uae_sem_post (msg_quit_sem);
                    235: }
                    236: 
                    237: /*
                    238:  * do_message_box()
                    239:  *
                    240:  * This makes up for GTK's lack of a function for creating simple message dialogs.
                    241:  * It can be called from any context. gui_init() must have been called at some point
                    242:  * previously.
                    243:  *
                    244:  * title   - will be displayed in the dialog's titlebar (or NULL for default)
                    245:  * message - the message itself
                    246:  * modal   - should the dialog block input to the rest of the GUI
                    247:  * wait    - should the dialog wait until the user has acknowledged it
                    248:  */
                    249: static void do_message_box (const guchar *title, const guchar *message, gboolean modal, gboolean wait)
                    250: {
                    251:     uae_sem_t msg_quit_sem;
                    252: 
                    253:     // If we a need reply, then this semaphore which will be used
                    254:     // to signal us when the dialog has been exited.
                    255:     uae_sem_init (&msg_quit_sem, 0, 0);
                    256: 
                    257:     write_comm_pipe_int   (&to_gui_pipe, GUICMD_MSGBOX, 0);
                    258:     write_comm_pipe_pvoid (&to_gui_pipe, (void *) title, 0);
                    259:     write_comm_pipe_pvoid (&to_gui_pipe, (void *) message, 0);
                    260:     write_comm_pipe_int   (&to_gui_pipe, (int) modal, 0);
                    261:     write_comm_pipe_pvoid (&to_gui_pipe, wait?&msg_quit_sem:NULL, 1);
                    262: 
                    263:     if (wait)
                    264:        uae_sem_wait (&msg_quit_sem);
                    265: }
                    266: 
                    267: void gui_message (const char *format, ...)
                    268: {
                    269:     char msg[2048];
                    270:     va_list parms;
                    271: 
                    272:     va_start (parms,format);
                    273:     vsprintf ( msg, format, parms);
                    274:     va_end (parms);
                    275: 
                    276:     if (gui_available)
                    277:        do_message_box (NULL, msg, TRUE, TRUE);
                    278: 
                    279:     write_log (msg);
                    280: }
                    281: 
                    282: /* Config save/load.  */
                    283: 
                    284: static void save_config (void)
                    285: {
                    286:     FILE *f;
                    287:     char tmp[257];
                    288: 
                    289:     /* Backup the options file.  */
                    290:     strcpy (tmp, optionsfile);
                    291:     strcat (tmp, "~");
                    292:     rename (optionsfile, tmp);
                    293: 
                    294:     f = fopen (optionsfile, "w");
                    295:     if (f == NULL) {
                    296:        write_log ("Error saving options file!\n");
                    297:        return;
                    298:     }
                    299:     save_options (f, &changed_prefs);
                    300:     fclose (f);
                    301: }
                    302: 
                    303: static int nr_for_led (GtkWidget *led)
                    304: {
                    305:     int i;
                    306:     i = 0;
                    307:     while (led_widgets[i] != led)
                    308:        i++;
                    309:     return i;
                    310: }
                    311: 
                    312: static void enable_disk_buttons (int enable)
                    313: {
                    314:     int i;
                    315:     for (i = 0; i < 4; i++) {
                    316:        drive_type t = changed_prefs.dfxtype[i];
                    317:        gtk_widget_set_sensitive (disk_insert_widget[i], enable && t != DRV_NONE);
                    318:        gtk_widget_set_sensitive (disk_eject_widget[i], enable && t != DRV_NONE);
                    319:        gtk_widget_set_sensitive (dftype_widget[i], enable);
                    320:     }
                    321: }
                    322: 
                    323: static void set_disk_state (void)
                    324: {
                    325:     int i;
                    326:     ignore_gui_changes++;
                    327:     for (i = 0; i < 4; i++) {
                    328:        drive_type t = changed_prefs.dfxtype[i];
                    329:        int n;
                    330:        if (i == 0)
                    331:            n = t == DRV_35_DD ? 0 : 1;
                    332:        else
                    333:            n = t == DRV_35_DD ? 1 : t == DRV_35_HD ? 2 : 0;
                    334:        gtk_combo_box_set_active (GTK_COMBO_BOX (dftype_widget[i]), n);
                    335:     }
                    336:     ignore_gui_changes--;
                    337: }
                    338: 
                    339: static void set_romlist_state (void)
                    340: {
                    341:     int i;
                    342:     int active_entry = 0;
                    343: 
                    344:     for (i = 1; i < romlist_nr_entries; i++)
                    345:        gtk_combo_box_remove_text (GTK_COMBO_BOX (romlist_widget), 1);
                    346:     romlist_nr_entries = 1;
                    347: 
                    348:     for (i = 0;; i++) {
                    349:        struct romlist *rl = romlist_from_idx (i, ROMTYPE_KICK, 1);
                    350:        if (!rl)
                    351:            break;
                    352:        if ((changed_prefs.rom_crc32 != 0 && rl->rd->crc32 == changed_prefs.rom_crc32)
                    353:            || (changed_prefs.rom_crc32 == 0 && strcmp (rl->path, changed_prefs.romfile) == 0))
                    354:            active_entry = romlist_nr_entries;
                    355:        gtk_combo_box_append_text (GTK_COMBO_BOX (romlist_widget), rl->rd->name);
                    356:        romlist_nr_entries++;
                    357:     }
                    358:     gtk_combo_box_set_active (GTK_COMBO_BOX (romlist_widget), active_entry);
                    359:     gtk_widget_set_sensitive (romsel_button, active_entry == 0);
                    360:     gtk_widget_set_sensitive (rom_text_widget, active_entry == 0);
                    361: }
                    362: 
                    363: static void set_cpu_state (void)
                    364: {
                    365:     gtk_widget_set_sensitive (cpuspeed_scale, changed_prefs.m68k_speed > 0);
                    366: 
                    367:     gtk_widget_set_sensitive (fpu_widget[0], changed_prefs.cpu_model != 68040 && changed_prefs.cpu_model != 68060);
                    368:     gtk_widget_set_sensitive (fpu_widget[1], changed_prefs.cpu_model == 68020 || changed_prefs.cpu_model == 68030);
                    369:     gtk_widget_set_sensitive (fpu_widget[2], changed_prefs.cpu_model == 68020 || changed_prefs.cpu_model == 68030);
                    370:     gtk_widget_set_sensitive (fpu_widget[3], changed_prefs.cpu_model == 68040);
                    371:     gtk_widget_set_sensitive (fpu_widget[4], changed_prefs.cpu_model == 68060);
                    372: }
                    373: 
                    374: static void set_cpu_widget (void)
                    375: {
                    376:     int nr = (changed_prefs.cpu_model == 68000 ? 0
                    377:              : changed_prefs.cpu_model == 68010 ? 1
                    378:              : changed_prefs.cpu_model == 68020 ? 2
                    379:              : changed_prefs.cpu_model == 68030 ? 4
                    380:              : changed_prefs.cpu_model == 68040 ? 5
                    381:              : 6);
                    382: 
                    383:     if (nr == 2 && !changed_prefs.address_space_24)
                    384:        nr++;
                    385:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cpu_widget[nr]), TRUE);
                    386: 
                    387:     nr = (changed_prefs.fpu_model == 68881 ? 1
                    388:          : changed_prefs.fpu_model == 68882 ? 2
                    389:          : changed_prefs.cpu_model == 68040 ? 3
                    390:          : changed_prefs.cpu_model == 68060 ? 4
                    391:          : 0);
                    392:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fpu_widget[nr]), TRUE);
                    393:     nr = changed_prefs.m68k_speed + 1 < 3 ? changed_prefs.m68k_speed + 1 : 2;
                    394:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cpuspeed_widgets[nr]), TRUE);
                    395: }
                    396: 
                    397: /* The idea behind this is to keep entries in aspect/centering boxes even
                    398:    if a screen mode is selected where they are unnecessary, but set the
                    399:    prefs to sane values.  */
                    400: static void adjust_gfx_prefs (struct gfx_params *gp, struct scrmode_widgets *w)
                    401: {
                    402:     int need_hcenter, need_vcenter, need_aspect, need_linedbl;
                    403:     need_hcenter = gp->width < 400 || (gp->width > 512 && gp->width < 800);
                    404:     need_vcenter = gp->height <= 256 || (gp->height > 300 && gp->height <= 512);
                    405:     need_linedbl = gp->height >= 400;
                    406:     need_aspect = ((gp->height < 256 || (gp->height > 300 && gp->height < 512))
                    407:                   && gp->height * 5 / 4 < gp->width);
                    408: 
                    409:     gtk_widget_set_sensitive (w->vc_label, need_vcenter);
                    410:     gtk_widget_set_sensitive (w->hc_label, need_hcenter);
                    411:     gtk_widget_set_sensitive (w->aspect, need_aspect);
                    412:     gtk_widget_set_sensitive (w->ld_label, need_linedbl);
                    413: 
                    414:     if (!need_linedbl)
                    415:        gp->linedbl = 0;
                    416:     if (!need_aspect)
                    417:        gp->correct_aspect = FALSE;
                    418:     if (!need_vcenter)
                    419:        gp->ycenter = 0;
                    420:     if (!need_hcenter)
                    421:        gp->xcenter = 0;
                    422: }
                    423: 
                    424: static void set_gfx_mode_state (struct gfx_params *gp, struct scrmode_widgets *w)
                    425: {
                    426:     ignore_gui_changes++;
                    427: 
                    428:     gtk_combo_box_set_active (GTK_COMBO_BOX (w->linedbl), gp->linedbl ? gp->linedbl - 1 : 1);
                    429:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w->aspect), gp->correct_aspect);
                    430:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w->leds), gp->leds_on_screen);
                    431: 
                    432:     gtk_combo_box_set_active (GTK_COMBO_BOX (w->hcenter), gp->xcenter);
                    433:     gtk_combo_box_set_active (GTK_COMBO_BOX (w->vcenter), gp->ycenter);
                    434:     ignore_gui_changes--;
                    435: }
                    436: 
                    437: static void set_fullscreen_state (void)
                    438: {
                    439:     ignore_gui_changes++;
                    440:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (afscr_widget), changed_prefs.gfx_afullscreen != 0);
                    441:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pfscr_widget), changed_prefs.gfx_pfullscreen != 0);
                    442:     ignore_gui_changes--;
                    443: }
                    444: 
                    445: static void set_gfx_state (void)
                    446: {
                    447:     int t;
                    448: 
                    449:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bimm_widget), changed_prefs.immediate_blits != 0);
                    450: 
                    451:     ignore_gui_changes++;
                    452:     uae_sem_wait (&gui_sem);
                    453:     t = fixup_prefs_dimensions (&gfx_w, gfx_windowed_modes, n_windowed_modes);
                    454:     gtk_combo_box_set_active (GTK_COMBO_BOX (gw_windowed.modelist), t);
                    455:     t = fixup_prefs_dimensions (&gfx_f, gfx_fullscreen_modes, n_fullscreen_modes);
                    456:     gtk_combo_box_set_active (GTK_COMBO_BOX (gw_fullscreen.modelist), t);
                    457:     ignore_gui_changes--;
                    458: 
                    459:     adjust_gfx_prefs (&gfx_w, &gw_windowed);
                    460:     adjust_gfx_prefs (&gfx_f, &gw_fullscreen);
                    461:     uae_sem_post (&gui_sem);
                    462: 
                    463:     set_gfx_mode_state (&gfx_w, &gw_windowed);
                    464:     set_gfx_mode_state (&gfx_f, &gw_fullscreen);
                    465: 
                    466:     set_fullscreen_state ();
                    467: #if 0
                    468:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b32_widget), changed_prefs.blits_32bit_enabled != 0);
                    469: #endif
                    470: }
                    471: 
                    472: /* The intended behaviour here is that on startup, and when loading a state
                    473:    file, we examine the prefs to see if they match a given motherboard, and
                    474:    initialize the combo box accordingly.  When the user changes it, default
                    475:    settings are automatically chosen unless the user sets "Generic", in which
                    476:    case he has control over all the options.  */
                    477: static void discover_cstype (void)
                    478: {
                    479:     int t0;
                    480:     int cstype = cstype_from_prefs (&changed_prefs);
                    481: 
                    482:     t0 = (cstype == CP_GENERIC ? 0
                    483:          : cstype == CP_A1000 ? 1
                    484:          : cstype == CP_A500 || cstype == CP_A500P ? 2
                    485:          : cstype == CP_A600 ? 3
                    486:          : cstype == CP_A1200 ? 4
                    487:          : cstype == CP_A3000 ? 5
                    488:          : 6);
                    489: 
                    490:     ignore_gui_changes++;
                    491:     gtk_combo_box_set_active (GTK_COMBO_BOX (mbtype_widget), t0);
                    492:     ignore_gui_changes--;
                    493: }
                    494: 
                    495: static void set_chipset_state (void)
                    496: {
                    497:     int t0 = 0;
                    498: 
                    499:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (coll_widget[changed_prefs.collision_level]), TRUE);
                    500:     if (changed_prefs.chipset_mask & CSMASK_AGA)
                    501:        t0 = 3;
                    502:     else if (changed_prefs.chipset_mask & CSMASK_ECS_DENISE)
                    503:        t0 = 2;
                    504:     else if (changed_prefs.chipset_mask & CSMASK_ECS_AGNUS)
                    505:        t0 = 1;
                    506:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cslevel_widget[t0]), TRUE);
                    507: }
                    508: 
                    509: static void set_sound_state (void)
                    510: {
                    511:     int n;
                    512:     int stereo = changed_prefs.sound_stereo;
                    513: 
                    514:     gtk_widget_set_sensitive (stereo_sep_scale, changed_prefs.sound_stereo != SND_MONO);
                    515:     gtk_widget_set_sensitive (stereo_delay_scale, changed_prefs.sound_stereo != SND_MONO);
                    516: 
                    517:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_widget[changed_prefs.produce_sound]), 1);
                    518:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_ch_widget[stereo]), 1);
                    519:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_interpol_widget[changed_prefs.sound_interpol]), 1);
                    520:     n = (changed_prefs.sound_filter == FILTER_SOUND_OFF ? 0
                    521:         : ((changed_prefs.sound_filter == FILTER_SOUND_EMUL ? 1 : 2)
                    522:            + (changed_prefs.sound_filter_type == FILTER_SOUND_TYPE_A500 ? 0 : 2)));
                    523:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_filter_widget[n]), 1);
                    524: }
                    525: 
                    526: static void set_mem_state (void)
                    527: {
                    528:     int bogo2m_ok;
                    529:     int t, t2, i;
                    530: 
                    531:     for (i = 0; i < 10; i++)
                    532:        gtk_widget_set_sensitive (z3size_widget[i], ! changed_prefs.address_space_24);
                    533:     for (i = 0; i < 7; i++)
                    534:        gtk_widget_set_sensitive (p96size_widget[i],
                    535:                                  changed_prefs.bootrom && ! changed_prefs.address_space_24);
                    536: 
                    537:     bogo2m_ok = !((changed_prefs.chipset_mask & CSMASK_AGA) || changed_prefs.cpu_model >= 68020);
                    538:     gtk_widget_set_sensitive (bogosize_widget[3], bogo2m_ok);
                    539:                              
                    540:     t = 0;
                    541:     t2 = changed_prefs.chipmem_size;
                    542:     while (t < 4 && t2 > 0x80000)
                    543:        t++, t2 >>= 1;
                    544:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chipsize_widget[t]), 1);
                    545: 
                    546:     t = 0;
                    547:     t2 = changed_prefs.bogomem_size;
                    548:     if (t2 > 0x100000 && !bogo2m_ok)
                    549:        t2 = 0x100000;
                    550:     changed_prefs.bogomem_size = t2;
                    551:     while (t < 3 && t2 >= 0x80000)
                    552:        t++, t2 >>= 1;
                    553:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bogosize_widget[t]), 1);
                    554: 
                    555:     t = 0;
                    556:     t2 = changed_prefs.fastmem_size;
                    557:     while (t < 4 && t2 >= 0x100000)
                    558:        t++, t2 >>= 1;
                    559:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fastsize_widget[t]), 1);
                    560: 
                    561:     t = 0;
                    562:     t2 = changed_prefs.z3fastmem_size;
                    563:     while (t < 9 && t2 >= 0x100000)
                    564:        t++, t2 >>= 1;
                    565:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (z3size_widget[t]), 1);
                    566: 
                    567:     t = 0;
                    568:     t2 = changed_prefs.gfxmem_size;
                    569:     while (t < 6 && t2 >= 0x100000)
                    570:        t++, t2 >>= 1;
                    571:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (p96size_widget[t]), 1);
                    572: 
                    573:     gtk_label_set_text (GTK_LABEL (rom_path_widget), changed_prefs.path_rom);
                    574:     gtk_label_set_text (GTK_LABEL (rom_text_widget), changed_prefs.romfile);
                    575:     gtk_label_set_text (GTK_LABEL (key_text_widget), changed_prefs.keyfile);
                    576: }
                    577: 
                    578: static void set_joy_state (void)
                    579: {
                    580:     int joy_count = inputdevice_get_device_total (IDTYPE_JOYSTICK);
                    581:     int j0j = jsem_isjoy (0, &changed_prefs);
                    582:     int j0m = jsem_ismouse (0, &changed_prefs);
                    583:     int j0k = jsem_iskbdjoy (0, &changed_prefs);
                    584:     int j1j = jsem_isjoy (1, &changed_prefs);
                    585:     int j1m = jsem_ismouse (1, &changed_prefs);
                    586:     int j1k = jsem_iskbdjoy (1, &changed_prefs);
                    587:     int j0t = (j0j == 0 || j0j == 1 ? j0j
                    588:               : j0m == 0 ? 2
                    589:               : j0k + 3);
                    590:     int j1t = (j1j == 0 || j1j == 1 ? j1j
                    591:               : j1m == 0 ? 2
                    592:               : j1k + 3);
                    593:     int i;
                    594: 
                    595:     if (j0t == j1t) {
                    596:        /* Can't happen */
                    597:        j0t++;
                    598:        j0t %= 6;
                    599:     }
                    600: 
                    601:     for (i = 0; i < 6; i++) {
                    602:        int available = i >= 2 || joy_count > i;
                    603:        if (changed_prefs.input_selected_setting != 0)
                    604:            available = 0;
                    605:        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[0][i]), j0t == i);
                    606:        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[1][i]), j1t == i);
                    607:        gtk_widget_set_sensitive (joy_widget[0][i], available && j1t != i);
                    608:        gtk_widget_set_sensitive (joy_widget[1][i], available && j0t != i);
                    609:     }
                    610: 
                    611:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (legacy_widget),
                    612:                                  changed_prefs.input_selected_setting == 0);
                    613: 
                    614:     gtk_combo_box_set_active (GTK_COMBO_BOX (kbdlang_widget),
                    615:                              changed_prefs.keyboard_lang);
                    616: }
                    617: 
                    618: static void set_hd_state (void)
                    619: {
                    620:     char texts[9][256];
                    621:     int nr = nr_units (currprefs.mountinfo);
                    622:     int i;
                    623: 
                    624:     gtk_list_store_clear (hd_store);
                    625:     for (i = 0; i < nr; i++) {
                    626:        GtkTreeIter iter;
                    627:        int secspertrack, surfaces, reserved, blocksize, size;
                    628:        int cylinders, readonly, pri;
                    629:        char *volname, *rootdir, *devname;
                    630:        char *failure;
                    631: 
                    632:        /* We always use currprefs.mountinfo for the GUI.  The filesystem
                    633:           code makes a private copy which is updated every reset.  */
                    634:        failure = get_filesys_unit (currprefs.mountinfo, i,
                    635:                                    &devname, &volname, &rootdir, &readonly,
                    636:                                    &secspertrack, &surfaces, &reserved,
                    637:                                    &cylinders, &size, &blocksize, &pri);
                    638: 
                    639:        if (is_hardfile (currprefs.mountinfo, i)) {
                    640:            sprintf (texts[0], "DH%d", i );
                    641:            sprintf (texts[3], "%d", surfaces);
                    642:            sprintf (texts[4], "%d", cylinders);
                    643:            sprintf (texts[5], "%d", secspertrack);
                    644:            sprintf (texts[6], "%d", reserved);
                    645:            sprintf (texts[7], "%d", size);
                    646:            sprintf (texts[8], "%d", blocksize);
                    647:        } else {
                    648:            strcpy (texts[0], volname);
                    649:            strcpy (texts[3], "n/a");
                    650:            strcpy (texts[4], "n/a");
                    651:            strcpy (texts[5], "n/a");
                    652:            strcpy (texts[6], "n/a");
                    653:            strcpy (texts[7], "n/a");
                    654:            strcpy (texts[8], "n/a");
                    655:        }
                    656:        strcpy (texts[1], rootdir);
                    657:        gtk_list_store_append (hd_store, &iter);
                    658: 
                    659:        gtk_list_store_set (hd_store, &iter,
                    660:                            0, i,
                    661:                            1, texts[0],
                    662:                            2, texts[1],
                    663:                            3, readonly,
                    664:                            4, texts[3],
                    665:                            5, texts[4],
                    666:                            6, texts[5],
                    667:                            7, texts[6],
                    668:                            8, texts[7],
                    669:                            9, texts[8],
                    670:                            10, pri,
                    671:                            -1);
                    672:        if (volname)
                    673:            free (volname);
                    674:        if (devname)
                    675:            free (devname);
                    676:        if (rootdir)
                    677:            free (rootdir);
                    678:     }
                    679:     gtk_widget_set_sensitive (hdchange_button, FALSE);
                    680:     gtk_widget_set_sensitive (hddel_button, FALSE);
                    681: 
                    682:     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bootrom_widget),
                    683:                                  changed_prefs.bootrom != 0);
                    684: }
                    685: 
                    686: static void rom_requirements_change (void)
                    687: {
                    688:     int i, min_widget = 0;
                    689: 
                    690:     gtk_widget_hide (req68020);
                    691:     gtk_widget_hide (req68ec020);
                    692:     gtk_widget_hide (req68030);
                    693:     gtk_widget_hide (reqa1000);
                    694:     gtk_widget_hide (reqa4000);
                    695:     if ((rom_req & ROMREQ_CPUMASK) == ROMREQ_68EC020) {
                    696:        min_widget = 2;
                    697:        gtk_widget_show (req68ec020);
                    698:     } else if ((rom_req & ROMREQ_CPUMASK) == ROMREQ_68020) {
                    699:        min_widget = 3;
                    700:        gtk_widget_show (req68020);
                    701:     } else if ((rom_req & ROMREQ_CPUMASK) == ROMREQ_68030) {
                    702:        min_widget = 4;
                    703:        gtk_widget_show (req68030);
                    704:     }
                    705:     if (rom_req & ROMREQ_A4000MB) {
                    706:        gtk_widget_show (reqa4000);
                    707:        gtk_combo_box_set_active (GTK_COMBO_BOX (mbtype_widget), 6);
                    708:        gtk_widget_set_sensitive (mbtype_labelled, 0);
                    709:     } else if (rom_req & ROMREQ_A1000) {
                    710:        gtk_widget_show (reqa1000);
                    711:        gtk_combo_box_set_active (GTK_COMBO_BOX (mbtype_widget), 1);
                    712:        gtk_widget_set_sensitive (mbtype_labelled, 0);
                    713:     } else
                    714:        gtk_widget_set_sensitive (mbtype_labelled, 1);
                    715: 
                    716:     i = find_current_toggle (cpu_widget, 7);
                    717:     if (i < min_widget)
                    718:        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cpu_widget[min_widget]), TRUE);
                    719: 
                    720:     for (i = 0; i < 7; i++)
                    721:        gtk_widget_set_sensitive (cpu_widget[i], i >= min_widget);
                    722: }
                    723: 
                    724: static void draw_led (int nr)
                    725: {
                    726:     GtkWidget *thing = led_widgets[nr];
                    727:     GdkWindow *window = thing->window;
                    728:     GdkGC *gc = gdk_gc_new (window);
                    729:     GdkColor *col;
                    730: 
                    731:     if (gui_ledstate & (1 << nr))
                    732:        col = led_on + nr;
                    733:     else
                    734:        col = led_off + nr;
                    735:     gdk_gc_set_foreground (gc, col);
                    736:     gdk_draw_rectangle (window, gc, 1, 0, 0, -1, -1);
                    737:     gdk_gc_destroy (gc);
                    738: }
                    739: 
                    740: static void set_widgets_from_config (void)
                    741: {
                    742:     gfx_w = changed_prefs.gfx_w;
                    743:     gfx_f = changed_prefs.gfx_f;
                    744:     set_disk_state ();
                    745:     enable_disk_buttons (1);
                    746:     set_romlist_state ();
                    747:     set_cpu_widget ();
                    748:     set_cpu_state ();
                    749:     set_gfx_state ();
                    750:     set_joy_state ();
                    751:     set_sound_state ();
                    752:     set_mem_state ();
                    753:     set_hd_state ();
                    754:     discover_cstype ();
                    755:     set_chipset_state ();
                    756:     rom_requirements_change ();
                    757: }
                    758: 
                    759: static int my_idle (void)
                    760: {
                    761:     unsigned int leds = gui_ledstate;
                    762:     int i;
                    763: 
                    764:     if (quit_gui) {    
                    765:        gui_active = 0;
                    766:        gtk_main_quit ();
                    767:        goto out;
                    768:     }
                    769: 
                    770:     while (comm_pipe_has_data (&to_gui_pipe)) {
                    771:        int cmd = read_comm_pipe_int_blocking (&to_gui_pipe);
                    772:        int n;
                    773:        switch (cmd) {
                    774:        case GUICMD_DISKCHANGE:
                    775:            n = read_comm_pipe_int_blocking (&to_gui_pipe);
                    776:            gtk_label_set_text (GTK_LABEL (disk_text_widget[n]), currprefs.df[n]);
                    777:            break;
                    778:        case GUICMD_UPDATE:
                    779:            /* Initialization.  */
                    780:            set_widgets_from_config ();
                    781: 
                    782:            gtk_widget_show (gui_window);
                    783:            uae_sem_post (&gui_init_sem);
                    784:            gui_active = 1;
                    785:            break;
                    786:        case GUICMD_PAUSE:
                    787:            /* Set Pause-Button active */
                    788:            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pause_uae_widget), TRUE);
                    789:            break;
                    790:        case GUICMD_UNPAUSE:
                    791:            /* Set Pause-Button inactive */
                    792:            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pause_uae_widget), FALSE);
                    793:            break;
                    794:        case GUICMD_NEW_ROMLIST:
                    795:            set_romlist_state ();
                    796:            break;
                    797:        case GUICMD_FULLSCREEN:
                    798:            set_fullscreen_state ();
                    799:            break;
                    800:        case GUICMD_MSGBOX:
                    801:            handle_message_box_request(&to_gui_pipe);
                    802:            break;
                    803:        }
                    804:     }
                    805: 
                    806:     if (gui_active) {
                    807:        int n = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)) == 0 ? 5 : 1;
                    808:        for (i = 0; i < n; i++) {
                    809:            unsigned int mask = 1 << i;
                    810:            unsigned int on = leds & mask;
                    811: 
                    812:            if (on == (prevledstate & mask))
                    813:                continue;
                    814: 
                    815:            /*  printf(": %d %d\n", i, on);*/
                    816:            draw_led (i);
                    817:        }
                    818:        prevledstate = leds;
                    819:     }
                    820:   out:
                    821:     return 1;
                    822: }
                    823: 
                    824: static gint gui_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
                    825: {
                    826:     gui_active = gui_available = 0;
                    827:     gtk_widget_destroy (disk_selector);
                    828:     disk_selector = 0;
                    829:     return FALSE;
                    830: }
                    831: 
                    832: static void dftype_changed (GtkWidget *w, gpointer data)
                    833: {
                    834:     int i;
                    835: 
                    836:     if (ignore_gui_changes)
                    837:        return;
                    838:     for (i = 0; i < 4; i++) {
                    839:        int which = gtk_combo_box_get_active (GTK_COMBO_BOX (dftype_widget[i]));
                    840:        if (i == 0)
                    841:            which++;
                    842:        changed_prefs.dfxtype[i] = (which == 0 ? DRV_NONE : which == 1 ? DRV_35_DD : DRV_35_HD);
                    843:     }
                    844:     enable_disk_buttons (1);
                    845: }
                    846: 
                    847: static void kbdlang_changed (GtkWidget *w, gpointer data)
                    848: {
                    849:     int which = gtk_combo_box_get_active (GTK_COMBO_BOX (kbdlang_widget));
                    850:     changed_prefs.keyboard_lang = which;
                    851: }
                    852: 
                    853: static void joy_changed (void)
                    854: {
                    855:     int j0t, j1t;
                    856:     if (! gui_active)
                    857:        return;
                    858: 
                    859:     j0t = find_current_toggle (joy_widget[0], 6);
                    860:     j1t = find_current_toggle (joy_widget[1], 6);
                    861:     changed_prefs.jport0 = (j0t == 0 || j0t == 1 ? JSEM_JOYS + j0t
                    862:                            : j0t == 2 ? JSEM_MICE
                    863:                            : JSEM_KBDLAYOUT + j0t - 3);
                    864:     changed_prefs.jport1 = (j1t == 0 || j1t == 1 ? JSEM_JOYS + j1t
                    865:                            : j1t == 2 ? JSEM_MICE
                    866:                            : JSEM_KBDLAYOUT + j1t - 3);
                    867: 
                    868:     changed_prefs.input_selected_setting = GTK_TOGGLE_BUTTON (legacy_widget)->active ? 0 : 1;
                    869: 
                    870:     if (changed_prefs.input_selected_setting != currprefs.input_selected_setting
                    871:        || changed_prefs.jport0 != currprefs.jport0
                    872:        || changed_prefs.jport1 != currprefs.jport1)
                    873:        inputdevice_config_change ();
                    874: 
                    875:     set_joy_state ();
                    876: }
                    877: 
                    878: static void coll_changed (void)
                    879: {
                    880:     changed_prefs.collision_level = find_current_toggle (coll_widget, 4);
                    881: }
                    882: 
                    883: static void cslevel_changed (void)
                    884: {
                    885:     int t = find_current_toggle (cslevel_widget, 4);
                    886:     int t1 = 0;
                    887:     if (t > 0)
                    888:        t1 |= CSMASK_ECS_AGNUS;
                    889:     if (t > 1)
                    890:        t1 |= CSMASK_ECS_DENISE;
                    891:     if (t > 2)
                    892:        t1 |= CSMASK_AGA;
                    893:     changed_prefs.chipset_mask = t1;
                    894:     set_mem_state ();
                    895: }
                    896: 
                    897: static void custom_changed (void)
                    898: {
                    899:     if (ignore_gui_changes)
                    900:        return;
                    901:     changed_prefs.gfx_framerate = framerate_adj->value;
                    902:     changed_prefs.immediate_blits = GTK_TOGGLE_BUTTON (bimm_widget)->active;
                    903:     changed_prefs.gfx_afullscreen = GTK_TOGGLE_BUTTON (afscr_widget)->active;
                    904:     changed_prefs.gfx_pfullscreen = GTK_TOGGLE_BUTTON (pfscr_widget)->active;
                    905: #if 0
                    906:     changed_prefs.blits_32bit_enabled = GTK_TOGGLE_BUTTON (b32_widget)->active;
                    907: #endif
                    908: }
                    909: 
                    910: static void leds_changed (void)
                    911: {
                    912:     int w_leds = GTK_TOGGLE_BUTTON (gw_windowed.leds)->active;
                    913:     int f_leds = GTK_TOGGLE_BUTTON (gw_fullscreen.leds)->active;
                    914:     gfx_w.leds_on_screen = w_leds;
                    915:     gfx_f.leds_on_screen = f_leds;
                    916:     write_comm_pipe_int (&from_gui_pipe, 11, 1);
                    917: }
                    918: 
                    919: static void aspect_changed (void)
                    920: {
                    921:     int w_aspect = GTK_TOGGLE_BUTTON (gw_windowed.aspect)->active;
                    922:     int f_aspect = GTK_TOGGLE_BUTTON (gw_fullscreen.aspect)->active;
                    923:     int w_ldbl = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_windowed.linedbl)) + 1;
                    924:     int f_ldbl = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_fullscreen.linedbl)) + 1;
                    925:     int w_hc = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_windowed.hcenter));
                    926:     int f_hc = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_fullscreen.hcenter));
                    927:     int w_vc = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_windowed.vcenter));
                    928:     int f_vc = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_fullscreen.vcenter));
                    929: 
                    930:     if (ignore_gui_changes)
                    931:        return;
                    932: 
                    933:     uae_sem_wait (&gui_sem);
                    934:     gfx_w.ycenter = w_vc;
                    935:     gfx_w.xcenter = w_hc;
                    936:     gfx_w.correct_aspect = w_aspect;
                    937:     gfx_w.linedbl = w_ldbl;
                    938:     gfx_f.ycenter = f_vc;
                    939:     gfx_f.xcenter = f_hc;
                    940:     gfx_f.correct_aspect = f_aspect;
                    941:     gfx_f.linedbl = f_ldbl;
                    942: 
                    943:     adjust_gfx_prefs (&gfx_w, &gw_windowed);
                    944:     adjust_gfx_prefs (&gfx_f, &gw_fullscreen);
                    945:     uae_sem_post (&gui_sem);
                    946:     write_comm_pipe_int (&from_gui_pipe, 11, 1);
                    947: }
                    948: 
                    949: static void screenmode_changed (void)
                    950: {
                    951:     int w = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_windowed.modelist));
                    952:     int f = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_fullscreen.modelist));
                    953:     int need_set_w = 0, need_set_f = 0;
                    954: 
                    955:     if (ignore_gui_changes)
                    956:        return;
                    957: 
                    958:     uae_sem_wait (&gui_sem);
                    959:     if (w != -1) {
                    960:        need_set_w = (gfx_w.width != gfx_windowed_modes[w].w
                    961:                      || gfx_w.height != gfx_windowed_modes[w].h);
                    962:        gfx_w.width = gfx_windowed_modes[w].w;
                    963:        gfx_w.height = gfx_windowed_modes[w].h;
                    964:     }
                    965:     if (f != -1) {
                    966:        need_set_f = (gfx_f.width != gfx_fullscreen_modes[f].w
                    967:                      || gfx_f.height != gfx_fullscreen_modes[f].h);
                    968:        gfx_f.width = gfx_fullscreen_modes[f].w;
                    969:        gfx_f.height = gfx_fullscreen_modes[f].h;
                    970:     }
                    971:     if (need_set_w) {
                    972:        fixup_prefs_dimensions (&gfx_w, gfx_windowed_modes, n_windowed_modes);
                    973:     }
                    974:     if (need_set_f) {
                    975:        fixup_prefs_dimensions (&gfx_f, gfx_fullscreen_modes, n_fullscreen_modes);
                    976:     }
                    977:     uae_sem_post (&gui_sem);
                    978: 
                    979:     if (!need_set_w && !need_set_f)
                    980:        return;
                    981: 
                    982:     /* We may have switched to a screenmode that has centering or other
                    983:        modifiers enabled; re-set the members of the prefs structure
                    984:        according to the new mode.  See comment before adjust_gfx_prefs.
                    985: 
                    986:        aspect_changed also sends the message to the main thread.  */
                    987:     aspect_changed ();
                    988: }
                    989: 
                    990: static void cpuspeed_changed (void)
                    991: {
                    992:     int which = find_current_toggle (cpuspeed_widgets, 3);
                    993:     changed_prefs.m68k_speed = (which == 0 ? -1
                    994:                                : which == 1 ? 0
                    995:                                : cpuspeed_adj->value);
                    996:     set_cpu_state ();
                    997: }
                    998: 
                    999: static void cputype_changed (void)
                   1000: {
                   1001:     int i, oldcl;
                   1002:     int whichtoggle;
                   1003:     if (! gui_active)
                   1004:        return;
                   1005: 
                   1006:     whichtoggle = find_current_toggle (cpu_widget, 7);
                   1007:     changed_prefs.address_space_24 = whichtoggle < 3;
                   1008:     if (whichtoggle >= 3)
                   1009:        whichtoggle--;
                   1010: 
                   1011:     if (whichtoggle == 5)
                   1012:        whichtoggle = 6;
                   1013:     changed_prefs.cpu_model = 68000 + 10 * whichtoggle;
                   1014: 
                   1015:     if (changed_prefs.cpu_model == 68060) {
                   1016:        changed_prefs.fpu_model = 68060;
                   1017:        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fpu_widget[4]), 1);
                   1018:     } else if (changed_prefs.cpu_model == 68040) {
                   1019:        changed_prefs.fpu_model = 68040;
                   1020:        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fpu_widget[3]), 1);
                   1021:     } else if ((changed_prefs.cpu_model != 68020 && changed_prefs.cpu_model != 68030)
                   1022:               || changed_prefs.fpu_model == 68040
                   1023:               || changed_prefs.fpu_model == 68060) {
                   1024:        changed_prefs.fpu_model = 0;
                   1025:        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fpu_widget[0]), 1);
                   1026:     } else {
                   1027:        whichtoggle = find_current_toggle (fpu_widget, 5);
                   1028:        changed_prefs.fpu_model = (whichtoggle == 0 ? 0
                   1029:                                   : whichtoggle == 1 ? 68881
                   1030:                                   : whichtoggle == 2 ? 68882
                   1031:                                   : whichtoggle == 3 ? 68040
                   1032:                                   : 68060);
                   1033:     }
                   1034: 
                   1035:     set_cpu_state ();
                   1036:     /* May influence bogomem size and Z3/GFXcard memory.  */
                   1037:     set_mem_state();
                   1038: }
                   1039: 
                   1040: static void chipsize_changed (void)
                   1041: {
                   1042:     int t = find_current_toggle (chipsize_widget, 5);
                   1043:     changed_prefs.chipmem_size = 0x80000 << t;
                   1044:     for (t = 0; t < 5; t++)
                   1045:        gtk_widget_set_sensitive (fastsize_widget[t], changed_prefs.chipmem_size <= 0x200000);
                   1046:     if (changed_prefs.chipmem_size > 0x200000) {
                   1047:        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fastsize_widget[0]), 1);
                   1048:        changed_prefs.fastmem_size = 0;
                   1049:     }
                   1050: }
                   1051: 
                   1052: static void bogosize_changed (void)
                   1053: {
                   1054:     int t = find_current_toggle (bogosize_widget, 4);
                   1055:     changed_prefs.bogomem_size = (0x40000 << t) & ~0x40000;
                   1056: }
                   1057: 
                   1058: static void fastsize_changed (void)
                   1059: {
                   1060:     int t = find_current_toggle (fastsize_widget, 5);
                   1061:     changed_prefs.fastmem_size = (0x80000 << t) & ~0x80000;
                   1062: }
                   1063: 
                   1064: static void z3size_changed (void)
                   1065: {
                   1066:     int t = find_current_toggle (z3size_widget, 10);
                   1067:     changed_prefs.z3fastmem_size = (0x80000 << t) & ~0x80000;
                   1068: }
                   1069: 
                   1070: static void p96size_changed (void)
                   1071: {
                   1072:     int t = find_current_toggle (p96size_widget, 7);
                   1073:     changed_prefs.gfxmem_size = (0x80000 << t) & ~0x80000;
                   1074: }
                   1075: 
                   1076: static void rom_combo_changed (void)
                   1077: {
                   1078:     int t = gtk_combo_box_get_active (GTK_COMBO_BOX (romlist_widget));
                   1079:     gtk_widget_set_sensitive (romsel_button, t == 0);
                   1080:     gtk_widget_set_sensitive (rom_text_widget, t == 0);
                   1081: 
                   1082:     rom_req = 0;
                   1083: 
                   1084:     if (t == 0) {
                   1085:        changed_prefs.rom_crc32 = 0;
                   1086:     } else {
                   1087:        struct romlist *rl = romlist_from_idx (t - 1, ROMTYPE_KICK, 1);
                   1088:        if (rl) {
                   1089:            changed_prefs.rom_crc32 = rl->rd->crc32;
                   1090:            rom_req = rl->rd->cpu;
                   1091:        }
                   1092:     }
                   1093:     rom_requirements_change ();
                   1094: }
                   1095: 
                   1096: static void sound_changed (void)
                   1097: {
                   1098:     int n;
                   1099: 
                   1100:     changed_prefs.produce_sound = find_current_toggle (sound_widget, 4);
                   1101:     n = find_current_toggle (sound_ch_widget, 3);
                   1102:     changed_prefs.sound_stereo = n == 0 ? SND_MONO : SND_STEREO;
                   1103:     changed_prefs.sound_interpol = find_current_toggle (sound_interpol_widget, 5);
                   1104:     n = find_current_toggle (sound_filter_widget, 5);
                   1105:     if (n == 0)
                   1106:        changed_prefs.sound_filter = FILTER_SOUND_OFF;
                   1107:     else {
                   1108:        changed_prefs.sound_filter = (n & 1) ? FILTER_SOUND_EMUL : FILTER_SOUND_ON;
                   1109:        changed_prefs.sound_filter_type = (n > 2 ? FILTER_SOUND_TYPE_A1200 : FILTER_SOUND_TYPE_A500);
                   1110:     }
                   1111:     changed_prefs.sound_mixed_stereo_delay = stereo_delay_adj->value;
                   1112:     changed_prefs.sound_stereo_separation = stereo_sep_adj->value;
                   1113: 
                   1114:     gtk_widget_set_sensitive (stereo_sep_scale, changed_prefs.sound_stereo == SND_STEREO);
                   1115:     gtk_widget_set_sensitive (stereo_delay_scale, changed_prefs.sound_stereo == SND_STEREO);
                   1116: }
                   1117: 
                   1118: static void bootrom_changed (void)
                   1119: {
                   1120:     changed_prefs.bootrom = GTK_TOGGLE_BUTTON (bootrom_widget)->active ? 1 : 0;
                   1121:     set_mem_state ();
                   1122: }
                   1123: 
                   1124: static void ntsc_changed (void)
                   1125: {
                   1126:     changed_prefs.ntscmode = find_current_toggle (ntsc_widget, 2);
                   1127: }
                   1128: 
                   1129: static void mbtype_changed (void)
                   1130: {
                   1131:     int needs_aga, allows_ocs, allows_ecs;
                   1132:     int n, cstype;
                   1133: 
                   1134:     if (ignore_gui_changes)
                   1135:        return;
                   1136: 
                   1137:     n = gtk_combo_box_get_active (GTK_COMBO_BOX (mbtype_widget));
                   1138:     cstype = (n == 0 ? CP_GENERIC
                   1139:              : n == 1 ? CP_A1000
                   1140:              : n == 2 ? CP_A500
                   1141:              : n == 3 ? CP_A600
                   1142:              : n == 4 ? CP_A1200
                   1143:              : n == 5 ? CP_A3000
                   1144:              : CP_A4000);
                   1145:     if (cstype != CP_GENERIC)
                   1146:        built_in_chipset_prefs (&changed_prefs, cstype);
                   1147: 
                   1148:     needs_aga = cstype == CP_A1200 || cstype == CP_A4000 || cstype == CP_A4000T || cstype == CP_CD32;
                   1149:     allows_ocs = cstype == CP_A1000 || cstype == CP_A500 || cstype == CP_A2000;
                   1150:     allows_ecs = !needs_aga && cstype != CP_A1000;
                   1151: 
                   1152:     gtk_widget_set_sensitive (cslevel_widget[0], cstype == CP_GENERIC || allows_ocs);
                   1153:     gtk_widget_set_sensitive (cslevel_widget[1], cstype == CP_GENERIC || allows_ecs);
                   1154:     gtk_widget_set_sensitive (cslevel_widget[2], cstype == CP_GENERIC || allows_ecs);
                   1155:     gtk_widget_set_sensitive (cslevel_widget[3], cstype == CP_GENERIC || needs_aga);
                   1156: 
                   1157:     if (cstype != CP_GENERIC) {
                   1158:        if (needs_aga)
                   1159:            changed_prefs.chipset_mask = CSMASK_AGA | CSMASK_FULL_ECS;
                   1160:        else if (! allows_ecs)
                   1161:            changed_prefs.chipset_mask = 0;
                   1162:     }
                   1163:     set_chipset_state ();
                   1164: }
                   1165: 
                   1166: static void did_reset (void)
                   1167: {
                   1168:     if (quit_gui)
                   1169:        return;
                   1170: 
                   1171:     write_comm_pipe_int (&from_gui_pipe, 2, 1);
                   1172: }
                   1173: 
                   1174: static void did_debug (void)
                   1175: {
                   1176:     if (quit_gui)
                   1177:        return;
                   1178: 
                   1179:     write_comm_pipe_int (&from_gui_pipe, 3, 1);
                   1180: }
                   1181: 
                   1182: static void did_quit (void)
                   1183: {
                   1184:     if (quit_gui)
                   1185:        return;
                   1186: 
                   1187:     write_comm_pipe_int (&from_gui_pipe, 4, 1);
                   1188: }
                   1189: 
                   1190: static void did_eject (GtkWidget *w, gpointer data_p)
                   1191: {
                   1192:     int data = GPOINTER_TO_INT (data_p);
                   1193:     if (quit_gui)
                   1194:        return;
                   1195: 
                   1196:     write_comm_pipe_int (&from_gui_pipe, 0, 0);
                   1197:     write_comm_pipe_int (&from_gui_pipe, data, 1);
                   1198:     gtk_label_set_text (GTK_LABEL (disk_text_widget[data]), "");
                   1199: }
                   1200: 
                   1201: static void pause_uae (void)
                   1202: {
                   1203:     if (quit_gui)
                   1204:        return;
                   1205: 
                   1206:     write_comm_pipe_int (&from_gui_pipe, GTK_TOGGLE_BUTTON (pause_uae_widget)->active ? 5 : 6, 1);
                   1207:     if (! GTK_TOGGLE_BUTTON (pause_uae_widget)->active)
                   1208:        gtk_widget_hide (lab_info);
                   1209: }
                   1210: 
                   1211: static void end_pause_uae (void)
                   1212: {
                   1213:     write_comm_pipe_int (&to_gui_pipe, GUICMD_UNPAUSE, 1);
                   1214: }
                   1215: 
                   1216: static char fsbuffer[100];
                   1217: 
                   1218: static GtkWidget *make_file_selector (const char *title,
                   1219:                                      GtkFileChooserAction action)
                   1220: {
                   1221:     GtkWidget *p = gtk_file_chooser_dialog_new (title, GTK_WINDOW (gui_window), action,
                   1222:                                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                   1223:                                                action == GTK_FILE_CHOOSER_ACTION_SAVE ? GTK_STOCK_SAVE : GTK_STOCK_OPEN,
                   1224:                                                GTK_RESPONSE_ACCEPT,
                   1225:                                                NULL);
                   1226: 
                   1227:     return p;
                   1228: }
                   1229: 
                   1230: static void filesel_set_path (GtkWidget *p, const char *path)
                   1231: {
                   1232:     size_t len = strlen (path);
                   1233:     if (len > 0 && ! access (path, R_OK)) {
                   1234:        char *tmp = xmalloc (len + 2);
                   1235:        strcpy (tmp, path);
                   1236:        strcat (tmp, "/");
                   1237:        gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (p), tmp);
                   1238:     }
                   1239: }
                   1240: 
                   1241: static void make_disk_selector (void)
                   1242: {
                   1243:     if (disk_selector)
                   1244:        return;
                   1245:     disk_selector = make_file_selector ("Select a disk image file to mount",
                   1246:                                        GTK_FILE_CHOOSER_ACTION_OPEN);
                   1247:     filesel_set_path (disk_selector, currprefs.path_floppy);
                   1248: }
                   1249: 
                   1250: static void did_insert (GtkWidget *w, gpointer data)
                   1251: {
                   1252:     int n = GPOINTER_TO_INT (data);
                   1253: 
                   1254:     make_disk_selector ();
                   1255:     sprintf (fsbuffer, "Select a disk image file for DF%d", n);
                   1256:     gtk_window_set_title (GTK_WINDOW (disk_selector), fsbuffer);
                   1257: 
                   1258:     if (gtk_dialog_run (GTK_DIALOG (disk_selector)) == GTK_RESPONSE_ACCEPT) {
                   1259:        char *filename;
                   1260: 
                   1261:        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (disk_selector));
                   1262: 
                   1263:        uae_sem_wait (&gui_sem);
                   1264:        if (new_disk_string[n] != 0)
                   1265:            free (new_disk_string[n]);
                   1266:        new_disk_string[n] = strdup (filename);
                   1267:        uae_sem_post (&gui_sem);
                   1268:        write_comm_pipe_int (&from_gui_pipe, 1, 0);
                   1269:        write_comm_pipe_int (&from_gui_pipe, n, 1);
                   1270:        gtk_label_set_text (GTK_LABEL (disk_text_widget[n]), filename);
                   1271: 
                   1272:        g_free (filename);
                   1273:     }
                   1274:     gtk_widget_hide (disk_selector);
                   1275: }
                   1276: 
                   1277: static gint driveled_event (GtkWidget *thing, GdkEvent *event)
                   1278: {
                   1279:     int lednr = nr_for_led (thing);
                   1280: 
                   1281:     switch (event->type) {
                   1282:      case GDK_MAP:
                   1283:        draw_led (lednr);
                   1284:        break;
                   1285:      case GDK_EXPOSE:
                   1286:        draw_led (lednr);
                   1287:        break;
                   1288:      default:
                   1289:        break;
                   1290:     }
                   1291: 
                   1292:   return 0;
                   1293: }
                   1294: 
                   1295: static GtkWidget *snap_selector;
                   1296: 
                   1297: static void did_loadstate (void)
                   1298: {
                   1299:     GtkWidget *dialog;
                   1300: 
                   1301:     dialog = make_file_selector ("Select a state file to restore", GTK_FILE_CHOOSER_ACTION_OPEN);
                   1302: 
                   1303:     if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
                   1304:        char *filename;
                   1305: 
                   1306:        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
                   1307: 
                   1308:        uae_sem_wait (&gui_sem);
                   1309:        gui_snapname = strdup (filename);
                   1310:        uae_sem_post (&gui_sem);
                   1311:        write_comm_pipe_int (&from_gui_pipe, 7, 0);
                   1312:        write_comm_pipe_int (&from_gui_pipe, STATE_DORESTORE, 1);
                   1313: 
                   1314:        g_free (filename);
                   1315:     }
                   1316: 
                   1317:     gtk_widget_destroy (dialog);
                   1318: }
                   1319: 
                   1320: static void did_savestate (void)
                   1321: {
                   1322:     GtkWidget *dialog;
                   1323: 
                   1324:     dialog = make_file_selector ("Select a filename for the state file",
                   1325:                                 GTK_FILE_CHOOSER_ACTION_SAVE);
                   1326: 
                   1327:     if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
                   1328:        char *filename;
                   1329: 
                   1330:        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
                   1331: 
                   1332:        uae_sem_wait (&gui_sem);
                   1333:        gui_snapname = strdup (filename);
                   1334:        uae_sem_post (&gui_sem);
                   1335:        write_comm_pipe_int (&from_gui_pipe, 7, 0);
                   1336:        write_comm_pipe_int (&from_gui_pipe, STATE_DOSAVE, 1);
                   1337: 
                   1338:        g_free (filename);
                   1339:     }
                   1340: 
                   1341:     gtk_widget_destroy (dialog);
                   1342: }
                   1343: 
                   1344: static void did_rompathchange (GtkWidget *w, gpointer data)
                   1345: {
                   1346:     GtkWidget *pathsel;
                   1347:     pathsel = make_file_selector ("Select a ROM path",
                   1348:                                  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
                   1349:     filesel_set_path (pathsel, currprefs.path_rom);
                   1350:     if (gtk_dialog_run (GTK_DIALOG (pathsel)) == GTK_RESPONSE_ACCEPT) {
                   1351:        char *filename;
                   1352: 
                   1353:        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (pathsel));
                   1354: 
                   1355:        uae_sem_wait (&gui_sem);
                   1356:        gui_romname = strdup (filename);
                   1357:        uae_sem_post (&gui_sem);
                   1358:        write_comm_pipe_int (&from_gui_pipe, 10, 0);
                   1359:        gtk_label_set_text (GTK_LABEL (rom_path_widget), gui_romname);
                   1360: 
                   1361:        g_free (filename);
                   1362:     }
                   1363: 
                   1364:     gtk_widget_destroy (pathsel);
                   1365: }
                   1366: 
                   1367: static void did_romchange (GtkWidget *w, gpointer data)
                   1368: {
                   1369:     GtkWidget *romsel;
                   1370: 
                   1371:     romsel = make_file_selector ("Select a ROM file",
                   1372:                                 GTK_FILE_CHOOSER_ACTION_OPEN);
                   1373:     filesel_set_path (romsel, currprefs.path_rom);
                   1374:     if (gtk_dialog_run (GTK_DIALOG (romsel)) == GTK_RESPONSE_ACCEPT) {
                   1375:        char *filename;
                   1376: 
                   1377:        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (romsel));
                   1378:        rom_req = 0;
                   1379:        rom_requirements_change ();
                   1380: 
                   1381:        uae_sem_wait (&gui_sem);
                   1382:        gui_romname = strdup (filename);
                   1383:        uae_sem_post (&gui_sem);
                   1384:        write_comm_pipe_int (&from_gui_pipe, 8, 0);
                   1385:        gtk_label_set_text (GTK_LABEL (rom_text_widget), gui_romname);
                   1386: 
                   1387:        g_free (filename);
                   1388:     }
                   1389: 
                   1390:     gtk_widget_destroy (romsel);
                   1391: }
                   1392: 
                   1393: static void did_keychange (GtkWidget *w, gpointer data)
                   1394: {
                   1395:     GtkWidget *keysel;
                   1396: 
                   1397:     keysel = make_file_selector ("Select a Kickstart key file",
                   1398:                                 GTK_FILE_CHOOSER_ACTION_OPEN);
                   1399:     filesel_set_path (keysel, currprefs.path_rom);
                   1400: 
                   1401:     if (gtk_dialog_run (GTK_DIALOG (keysel)) == GTK_RESPONSE_ACCEPT) {
                   1402:        char *filename;
                   1403: 
                   1404:        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (keysel));
                   1405:        uae_sem_wait (&gui_sem);
                   1406:        gui_keyname = strdup (filename);
                   1407:        uae_sem_post (&gui_sem);
                   1408:        write_comm_pipe_int (&from_gui_pipe, 9, 0);
                   1409:        gtk_label_set_text (GTK_LABEL (key_text_widget), gui_keyname);
                   1410: 
                   1411:        g_free (filename);
                   1412:     }
                   1413:     
                   1414:     gtk_widget_destroy (keysel);
                   1415: }
                   1416: 
                   1417: static void add_empty_vbox (GtkWidget *tobox)
                   1418: {
                   1419:     GtkWidget *thing = gtk_vbox_new (FALSE, 0);
                   1420:     gtk_widget_show (thing);
                   1421:     gtk_box_pack_start (GTK_BOX (tobox), thing, TRUE, TRUE, 0);
                   1422: }
                   1423: 
                   1424: static void add_centered_to_vbox (GtkWidget *vbox, GtkWidget *w, int vexpand)
                   1425: {
                   1426:     GtkWidget *hbox = gtk_hbox_new (TRUE, 0);
                   1427:     gtk_widget_show (hbox);
                   1428:     gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, FALSE, 0);
                   1429:     gtk_box_pack_start (GTK_BOX (vbox), hbox, vexpand, vexpand, 0);
                   1430: }
                   1431: 
                   1432: static GtkWidget *make_labelled_widget (const char *str, GtkWidget *thing, int expand)
                   1433: {
                   1434:     GtkWidget *label = gtk_label_new (str);
                   1435:     GtkWidget *hbox2 = gtk_hbox_new (FALSE, 4);
                   1436: 
                   1437:     gtk_widget_show (label);
                   1438:     gtk_widget_show (thing);
                   1439: 
                   1440:     gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
                   1441:     gtk_box_pack_start (GTK_BOX (hbox2), thing, expand, TRUE, 0);
                   1442: 
                   1443:     return hbox2;
                   1444: }
                   1445: 
                   1446: static GtkWidget *add_labelled_widget_centered (const char *str, GtkWidget *thing, GtkWidget *vbox)
                   1447: {
                   1448:     GtkWidget *w = make_labelled_widget (str, thing, FALSE);
                   1449:     gtk_widget_show (w);
                   1450:     add_centered_to_vbox (vbox, w, 0);
                   1451:     return w;
                   1452: }
                   1453: 
                   1454: static int make_radio_group (const char **labels, GtkWidget *tobox,
                   1455:                              GtkWidget **saveptr, gint t1, gint t2,
                   1456:                              void (*sigfunc) (void), int count, GSList *group)
                   1457: {
                   1458:     int t = 0;
                   1459: 
                   1460:     while (*labels && (count == -1 || count-- > 0)) {
                   1461:        GtkWidget *thing = gtk_radio_button_new_with_label (group, *labels++);
                   1462:        group = gtk_radio_button_group (GTK_RADIO_BUTTON (thing));
                   1463: 
                   1464:        *saveptr++ = thing;
                   1465:        gtk_widget_show (thing);
                   1466:        gtk_box_pack_start (GTK_BOX (tobox), thing, t1, t2, 0);
                   1467:        gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
                   1468:        t++;
                   1469:     }
                   1470:     return t;
                   1471: }
                   1472: 
                   1473: static GtkWidget *make_radio_group_box (const char *title, const char **labels,
                   1474:                                        GtkWidget **saveptr, int horiz,
                   1475:                                        void (*sigfunc) (void), GtkWidget **boxp)
                   1476: {
                   1477:     GtkWidget *frame, *newbox;
                   1478: 
                   1479:     frame = gtk_frame_new (title);
                   1480:     newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (FALSE, 4);
                   1481:     gtk_widget_show (newbox);
                   1482:     gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
                   1483:     gtk_container_add (GTK_CONTAINER (frame), newbox);
                   1484:     make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc, -1, NULL);
                   1485:     if (boxp)
                   1486:        *boxp = newbox;
                   1487:     return frame;
                   1488: }
                   1489: 
                   1490: static GtkWidget *make_radio_group_box_1 (const char *title, const char **labels,
                   1491:                                          GtkWidget **saveptr, int horiz,
                   1492:                                          void (*sigfunc) (void), int elts_per_column)
                   1493: {
                   1494:     GtkWidget *frame, *newbox;
                   1495:     GtkWidget *column;
                   1496:     GSList *group = 0;
                   1497: 
                   1498:     frame = gtk_frame_new (title);
                   1499:     column = (horiz ? gtk_vbox_new : gtk_hbox_new) (FALSE, 4);
                   1500:     gtk_container_add (GTK_CONTAINER (frame), column);
                   1501:     gtk_widget_show (column);
                   1502: 
                   1503:     while (*labels) {
                   1504:        int count;
                   1505:        newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (FALSE, 4);
                   1506:        gtk_widget_show (newbox);
                   1507:        gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
                   1508:        gtk_container_add (GTK_CONTAINER (column), newbox);
                   1509:        count = make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc, elts_per_column, group);
                   1510:        labels += count;
                   1511:        saveptr += count;
                   1512:        group = gtk_radio_button_group (GTK_RADIO_BUTTON (saveptr[-1]));
                   1513:     }
                   1514:     return frame;
                   1515: }
                   1516: 
                   1517: static GtkWidget *make_led (int nr)
                   1518: {
                   1519:     GtkWidget *subframe, *the_led, *thing;
                   1520:     GdkColormap *colormap;
                   1521: 
                   1522:     the_led = gtk_vbox_new (FALSE, 0);
                   1523:     gtk_widget_show (the_led);
                   1524: 
                   1525:     thing = gtk_preview_new (GTK_PREVIEW_COLOR);
                   1526:     gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
                   1527:     gtk_widget_show (thing);
                   1528: 
                   1529:     subframe = gtk_frame_new (NULL);
                   1530:     gtk_box_pack_start (GTK_BOX (the_led), subframe, TRUE, TRUE, 0);
                   1531:     gtk_widget_show (subframe);
                   1532: 
                   1533:     thing = gtk_drawing_area_new ();
                   1534:     gtk_drawing_area_size (GTK_DRAWING_AREA (thing), 20, 5);
                   1535:     gtk_widget_set_events (thing, GDK_EXPOSURE_MASK);
                   1536:     gtk_container_add (GTK_CONTAINER (subframe), thing);
                   1537:     colormap = gtk_widget_get_colormap (thing);
                   1538:     led_on[nr].red = nr == 0 ? 0xEEEE : 0xCCCC;
                   1539:     led_on[nr].green = nr == 0 ? 0: 0xFFFF;
                   1540:     led_on[nr].blue = 0;
                   1541:     led_on[nr].pixel = 0;
                   1542:     led_off[nr].red = 0;
                   1543:     led_off[nr].green = 0;
                   1544:     led_off[nr].blue = 0;
                   1545:     led_off[nr].pixel = 0;
                   1546:     gdk_color_alloc (colormap, led_on + nr);
                   1547:     gdk_color_alloc (colormap, led_off + nr);
                   1548:     led_widgets[nr] = thing;
                   1549:     gtk_signal_connect (GTK_OBJECT (thing), "event",
                   1550:                        (GtkSignalFunc) driveled_event, (gpointer) thing);
                   1551:     gtk_widget_show (thing);
                   1552: 
                   1553:     thing = gtk_preview_new (GTK_PREVIEW_COLOR);
                   1554:     gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
                   1555:     gtk_widget_show (thing);
                   1556: 
                   1557:     return the_led;
                   1558: }
                   1559: 
                   1560: static GtkWidget *make_file_container (const char *title, GtkWidget *vbox, int vertical)
                   1561: {
                   1562:     GtkWidget *thing = gtk_frame_new (title);
                   1563:     GtkWidget *file_vbox = vertical ? gtk_vbox_new (FALSE, 4) : gtk_hbox_new (FALSE, 4);
                   1564: 
                   1565:     gtk_container_set_border_width (GTK_CONTAINER (file_vbox), 4);
                   1566:     gtk_container_add (GTK_CONTAINER (thing), file_vbox);
                   1567:     gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
                   1568:     gtk_widget_show (file_vbox);
                   1569:     gtk_widget_show (thing);
                   1570: 
                   1571:     return file_vbox;
                   1572: }
                   1573: 
                   1574: static GtkWidget *make_file_widget (GtkWidget *buttonbox)
                   1575: {
                   1576:     GtkWidget *thing, *subthing;
                   1577:     GtkWidget *subframe = gtk_frame_new (NULL);
                   1578: 
                   1579:     gtk_frame_set_shadow_type (GTK_FRAME (subframe), GTK_SHADOW_ETCHED_OUT);
                   1580:     gtk_box_pack_start (GTK_BOX (buttonbox), subframe, TRUE, TRUE, 0);
                   1581:     gtk_widget_show (subframe);
                   1582:     subthing = gtk_vbox_new (FALSE, 0);
                   1583:     gtk_widget_show (subthing);
                   1584:     gtk_container_add (GTK_CONTAINER (subframe), subthing);
                   1585:     thing = gtk_label_new ("");
                   1586:     gtk_widget_show (thing);
                   1587:     gtk_box_pack_start (GTK_BOX (subthing), thing, TRUE, TRUE, 0);
                   1588: 
                   1589:     return thing;
                   1590: }
                   1591: 
                   1592: static void make_floppy_disks (GtkWidget *vbox)
                   1593: {
                   1594:     GtkWidget *thing, *subthing, *subframe, *buttonbox, *file_vbox;
                   1595:     char buf[5];
                   1596:     int i;
                   1597: 
                   1598:     add_empty_vbox (vbox);
                   1599: 
                   1600:     for (i = 0; i < 4; i++) {
                   1601:        /* Frame with an hbox and the "DFx:" title */
                   1602:        sprintf (buf, "DF%d:", i);
                   1603:        file_vbox = make_file_container (buf, vbox, 1);
                   1604: 
                   1605:        buttonbox = gtk_hbox_new (FALSE, 4);
                   1606:        gtk_box_pack_start (GTK_BOX (file_vbox), buttonbox, FALSE, TRUE, 0);
                   1607:        gtk_widget_show (buttonbox);
                   1608: 
                   1609:        /* LED */
                   1610:        subthing = make_led (i + 1);
                   1611:        gtk_box_pack_start (GTK_BOX (buttonbox), subthing, FALSE, TRUE, 0);
                   1612: 
                   1613:        /* Current file display */
                   1614:        disk_text_widget[i] = make_file_widget (buttonbox);
                   1615: 
                   1616:        /* Now, the buttons.  */
                   1617:        thing = gtk_button_new_with_label ("Eject");
                   1618:        gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
                   1619:        gtk_widget_show (thing);
                   1620:        disk_eject_widget[i] = thing;
                   1621:        gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_eject,
                   1622:                            GINT_TO_POINTER (i));
                   1623: 
                   1624:        thing = gtk_button_new_with_label ("Insert");
                   1625:        gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
                   1626:        gtk_widget_show (thing);
                   1627:        disk_insert_widget[i] = thing;
                   1628:        gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_insert,
                   1629:                            GINT_TO_POINTER (i));
                   1630: 
                   1631:        buttonbox = gtk_hbox_new (FALSE, 4);
                   1632:        gtk_box_pack_start (GTK_BOX (file_vbox), buttonbox, FALSE, FALSE, 0);
                   1633:        gtk_widget_show (buttonbox);
                   1634: 
                   1635:        if (i == 0)
                   1636:            thing = make_chooser (2, "3.5 DD", "3.5 HD");
                   1637:        else
                   1638:            thing = make_chooser (3, "Disabled", "3.5 DD", "3.5 HD");
                   1639:        gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) dftype_changed,
                   1640:                            GINT_TO_POINTER (i));
                   1641:        dftype_widget[i] = thing;
                   1642: 
                   1643:        thing = make_labelled_widget ("Type:", thing, 0);
                   1644:        gtk_box_pack_end (GTK_BOX (buttonbox), thing, FALSE, FALSE, 0);
                   1645:        gtk_widget_show (thing);
                   1646:     }
                   1647: 
                   1648:     add_empty_vbox (vbox);
                   1649: }
                   1650: 
                   1651: static GtkWidget *make_cpu_speed_sel (void)
                   1652: {
                   1653:     int t;
                   1654:     static const char *labels[] = {
                   1655:        "Optimize for host CPU speed", "Approximate 68000/7MHz speed", "Adjustable",
                   1656:        NULL
                   1657:     };
                   1658:     GtkWidget *frame, *newbox;
                   1659: 
                   1660:     frame = gtk_frame_new ("CPU speed");
                   1661:     newbox = gtk_vbox_new (FALSE, 4);
                   1662:     gtk_widget_show (newbox);
                   1663:     gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
                   1664:     gtk_container_add (GTK_CONTAINER (frame), newbox);
                   1665:     make_radio_group (labels, newbox, cpuspeed_widgets, 0, 1, cpuspeed_changed, -1, NULL);
                   1666: 
                   1667:     t = currprefs.m68k_speed > 0 ? currprefs.m68k_speed : 4 * CYCLE_UNIT;
                   1668:     cpuspeed_adj = GTK_ADJUSTMENT (gtk_adjustment_new (t, 1.0, 5120.0, 1.0, 1.0, 1.0));
                   1669:     gtk_signal_connect (GTK_OBJECT (cpuspeed_adj), "value_changed",
                   1670:                        GTK_SIGNAL_FUNC (cpuspeed_changed), NULL);
                   1671: 
                   1672:     cpuspeed_scale = gtk_hscale_new (cpuspeed_adj);
                   1673:     gtk_range_set_update_policy (GTK_RANGE (cpuspeed_scale), GTK_UPDATE_DELAYED);
                   1674:     gtk_scale_set_digits (GTK_SCALE (cpuspeed_scale), 0);
                   1675:     gtk_scale_set_value_pos (GTK_SCALE (cpuspeed_scale), GTK_POS_RIGHT);
                   1676:     cpuspeed_scale = make_labelled_widget ("Cycles/insn:", cpuspeed_scale, TRUE);
                   1677:     gtk_widget_show (cpuspeed_scale);
                   1678:     gtk_box_pack_start (GTK_BOX (newbox), cpuspeed_scale, FALSE, FALSE, 0);
                   1679: 
                   1680:     return frame;
                   1681: }
                   1682: 
                   1683: static void make_cpu_widgets (GtkWidget *vbox)
                   1684: {
                   1685:     int i;
                   1686:     GtkWidget *newbox, *hbox, *frame;
                   1687:     GtkWidget *thing, *label;
                   1688:     static const char *cpulabels[] = {
                   1689:        "68000", "68010", "68EC020", "68020", "68030", "68040", "68060",
                   1690:        NULL
                   1691:     };
                   1692:     static const char *fpulabels[] = {
                   1693:        "None", "68881", "68882", "68040", "68060",
                   1694:        NULL
                   1695:     };
                   1696: 
                   1697:     add_empty_vbox (vbox);
                   1698: 
                   1699:     hbox = gtk_hbox_new (FALSE, 0);
                   1700:     add_empty_vbox (hbox);
                   1701: 
                   1702:     newbox = make_radio_group_box ("CPU type", cpulabels, cpu_widget, 0, cputype_changed, NULL);
                   1703:     gtk_widget_show (newbox);
                   1704:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
                   1705: 
                   1706:     newbox = make_radio_group_box ("FPU type", fpulabels, fpu_widget, 0, cputype_changed, NULL);
                   1707:     gtk_widget_show (newbox);
                   1708:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
                   1709: 
                   1710:     newbox = make_cpu_speed_sel ();
                   1711:     gtk_widget_show (newbox);
                   1712:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
                   1713: 
                   1714:     add_empty_vbox (hbox);
                   1715:     gtk_widget_show (hbox);
                   1716:     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
                   1717: 
                   1718:     req68ec020 = gtk_label_new ("The selected ROM requires at least a 68ec020.");
                   1719:     add_centered_to_vbox (vbox, req68ec020, 0);
                   1720: 
                   1721:     req68020 = gtk_label_new ("The selected ROM requires at least a 68020.");
                   1722:     add_centered_to_vbox (vbox, req68020, 0);
                   1723: 
                   1724:     req68030 = gtk_label_new ("The selected ROM requires at least a 68030.");
                   1725:     add_centered_to_vbox (vbox, req68030, 0);
                   1726: 
                   1727:     add_empty_vbox (vbox);
                   1728: 
                   1729:     label = gtk_label_new ("CPU type settings take effect after the next reset.");
                   1730:     gtk_widget_show (label);
                   1731:     add_centered_to_vbox (vbox, label, 0);
                   1732: }
                   1733: 
                   1734: static GtkWidget *make_screenmode_box (const char *title, struct scrmode_widgets *mw,
                   1735:                                       struct uae_rect *modes, int n_modes)
                   1736: {
                   1737:     GtkWidget *vbox;
                   1738:     int i;
                   1739: 
                   1740:     mw->frame = gtk_frame_new (title);
                   1741:     gtk_widget_show (mw->frame);
                   1742: 
                   1743:     vbox = gtk_vbox_new (FALSE, 10);
                   1744:     gtk_widget_show (vbox);
                   1745:     gtk_container_add (GTK_CONTAINER (mw->frame), vbox);
                   1746:     gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
                   1747: 
                   1748:     mw->modelist = gtk_combo_box_new_text ();
                   1749:     gtk_widget_show (mw->modelist);
                   1750:     gtk_box_pack_start (GTK_BOX (vbox), mw->modelist, FALSE, TRUE, 0);
                   1751: 
                   1752:     for (i = 0; i < n_modes; i++) {
                   1753:        char t[200];
                   1754:        sprintf (t, "%dx%d", modes[i].w, modes[i].h);
                   1755:        gtk_combo_box_append_text (GTK_COMBO_BOX (mw->modelist), t);
                   1756:     }
                   1757:     if (n_modes == 0)
                   1758:        gtk_widget_set_sensitive (mw->frame, FALSE);
                   1759: 
                   1760:     mw->hcenter = make_chooser (3, "Off", "Simple", "Smart");
                   1761:     mw->hc_label = make_labelled_widget ("Horizontal bounds detect:", mw->hcenter, TRUE);
                   1762:     gtk_widget_show (mw->hc_label);
                   1763:     gtk_box_pack_start (GTK_BOX (vbox), mw->hc_label, FALSE, TRUE, 0);
                   1764:     
                   1765:     mw->vcenter = make_chooser (3, "Off", "Simple", "Smart");
                   1766:     mw->vc_label = make_labelled_widget ("Vertical bounds detect:", mw->vcenter, TRUE);
                   1767:     gtk_widget_show (mw->vc_label);
                   1768:     gtk_box_pack_start (GTK_BOX (vbox), mw->vc_label, FALSE, TRUE, 0);
                   1769: 
                   1770:     mw->linedbl = make_chooser (2, "Double", "Scanlines");
                   1771:     mw->ld_label = make_labelled_widget ("Line doubling:", mw->linedbl, TRUE);
                   1772:     gtk_widget_show (mw->ld_label);
                   1773:     gtk_box_pack_start (GTK_BOX (vbox), mw->ld_label, FALSE, TRUE, 0);
                   1774: 
                   1775:     mw->aspect = gtk_check_button_new_with_label ("Correct aspect ratio");
                   1776:     gtk_widget_show (mw->aspect);
                   1777:     gtk_box_pack_start (GTK_BOX (vbox), mw->aspect, FALSE, TRUE, 0);
                   1778: 
                   1779:     mw->leds = gtk_check_button_new_with_label ("Show LEDs on screen");
                   1780:     gtk_widget_show (mw->leds);
                   1781:     gtk_box_pack_start (GTK_BOX (vbox), mw->leds, FALSE, TRUE, 0);
                   1782: 
                   1783:     gtk_signal_connect (GTK_OBJECT (mw->leds), "clicked",
                   1784:                        (GtkSignalFunc) leds_changed, NULL);
                   1785:     gtk_signal_connect (GTK_OBJECT (mw->aspect), "clicked",
                   1786:                        (GtkSignalFunc) aspect_changed, NULL);
                   1787:     gtk_signal_connect (GTK_OBJECT (mw->linedbl), "changed",
                   1788:                        (GtkSignalFunc) aspect_changed, NULL);
                   1789:     gtk_signal_connect (GTK_OBJECT (mw->hcenter), "changed",
                   1790:                        (GtkSignalFunc) aspect_changed, NULL);
                   1791:     gtk_signal_connect (GTK_OBJECT (mw->vcenter), "changed",
                   1792:                        (GtkSignalFunc) aspect_changed, NULL);
                   1793:     gtk_signal_connect (GTK_OBJECT (mw->modelist), "changed",
                   1794:                        (GtkSignalFunc) screenmode_changed, NULL);
                   1795: 
                   1796:     return mw->frame;
                   1797: }
                   1798: 
                   1799: static void make_gfx_widgets (GtkWidget *vbox)
                   1800: {
                   1801:     GtkWidget *thing, *frame, *newbox, *hbox;
                   1802: 
                   1803:     add_empty_vbox (vbox);
                   1804: 
                   1805:     hbox = gtk_hbox_new (FALSE, 10);
                   1806:     gtk_widget_show (hbox);
                   1807:     add_centered_to_vbox (vbox, hbox, 0);
                   1808: 
                   1809:     thing = make_screenmode_box ("Fullscreen mode", &gw_fullscreen, gfx_fullscreen_modes, n_fullscreen_modes);
                   1810:     gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, FALSE, 0);
                   1811:     thing = make_screenmode_box ("Windowed mode", &gw_windowed, gfx_windowed_modes, n_windowed_modes);
                   1812:     gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, FALSE, 0);
                   1813:     
                   1814:     hbox = gtk_hbox_new (FALSE, 10);
                   1815:     gtk_widget_show (hbox);
                   1816:     add_centered_to_vbox (vbox, hbox, 0);
                   1817: 
                   1818:     frame = gtk_frame_new ("Miscellaneous");
                   1819:     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
                   1820: 
                   1821:     gtk_widget_show (frame);
                   1822:     newbox = gtk_vbox_new (FALSE, 4);
                   1823:     gtk_widget_show (newbox);
                   1824:     gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
                   1825:     gtk_container_add (GTK_CONTAINER (frame), newbox);
                   1826: 
                   1827:     framerate_adj = GTK_ADJUSTMENT (gtk_adjustment_new (currprefs.gfx_framerate, 1, 21, 1, 1, 1));
                   1828:     gtk_signal_connect (GTK_OBJECT (framerate_adj), "value_changed",
                   1829:                        GTK_SIGNAL_FUNC (custom_changed), NULL);
                   1830: 
                   1831:     thing = gtk_hscale_new (framerate_adj);
                   1832:     gtk_range_set_update_policy (GTK_RANGE (thing), GTK_UPDATE_DELAYED);
                   1833:     gtk_scale_set_digits (GTK_SCALE (thing), 0);
                   1834:     gtk_scale_set_value_pos (GTK_SCALE (thing), GTK_POS_RIGHT);
                   1835:     thing = make_labelled_widget ("Framerate:", thing, TRUE);
                   1836:     gtk_widget_show (thing);
                   1837:     gtk_box_pack_start (GTK_BOX (newbox), thing, FALSE, FALSE, 0);
                   1838: 
                   1839:     b32_widget = gtk_check_button_new_with_label ("32 bit blitter");
                   1840:     add_centered_to_vbox (newbox, b32_widget, 0);
                   1841: #if 0
                   1842:     gtk_widget_show (b32_widget);
                   1843: #endif
                   1844:     bimm_widget = gtk_check_button_new_with_label ("Immediate blits");
                   1845:     gtk_box_pack_start (GTK_BOX (newbox), bimm_widget, FALSE, FALSE, 0);
                   1846:     gtk_widget_show (bimm_widget);
                   1847: 
                   1848:     afscr_widget = gtk_check_button_new_with_label ("Amiga modes fullscreen");
                   1849:     gtk_box_pack_start (GTK_BOX (newbox), afscr_widget, FALSE, FALSE, 0);
                   1850:     gtk_widget_show (afscr_widget);
                   1851:     pfscr_widget = gtk_check_button_new_with_label ("Picasso modes fullscreen");
                   1852:     gtk_box_pack_start (GTK_BOX (newbox), pfscr_widget, FALSE, FALSE, 0);
                   1853:     gtk_widget_show (pfscr_widget);
                   1854:     add_empty_vbox (vbox);
                   1855: 
                   1856:     gtk_signal_connect (GTK_OBJECT (bimm_widget), "clicked",
                   1857:                        (GtkSignalFunc) custom_changed, NULL);
                   1858:     gtk_signal_connect (GTK_OBJECT (afscr_widget), "clicked",
                   1859:                        (GtkSignalFunc) custom_changed, NULL);
                   1860:     gtk_signal_connect (GTK_OBJECT (pfscr_widget), "clicked",
                   1861:                        (GtkSignalFunc) custom_changed, NULL);
                   1862: #if 0
                   1863:     gtk_signal_connect (GTK_OBJECT (b32_widget), "clicked",
                   1864:                        (GtkSignalFunc) custom_changed, NULL);
                   1865: #endif
                   1866: }
                   1867: 
                   1868: static void make_chipset_widgets (GtkWidget *vbox)
                   1869: {
                   1870:     GtkWidget *newbox, *hbox, *thing, *tmpbox;
                   1871:     static const char *colllabels[] = {
                   1872:        "None (fastest)", "Sprites only", "Sprites & playfields", "Full (very slow)",
                   1873:        NULL
                   1874:     };
                   1875:     static const char *cslevellabels[] = {
                   1876:        "OCS", "ECS Agnus", "Full ECS", "AGA", NULL
                   1877:     };
                   1878:     static const char *ntsclabels[] = {
                   1879:        "PAL (European)", "NTSC (American)", NULL
                   1880:     };
                   1881: 
                   1882:     add_empty_vbox (vbox);
                   1883: 
                   1884:     mbtype_widget = make_chooser (7, "Generic", "A1000", "A500/A2000", "A600", "A1200", "A3000", "A4000");
                   1885:     gtk_widget_show (mbtype_widget);
                   1886:     gtk_signal_connect (GTK_OBJECT (mbtype_widget), "changed", (GtkSignalFunc) mbtype_changed,
                   1887:                        NULL);
                   1888:     mbtype_labelled = make_labelled_widget ("Motherboard type:", mbtype_widget, TRUE);
                   1889:     gtk_widget_show (mbtype_labelled);
                   1890:     add_centered_to_vbox (vbox, mbtype_labelled, 0);
                   1891: 
                   1892:     hbox = gtk_hbox_new (FALSE, 10);
                   1893:     gtk_widget_show (hbox);
                   1894:     add_centered_to_vbox (vbox, hbox, 0);
                   1895: 
                   1896:     newbox = make_radio_group_box ("Sprite collisions", colllabels, coll_widget, 0, coll_changed, NULL);
                   1897:     gtk_widget_show (newbox);
                   1898:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
                   1899: 
                   1900:     newbox = make_radio_group_box ("Chipset", cslevellabels, cslevel_widget, 0, cslevel_changed, NULL);
                   1901:     gtk_widget_show (newbox);
                   1902:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
                   1903: 
                   1904:     newbox = make_radio_group_box ("Chipset video output", ntsclabels, ntsc_widget, 0, ntsc_changed, NULL);
                   1905:     gtk_widget_show (newbox);
                   1906:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
                   1907: 
                   1908:     reqa4000 = gtk_label_new ("The selected ROM requires at least an A4000.");
                   1909:     add_centered_to_vbox (vbox, reqa4000, 0);
                   1910: 
                   1911:     reqa1000 = gtk_label_new ("The selected ROM requires an A1000 motherboard.");
                   1912:     add_centered_to_vbox (vbox, reqa1000, 0);
                   1913: 
                   1914:     add_empty_vbox (vbox);
                   1915: 
                   1916:     thing = gtk_label_new ("Chipset type settings take effect after the next reset.");
                   1917:     gtk_widget_show (thing);
                   1918:     add_centered_to_vbox (vbox, thing, 0);
                   1919: }
                   1920: 
                   1921: static void make_sound_widgets (GtkWidget *vbox)
                   1922: {
                   1923:     GtkWidget *frame, *newbox;
                   1924:     int t;
                   1925:     GtkWidget *hbox, *inner_vbox, *outer_hbox;
                   1926:     static const char *soundlabels1[] = {
                   1927:        "None", "No output", "Normal", "Accurate",
                   1928:        NULL
                   1929:     }, *soundlabels2[] = {
                   1930:        "None", "RH", "BS", "Sinc", "Anti",
                   1931:        NULL
                   1932:     }, *soundlabels3[] = {
                   1933:        "Mono", "Stereo",
                   1934:        NULL
                   1935:     }, *soundlabels4[] = {
                   1936:        "Off", "A500 (power LED)", "A500 (always on)",
                   1937:        "A1200 (power LED)", "A1200 (always on)",
                   1938:        NULL
                   1939:     };
                   1940: 
                   1941:     add_empty_vbox (vbox);
                   1942: 
                   1943:     outer_hbox = gtk_hbox_new (FALSE, 0);
                   1944:     gtk_widget_show (outer_hbox);
                   1945:     add_centered_to_vbox (vbox, outer_hbox, 0);
                   1946:     
                   1947:     inner_vbox = gtk_vbox_new (FALSE, 0);
                   1948:     gtk_widget_show (inner_vbox);
                   1949:     gtk_box_pack_start (GTK_BOX (outer_hbox), inner_vbox, FALSE, TRUE, 0);
                   1950: 
                   1951:     hbox = gtk_hbox_new (FALSE, 0);
                   1952:     add_empty_vbox (hbox);
                   1953: 
                   1954:     newbox = make_radio_group_box ("Mode", soundlabels1, sound_widget, 0, sound_changed, NULL);
                   1955:     gtk_widget_show (newbox);
                   1956:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
                   1957: 
                   1958:     frame = gtk_frame_new ("Channels");
                   1959:     gtk_widget_show (frame);
                   1960:     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
                   1961:     newbox = gtk_vbox_new (FALSE, 4);
                   1962:     gtk_widget_show (newbox);
                   1963:     gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
                   1964:     gtk_container_add (GTK_CONTAINER (frame), newbox);
                   1965:     make_radio_group (soundlabels3, newbox, sound_ch_widget, 0, 1, sound_changed, -1, NULL);
                   1966: 
                   1967:     newbox = make_radio_group_box ("Interpolation", soundlabels2, sound_interpol_widget, 0, sound_changed, NULL);
                   1968:     gtk_widget_show (newbox);
                   1969:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
                   1970: 
                   1971:     newbox = make_radio_group_box ("Filter", soundlabels4, sound_filter_widget, 0, sound_changed, NULL);
                   1972:     gtk_widget_show (newbox);
                   1973:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
                   1974: 
                   1975:     add_empty_vbox (hbox);
                   1976:     gtk_widget_show (hbox);
                   1977:     gtk_box_pack_start (GTK_BOX (inner_vbox), hbox, FALSE, FALSE, 0);
                   1978: 
                   1979:     t = currprefs.sound_stereo_separation;
                   1980:     if (t == 0)
                   1981:        t = MIXED_STEREO_MAX;
                   1982:     stereo_sep_adj = GTK_ADJUSTMENT (gtk_adjustment_new (t, 1, MIXED_STEREO_MAX, 1, 1, 0));
                   1983:     gtk_signal_connect (GTK_OBJECT (stereo_sep_adj), "value_changed",
                   1984:                        GTK_SIGNAL_FUNC (sound_changed), NULL);
                   1985: 
                   1986:     stereo_sep_scale = gtk_hscale_new (stereo_sep_adj);
                   1987:     gtk_range_set_update_policy (GTK_RANGE (stereo_sep_scale), GTK_UPDATE_DELAYED);
                   1988:     gtk_scale_set_digits (GTK_SCALE (stereo_sep_scale), 0);
                   1989:     gtk_scale_set_value_pos (GTK_SCALE (stereo_sep_scale), GTK_POS_RIGHT);
                   1990:     stereo_sep_scale = make_labelled_widget ("Stereo separation:", stereo_sep_scale, TRUE);
                   1991:     gtk_widget_show (stereo_sep_scale);
                   1992:     gtk_box_pack_start (GTK_BOX (inner_vbox), stereo_sep_scale, FALSE, FALSE, 0);
                   1993: 
                   1994:     t = currprefs.sound_mixed_stereo_delay;
                   1995:     stereo_delay_adj = GTK_ADJUSTMENT (gtk_adjustment_new (t, 0, SOUND_MAX_LOG_DELAY, 1, 1, 1));
                   1996:     gtk_signal_connect (GTK_OBJECT (stereo_delay_adj), "value_changed",
                   1997:                        GTK_SIGNAL_FUNC (sound_changed), NULL);
                   1998: 
                   1999:     stereo_delay_scale = gtk_hscale_new (stereo_delay_adj);
                   2000:     gtk_range_set_update_policy (GTK_RANGE (stereo_delay_scale), GTK_UPDATE_DELAYED);
                   2001:     gtk_scale_set_digits (GTK_SCALE (stereo_delay_scale), 0);
                   2002:     gtk_scale_set_value_pos (GTK_SCALE (stereo_delay_scale), GTK_POS_RIGHT);
                   2003:     stereo_delay_scale = make_labelled_widget ("Stereo mixing delay:", stereo_delay_scale, TRUE);
                   2004:     gtk_widget_show (stereo_delay_scale);
                   2005:     gtk_box_pack_start (GTK_BOX (inner_vbox), stereo_delay_scale, FALSE, FALSE, 0);
                   2006: 
                   2007:     add_empty_vbox (vbox);
                   2008: }
                   2009: 
                   2010: static void make_rom_widgets (GtkWidget *dvbox)
                   2011: {
                   2012:     GtkWidget *hbox = gtk_hbox_new (FALSE, 10);
                   2013:     GtkWidget *label, *frame;
                   2014: 
                   2015:     rom_req = 0;
                   2016: 
                   2017:     add_empty_vbox (dvbox);
                   2018: 
                   2019:     {
                   2020:        GtkWidget *buttonbox = make_file_container ("ROM search path:", dvbox, 0);
                   2021:        GtkWidget *thing = gtk_button_new_with_label ("Change");
                   2022: 
                   2023:        /* Current file display */
                   2024:        rom_path_widget = make_file_widget (buttonbox);
                   2025: 
                   2026:        gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
                   2027:        gtk_widget_show (thing);
                   2028:        gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_rompathchange, 0);
                   2029:     }
                   2030: 
                   2031:     {
                   2032:        GtkWidget *buttonbox = make_file_container ("Kickstart ROM file:", dvbox, 1);
                   2033:        GtkWidget *hbox, *thing;
                   2034: 
                   2035:        romlist_widget = gtk_combo_box_new_text ();
                   2036:        gtk_widget_show (romlist_widget);
                   2037:        gtk_box_pack_start (GTK_BOX (buttonbox), romlist_widget, FALSE, TRUE, 0);
                   2038:        gtk_combo_box_append_text (GTK_COMBO_BOX (romlist_widget),
                   2039:                                   "Manually select a ROM file");
                   2040:        romlist_nr_entries = 1;
                   2041:        gtk_signal_connect (GTK_OBJECT (romlist_widget), "changed", (GtkSignalFunc) rom_combo_changed, 0);
                   2042: 
                   2043:        hbox = gtk_hbox_new (FALSE, 0);
                   2044:        gtk_box_pack_start (GTK_BOX (buttonbox), hbox, FALSE, TRUE, 0);
                   2045:        gtk_widget_show (hbox);
                   2046: 
                   2047:        /* Current file display */
                   2048:        rom_text_widget = make_file_widget (hbox);
                   2049: 
                   2050:        romsel_button = gtk_button_new_with_label ("Change");
                   2051:        gtk_box_pack_start (GTK_BOX (hbox), romsel_button, FALSE, TRUE, 0);
                   2052:        gtk_widget_show (romsel_button);
                   2053:        gtk_signal_connect (GTK_OBJECT (romsel_button), "clicked", (GtkSignalFunc) did_romchange, 0);
                   2054:     }
                   2055: 
                   2056:     {
                   2057:        GtkWidget *buttonbox = make_file_container ("ROM key file for Cloanto Amiga Forever:", dvbox, 0);
                   2058:        GtkWidget *thing = gtk_button_new_with_label ("Change");
                   2059: 
                   2060:        /* Current file display */
                   2061:        key_text_widget = make_file_widget (buttonbox);
                   2062: 
                   2063:        gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
                   2064:        gtk_widget_show (thing);
                   2065:        gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_keychange, 0);
                   2066:     }
                   2067: 
                   2068:     label = gtk_label_new ("These settings take effect after the next reset.");
                   2069:     gtk_widget_show (label);
                   2070:     add_centered_to_vbox (dvbox, label, 0);
                   2071: 
                   2072:     add_empty_vbox (dvbox);
                   2073: }
                   2074: 
                   2075: static void make_ram_widgets (GtkWidget *dvbox)
                   2076: {
                   2077:     GtkWidget *hbox = gtk_hbox_new (FALSE, 10);
                   2078:     GtkWidget *label, *frame;
                   2079: 
                   2080:     static const char *chiplabels[] = {
                   2081:        "512 KB", "1 MB", "2 MB", "4 MB", "8 MB", NULL
                   2082:     };
                   2083:     static const char *bogolabels[] = {
                   2084:        "None", "512 KB", "1 MB", "1.8 MB", NULL
                   2085:     };
                   2086:     static const char *fastlabels[] = {
                   2087:        "None", "1 MB", "2 MB", "4 MB", "8 MB", NULL
                   2088:     };
                   2089:     static const char *z3labels[] = {
                   2090:        "None", "1 MB", "2 MB", "4 MB", "8 MB",
                   2091:        "16 MB", "32 MB", "64 MB", "128 MB", "256 MB",
                   2092:        NULL
                   2093:     };
                   2094:     static const char *p96labels[] = {
                   2095:        "None", "1 MB", "2 MB", "4 MB", "8 MB", "16 MB", "32 MB", NULL
                   2096:     };
                   2097: 
                   2098:     add_empty_vbox (dvbox);
                   2099: 
                   2100:     gtk_widget_show (hbox);
                   2101:     add_centered_to_vbox (dvbox, hbox, 0);
                   2102: 
                   2103:     add_empty_vbox (dvbox);
                   2104: 
                   2105:     label = gtk_label_new ("These settings take effect after the next reset.");
                   2106:     gtk_widget_show (label);
                   2107:     add_centered_to_vbox (dvbox, label, 0);
                   2108: 
                   2109:     frame = make_radio_group_box ("Chip Mem", chiplabels, chipsize_widget, 0, chipsize_changed, NULL);
                   2110:     gtk_widget_show (frame);
                   2111:     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
                   2112: 
                   2113:     frame = make_radio_group_box ("Slow Mem", bogolabels, bogosize_widget, 0, bogosize_changed, NULL);
                   2114:     gtk_widget_show (frame);
                   2115:     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
                   2116: 
                   2117:     frame = make_radio_group_box ("Fast Mem", fastlabels, fastsize_widget, 0, fastsize_changed, NULL);
                   2118:     gtk_widget_show (frame);
                   2119:     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
                   2120: 
                   2121:     frame = make_radio_group_box_1 ("Z3 Mem", z3labels, z3size_widget, 0, z3size_changed, 5);
                   2122:     gtk_widget_show (frame);
                   2123:     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
                   2124: 
                   2125:     frame = make_radio_group_box_1 ("P96 RAM", p96labels, p96size_widget, 0, p96size_changed, 4);
                   2126:     gtk_widget_show (frame);
                   2127:     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
                   2128: }
                   2129: 
                   2130: static void make_joy_widgets (GtkWidget *dvbox)
                   2131: {
                   2132:     int i;
                   2133:     GtkWidget *hbox = gtk_hbox_new (FALSE, 10);
                   2134:     GtkWidget *thing;
                   2135:     static const char *joylabels[] = {
                   2136:        "Joystick 0", "Joystick 1", "Mouse", "Numeric pad",
                   2137:        "Cursor keys/Right Ctrl", "T/F/H/B/Left Alt",
                   2138:        NULL
                   2139:     };
                   2140: 
                   2141:     add_empty_vbox (dvbox);
                   2142:     gtk_widget_show (hbox);
                   2143:     add_centered_to_vbox (dvbox, hbox, 0);
                   2144: 
                   2145:     legacy_widget = gtk_check_button_new_with_label ("Use legacy configuration");
                   2146:     add_centered_to_vbox (dvbox, legacy_widget, 0);
                   2147:     gtk_widget_show (legacy_widget);
                   2148:     gtk_signal_connect (GTK_OBJECT (legacy_widget), "clicked",
                   2149:                        (GtkSignalFunc) joy_changed, NULL);
                   2150: 
                   2151:     for (i = 0; i < 2; i++) {
                   2152:        GtkWidget *vbox, *frame;
                   2153:        char buffer[20];
                   2154:        int j;
                   2155: 
                   2156:        sprintf (buffer, "Port %d", i);
                   2157:        frame = make_radio_group_box (buffer, joylabels, joy_widget[i], 0, joy_changed, NULL);
                   2158:        gtk_widget_show (frame);
                   2159:        gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
                   2160:     }
                   2161: 
                   2162:     thing = make_chooser (7, "English (QWERTY)", "Danish", "Deutsch (QWERTZ)", "Swedish",
                   2163:                          "Francais (AZERTY)", "Italian", "Spanish");
                   2164:     gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) kbdlang_changed,
                   2165:                        GINT_TO_POINTER (i));
                   2166:     kbdlang_widget = thing;
                   2167:     thing = add_labelled_widget_centered ("Keyboard language:", thing, dvbox);
                   2168: 
                   2169:     add_empty_vbox (dvbox);
                   2170: }
                   2171: 
                   2172: static GtkWidget *leftalign (GtkWidget *thing)
                   2173: {
                   2174:     GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
                   2175:     gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, FALSE, 0);
                   2176:     return hbox;
                   2177: }
                   2178: 
                   2179: static GtkWidget *create_dirdlg (const char *title, int row)
                   2180: {
                   2181:     GtkWidget *vbox, *pathsel, *dirdlg;
                   2182:     GtkWidget *path_entry, *volname_entry, *pri_entry;
                   2183: 
                   2184:     dirdlg = gtk_dialog_new_with_buttons (title, GTK_WINDOW (gui_window),
                   2185:                                          GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                   2186:                                          GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
                   2187:                                          GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
                   2188:                                          NULL);
                   2189: 
                   2190:     gtk_window_set_position (GTK_WINDOW (dirdlg), GTK_WIN_POS_MOUSE);
                   2191: 
                   2192:     vbox = GTK_DIALOG (dirdlg)->vbox;
                   2193: 
                   2194:     pathsel = make_file_selector ("Select a path to mount",
                   2195:                                  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
                   2196: 
                   2197:     gtkutil_add_table (GTK_WIDGET (vbox),
                   2198:                       leftalign (gtk_label_new ("Path:")), 1, 1, GTK_FILL,
                   2199:                       leftalign (path_entry = gtk_file_chooser_button_new_with_dialog (pathsel)), 2, 1, GTK_FILL,
                   2200:                       GTKUTIL_ROW_END,
                   2201:                       leftalign (gtk_label_new ("Volume name:")), 1, 1, GTK_FILL,
                   2202:                       leftalign (volname_entry = gtk_entry_new_with_max_length (32)), 2, 1, GTK_FILL,
                   2203:                       GTKUTIL_ROW_END,
                   2204:                       leftalign (gtk_label_new ("Boot priority:")), 1, 1, GTK_FILL,
                   2205:                       leftalign (pri_entry = gtk_entry_new_with_max_length (2)), 2, 1, GTK_FILL,
                   2206:                       GTKUTIL_TABLE_END);
                   2207: 
                   2208:     if (row != -1) {
                   2209:        char *failure;
                   2210:        char t[20];
                   2211:        int secspertrack, surfaces, reserved, blocksize, size;
                   2212:        int cylinders, readonly, pri;
                   2213:        char *volname, *rootdir, *devname;
                   2214: 
                   2215:        failure = get_filesys_unit (currprefs.mountinfo, row,
                   2216:                                    &devname, &volname, &rootdir, &readonly,
                   2217:                                    &secspertrack, &surfaces, &reserved,
                   2218:                                    &cylinders, &size, &blocksize, &pri);
                   2219:        if (failure) {
                   2220:            mkmsgbox ("Error", failure);
                   2221:            goto out;
                   2222:        }
                   2223:        gtk_entry_set_text (GTK_ENTRY (volname_entry), volname);
                   2224:        gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (path_entry), rootdir);
                   2225:        sprintf (t, "%d", pri);
                   2226:        gtk_entry_set_text (GTK_ENTRY (pri_entry), t);
                   2227:        if (volname)
                   2228:            free (volname);
                   2229:        if (devname)
                   2230:            free (devname);
                   2231:        if (rootdir)
                   2232:            free (rootdir);
                   2233:     }
                   2234: 
                   2235:   retry:
                   2236:     if (gtk_dialog_run (GTK_DIALOG (dirdlg)) == GTK_RESPONSE_ACCEPT) {
                   2237:        const char *failure;
                   2238:        const char *pathname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (path_entry));
                   2239:        const char *volname = gtk_entry_get_text (GTK_ENTRY (volname_entry));
                   2240:        const char *bprstr = gtk_entry_get_text (GTK_ENTRY (pri_entry));
                   2241:        char fixed_volname[256];
                   2242:        int n, bpr;
                   2243: 
                   2244:        if (pathname == NULL || strlen (pathname) == 0 || access (pathname, R_OK) != 0) {
                   2245:            mkmsgbox ("Error", "You must select a valid path.");
                   2246:            goto retry;
                   2247:        }
                   2248:        n = volname == NULL ? 0 : strlen (volname);
                   2249:        if (n > 255) {
                   2250:            mkmsgbox ("Error", "Volume name too long.");
                   2251:            goto retry;
                   2252:        }
                   2253:        /* Strip colons from the end.  */
                   2254:        if (n > 0) {
                   2255:            strcpy (fixed_volname, volname);
                   2256:            if (fixed_volname[n - 1] == ':') {
                   2257:                fixed_volname[n - 1] = '\0';
                   2258:                n--;
                   2259:            }
                   2260:        }
                   2261: 
                   2262:        if (n == 0) {
                   2263:            mkmsgbox ("Error", "You must enter a volume name.");
                   2264:            goto retry;
                   2265:        }
                   2266: 
                   2267:        if (strlen (bprstr) == 0) {
                   2268:            mkmsgbox ("Error", "You must enter a valid number of surfaces.");
                   2269:            goto retry;
                   2270:        }
                   2271:        bpr = atoi (bprstr);
                   2272: 
                   2273:        if (row == -1) {
                   2274:            failure = add_filesys_unit (currprefs.mountinfo, NULL, fixed_volname, pathname,
                   2275:                                        0, 0, 0, 0, 0, bpr);
                   2276:        } else {
                   2277:            failure = set_filesys_unit (currprefs.mountinfo, row, NULL, fixed_volname, pathname,
                   2278:                                        0, 0, 0, 0, 0, bpr);
                   2279:        }
                   2280:        if (failure) {
                   2281:            mkmsgbox ("Error", failure);
                   2282:            goto retry;
                   2283:        }
                   2284:        set_hd_state ();
                   2285:     }
                   2286: 
                   2287:   out:
                   2288:     gtk_widget_destroy (dirdlg);
                   2289:     return 0;
                   2290: }
                   2291: 
                   2292: static void create_hdfdlg (const char *title, int row)
                   2293: {
                   2294:     GtkWidget *vbox, *pathsel;
                   2295:     GtkWidget *hdfdlg;
                   2296:     static GtkWidget *bpt_entry, *surfaces_entry, *pri_entry;
                   2297:     static GtkWidget *blocksize_entry, *reserved_entry, *path_entry;
                   2298: 
                   2299:     int readonly = 0;
                   2300: 
                   2301:     hdfdlg = gtk_dialog_new_with_buttons (title, GTK_WINDOW (gui_window),
                   2302:                                          GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                   2303:                                          GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
                   2304:                                          GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
                   2305:                                          NULL);
                   2306: 
                   2307:     gtk_window_set_position (GTK_WINDOW (hdfdlg), GTK_WIN_POS_MOUSE);
                   2308: 
                   2309:     pathsel = make_file_selector ("Select a path to mount",
                   2310:                                  GTK_FILE_CHOOSER_ACTION_OPEN);
                   2311: 
                   2312:     vbox = GTK_DIALOG (hdfdlg)->vbox;
                   2313: 
                   2314:     gtkutil_add_table (GTK_WIDGET (vbox),
                   2315:                       leftalign (gtk_label_new ("File:")), 1, 1, GTK_FILL,
                   2316:                       leftalign (path_entry = gtk_file_chooser_button_new_with_dialog (pathsel)), 2, 1, GTK_FILL,
                   2317:                       GTKUTIL_ROW_END,
                   2318:                       leftalign (gtk_label_new ("Reserved blocks:")), 1, 1, GTK_FILL,
                   2319:                       leftalign (reserved_entry = gtk_entry_new_with_max_length (6)), 2, 1, GTK_FILL,
                   2320:                       GTKUTIL_ROW_END,
                   2321:                       leftalign (gtk_label_new ("Surfaces:")), 1, 1, GTK_FILL,
                   2322:                       leftalign (surfaces_entry = gtk_entry_new_with_max_length (2)), 2, 1, GTK_FILL,
                   2323:                       GTKUTIL_ROW_END,
                   2324:                       leftalign (gtk_label_new ("Blocksize:")), 1, 1, GTK_FILL,
                   2325:                       leftalign (blocksize_entry = gtk_entry_new_with_max_length (6)), 2, 1, GTK_FILL,
                   2326:                       GTKUTIL_ROW_END,                
                   2327:                       leftalign (gtk_label_new ("Blocks per track:")), 1, 1, GTK_FILL,
                   2328:                       leftalign (bpt_entry = gtk_entry_new_with_max_length (6)), 2, 1, GTK_FILL,
                   2329:                       GTKUTIL_ROW_END,
                   2330:                       leftalign (gtk_label_new ("Boot priority:")), 1, 1, GTK_FILL,
                   2331:                       leftalign (pri_entry = gtk_entry_new_with_max_length (2)), 2, 1, GTK_FILL,
                   2332: 
                   2333:                       GTKUTIL_TABLE_END);
                   2334: 
                   2335:     gtk_file_chooser_button_set_width_chars (GTK_FILE_CHOOSER_BUTTON (path_entry), 40);
                   2336: 
                   2337:     if (row != -1) {
                   2338:        char *failure;
                   2339:        char *devname, *volname, *rootdir;
                   2340:        int secspertrack, surfaces, reserved, blocksize, size;
                   2341:        int cylinders, pri;
                   2342:        char t[20];
                   2343: 
                   2344:        failure = get_filesys_unit (currprefs.mountinfo, row,
                   2345:                                    &devname, &volname, &rootdir, &readonly,
                   2346:                                    &secspertrack, &surfaces, &reserved,
                   2347:                                    &cylinders, &size, &blocksize, &pri);
                   2348:        if (failure) {
                   2349:            mkmsgbox ("Error", failure);
                   2350:            goto out;
                   2351:        }
                   2352:        gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (path_entry), rootdir);
                   2353:        sprintf (t, "%d", blocksize);
                   2354:        gtk_entry_set_text (GTK_ENTRY (blocksize_entry), t);
                   2355:        sprintf (t, "%d", secspertrack);
                   2356:        gtk_entry_set_text (GTK_ENTRY (bpt_entry), t);
                   2357:        sprintf (t, "%d", surfaces);
                   2358:        gtk_entry_set_text (GTK_ENTRY (surfaces_entry), t);
                   2359:        sprintf (t, "%d", reserved);
                   2360:        gtk_entry_set_text (GTK_ENTRY (reserved_entry), t);
                   2361:        sprintf (t, "%d", pri);
                   2362:        gtk_entry_set_text (GTK_ENTRY (pri_entry), t);
                   2363:        if (volname)
                   2364:            free (volname);
                   2365:        if (devname)
                   2366:            free (devname);
                   2367:        if (rootdir)
                   2368:            free (rootdir);
                   2369:     }
                   2370: 
                   2371:   retry:
                   2372:     if (gtk_dialog_run (GTK_DIALOG (hdfdlg)) == GTK_RESPONSE_ACCEPT) {
                   2373:        const char *failure;
                   2374:        const char *new_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (path_entry));
                   2375:        const char *bptstr = gtk_entry_get_text (GTK_ENTRY (bpt_entry));
                   2376:        const char *sfstr = gtk_entry_get_text (GTK_ENTRY (surfaces_entry));
                   2377:        const char *bsstr = gtk_entry_get_text (GTK_ENTRY (blocksize_entry));
                   2378:        const char *rsrvstr = gtk_entry_get_text (GTK_ENTRY (reserved_entry));
                   2379:        const char *bprstr = gtk_entry_get_text (GTK_ENTRY (pri_entry));
                   2380:        int n, sf, bpt, bs, rsrv, bpr;
                   2381: 
                   2382:        if (new_filename == NULL || strlen (new_filename) == 0) {
                   2383:            mkmsgbox ("Error", "You must enter a valid filename.");
                   2384:            goto retry;
                   2385:        }
                   2386: 
                   2387:        if (strlen (bptstr) == 0 || (bpt = atoi (bptstr)) == 0) {
                   2388:            mkmsgbox ("Error", "You must enter a valid number of blocks per track.");
                   2389:            goto retry;
                   2390:        }
                   2391:        if (strlen (rsrvstr) == 0) {
                   2392:            mkmsgbox ("Error", "You must enter the number of reserved blocks.");
                   2393:            goto retry;
                   2394:        }
                   2395:        rsrv = atoi (rsrvstr);
                   2396:        if (strlen (sfstr) == 0 || (sf = atoi (sfstr)) == 0) {
                   2397:            mkmsgbox ("Error", "You must enter a valid number of surfaces.");
                   2398:            goto retry;
                   2399:        }
                   2400:        if (strlen (bsstr) == 0 || (bs = atoi (bsstr)) == 0) {
                   2401:            mkmsgbox ("Error", "You must enter a valid number of surfaces.");
                   2402:            goto retry;
                   2403:        }
                   2404:        if (strlen (bprstr) == 0) {
                   2405:            mkmsgbox ("Error", "You must enter a valid number of surfaces.");
                   2406:            goto retry;
                   2407:        }
                   2408:        bpr = atoi (bprstr);
                   2409: 
                   2410:        if (row == -1) {
                   2411:            failure = add_filesys_unit (currprefs.mountinfo, NULL, NULL, new_filename,
                   2412:                                        readonly, bpt, sf, rsrv, bs, bpr);
                   2413:        } else {
                   2414:            failure = set_filesys_unit (currprefs.mountinfo, row, NULL, NULL, new_filename,
                   2415:                                        readonly, bpt, sf, rsrv, bs, bpr);
                   2416:        }
                   2417:        if (failure) {
                   2418:            mkmsgbox ("Error", failure);
                   2419:            goto retry;
                   2420:        }
                   2421:        set_hd_state ();
                   2422:     }
                   2423:   out:
                   2424:     gtk_widget_destroy (hdfdlg);
                   2425:     return;
                   2426: }
                   2427: 
                   2428: static void did_newdir (void)
                   2429: {
                   2430:     create_dirdlg ("Add a new mounted directory", -1);
                   2431: }
                   2432: 
                   2433: static void did_newhdf (void)
                   2434: {
                   2435:     create_hdfdlg ("Add a new hardfile", -1);
                   2436: }
                   2437: 
                   2438: static void did_newadf (void)
                   2439: {
                   2440:     make_disk_selector ();
                   2441: 
                   2442:     if (gtk_dialog_run (GTK_DIALOG (disk_selector)) == GTK_RESPONSE_ACCEPT) {
                   2443:        char *filename;
                   2444:        struct zfile *f;
                   2445:        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (disk_selector));
                   2446: 
                   2447:        f = zfile_open (filename, "rb");
                   2448:        if (f) {
                   2449:            const char *failure;
                   2450:            char buf[512];
                   2451:            long size;
                   2452:            zfile_fread (buf, 1, 512, f);
                   2453:            zfile_fseek (f, 0, SEEK_END);
                   2454:            size = zfile_ftell (f);
                   2455:            if (buf[0] != 'D' || buf[1] != 'O' || buf[2] != 'S'
                   2456:                || (buf[3] != 0 && buf[3] != 1)
                   2457:                || size != 901120)
                   2458:            {
                   2459:                mkmsgbox ("Error", "Not an ADF diskfile.");
                   2460:            } else {
                   2461:                failure = add_filesys_unit (currprefs.mountinfo, NULL, NULL, filename,
                   2462:                                            0, 11, 2, 2, 512, -2);
                   2463:                if (failure)
                   2464:                    mkmsgbox ("Error", failure);
                   2465:                else
                   2466:                    set_hd_state ();
                   2467:            }
                   2468:            zfile_fclose (f);
                   2469:        }
                   2470: 
                   2471:        g_free (filename);
                   2472:     }
                   2473: 
                   2474:     gtk_widget_hide (disk_selector);
                   2475: }
                   2476: 
                   2477: static void did_hdchange (void)
                   2478: {
                   2479:     GtkTreeIter iter;
                   2480:     GtkTreeModel *model;
                   2481:     int idx;
                   2482: 
                   2483:     if (gtk_tree_selection_get_selected (hd_selection, &model, &iter))
                   2484:        gtk_tree_model_get (model, &iter, 0, &idx, -1);
                   2485:     else
                   2486:        return;
                   2487: 
                   2488:     if (is_hardfile (currprefs.mountinfo, idx)) {
                   2489:        create_hdfdlg ("Change a hardfile", idx);
                   2490:     } else {
                   2491:        create_dirdlg ("Change a mounted directory", idx);
                   2492:    }
                   2493: }
                   2494: static void did_hddel (void)
                   2495: {
                   2496:     GtkTreeIter iter;
                   2497:     GtkTreeModel *model;
                   2498:     int idx;
                   2499: 
                   2500:     if (gtk_tree_selection_get_selected (hd_selection, &model, &iter))
                   2501:        gtk_tree_model_get (model, &iter, 0, &idx, -1);
                   2502:     else
                   2503:        return;
                   2504: 
                   2505:     kill_filesys_unit (currprefs.mountinfo, idx);
                   2506:     set_hd_state ();
                   2507: }
                   2508: 
                   2509: static void hdsel_changed (GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,
                   2510:                           gpointer user_data)
                   2511: {
                   2512:     GtkTreeIter iter;
                   2513:     GtkTreeModel *model;
                   2514: 
                   2515:     if (gtk_tree_selection_get_selected (hd_selection, &model, &iter)) {
                   2516:        gtk_widget_set_sensitive (hdchange_button, TRUE);
                   2517:        gtk_widget_set_sensitive (hddel_button, TRUE);
                   2518:     } else {
                   2519:        gtk_widget_set_sensitive (hdchange_button, FALSE);
                   2520:        gtk_widget_set_sensitive (hddel_button, FALSE);
                   2521:     }
                   2522: }
                   2523: 
                   2524: static void hdunselect (GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,
                   2525:                        gpointer user_data)
                   2526: {
                   2527:     gtk_widget_set_sensitive (hdchange_button, FALSE);
                   2528:     gtk_widget_set_sensitive (hddel_button, FALSE);
                   2529: }
                   2530: 
                   2531: static void preset_changed (GtkTreeSelection *selection, gpointer data)
                   2532: {
                   2533:     GtkTreeIter iter;
                   2534:     GtkTreeModel *model;
                   2535: 
                   2536:     if (gtk_tree_selection_get_selected (selection, &model, &iter))
                   2537:        gtk_widget_set_sensitive (preset_button, TRUE);
                   2538:     else
                   2539:        gtk_widget_set_sensitive (preset_button, FALSE);
                   2540: }
                   2541: 
                   2542: static void did_set_preset (void)
                   2543: {
                   2544:     GtkTreeIter iter;
                   2545:     GtkTreeModel *model;
                   2546:     gchar *filename;
                   2547: 
                   2548:     if (gtk_tree_selection_get_selected (preset_selection, &model, &iter)) {
                   2549:        gtk_tree_model_get (model, &iter, 1, &filename, -1);
                   2550: 
                   2551:        if (filename) {
                   2552:            cfgfile_load (&changed_prefs, filename);
                   2553:            set_widgets_from_config ();
                   2554:        }
                   2555:        g_free (filename);
                   2556:     }
                   2557: }
                   2558: 
                   2559: static GtkWidget *make_buttons_1 (const char *label, GtkWidget *box, void (*sigfunc) (void),
                   2560:                                  GtkWidget *(*create)(const char *label), int expand)
                   2561: {
                   2562:     GtkWidget *thing = create (label);
                   2563:     gtk_widget_show (thing);
                   2564:     gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
                   2565:     gtk_box_pack_start (GTK_BOX (box), thing, expand, expand, 0);
                   2566: 
                   2567:     return thing;
                   2568: }
                   2569: #define make_buttons(label, box, sigfunc, create) make_buttons_1(label, box, sigfunc, create, 1)
                   2570: #define make_button(label, box, sigfunc) make_buttons(label, box, sigfunc, gtk_button_new_with_label)
                   2571: 
                   2572: static void new_text_cell_renderer (GtkWidget *treeview, const char *title, int colnr,
                   2573:                                    int expand, int ellipsize)
                   2574: {
                   2575:     GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
                   2576:     GtkTreeViewColumn *column;
                   2577:     column = gtk_tree_view_column_new_with_attributes (title, renderer,
                   2578:                                                       "text", colnr, NULL);
                   2579:     gtk_tree_view_column_set_expand (column, expand);
                   2580:     gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
                   2581:     if (ellipsize)
                   2582:        g_object_set (renderer,
                   2583:                      "ellipsize", PANGO_ELLIPSIZE_START,
                   2584:                      "ellipsize-set", TRUE,
                   2585:                      NULL);
                   2586: }
                   2587: 
                   2588: static void make_hd_widgets (GtkWidget *dvbox)
                   2589: {
                   2590:     GtkCellRenderer *renderer;
                   2591:     GtkTreeViewColumn *column;
                   2592:     GtkAdjustment *adj;
                   2593:     GtkWidget *scrolled, *buttonbox, *vbox, *hbox;
                   2594:     int i;
                   2595: 
                   2596:     hd_store = gtk_list_store_new (11,
                   2597:                                   G_TYPE_INT,
                   2598:                                   G_TYPE_STRING, G_TYPE_STRING,
                   2599:                                   G_TYPE_BOOLEAN,
                   2600:                                   G_TYPE_STRING, G_TYPE_STRING,
                   2601:                                   G_TYPE_STRING, G_TYPE_STRING,
                   2602:                                   G_TYPE_STRING, G_TYPE_STRING,
                   2603:                                   G_TYPE_INT);
                   2604: 
                   2605: #if 0
                   2606:     add_empty_vbox (dvbox);
                   2607: #endif
                   2608: 
                   2609:     hbox = gtk_hbox_new (FALSE, 0);
                   2610:     gtk_box_pack_start (GTK_BOX (dvbox), hbox, TRUE, TRUE, 20);
                   2611:     gtk_widget_show (hbox);
                   2612: 
                   2613:     vbox = gtk_vbox_new (FALSE, 4);
                   2614:     gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
                   2615:     gtk_widget_show (vbox);
                   2616: 
                   2617:     hdlist_widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (hd_store));
                   2618: 
                   2619:     new_text_cell_renderer (hdlist_widget, "Volume", 1, 0, 0);
                   2620:     new_text_cell_renderer (hdlist_widget, "Path/File", 2, 1, 1);
                   2621:     
                   2622:     renderer = gtk_cell_renderer_toggle_new ();
                   2623:     column = gtk_tree_view_column_new_with_attributes ("R/O", renderer,
                   2624:                                                       "active", 3, NULL);
                   2625:     gtk_tree_view_column_set_expand (column, 0);
                   2626:     gtk_tree_view_append_column (GTK_TREE_VIEW (hdlist_widget), column);
                   2627: 
                   2628:     new_text_cell_renderer (hdlist_widget, "Heads", 4, 0, 0);
                   2629:     new_text_cell_renderer (hdlist_widget, "Cyl.", 5, 0, 0);
                   2630:     new_text_cell_renderer (hdlist_widget, "Sec.", 6, 0, 0);
                   2631:     new_text_cell_renderer (hdlist_widget, "Rsrvd", 7, 0, 0);
                   2632:     new_text_cell_renderer (hdlist_widget, "Size", 8, 0, 0);
                   2633:     new_text_cell_renderer (hdlist_widget, "Blksize", 9, 0, 0);
                   2634:     new_text_cell_renderer (hdlist_widget, "Pri", 10, 0, 0);
                   2635: 
                   2636:     gtk_widget_show (hdlist_widget);
                   2637: 
                   2638:     scrolled = gtk_scrolled_window_new (NULL, NULL);
                   2639:     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
                   2640:                                    GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
                   2641:     gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
                   2642:     gtk_widget_show (scrolled);
                   2643: 
                   2644:     gtk_container_add (GTK_CONTAINER (scrolled), hdlist_widget);
                   2645: 
                   2646:     hd_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (hdlist_widget));
                   2647:     gtk_tree_selection_set_mode (hd_selection, GTK_SELECTION_SINGLE);
                   2648:     g_signal_connect (G_OBJECT (hd_selection), "changed",
                   2649:                      G_CALLBACK (hdsel_changed), NULL);
                   2650: 
                   2651:     /* The buttons */
                   2652:     buttonbox = gtk_hbox_new (FALSE, 4);
                   2653:     gtk_widget_show (buttonbox);
                   2654:     gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, FALSE, 0);
                   2655:     make_button ("New filesystem...", buttonbox, did_newdir);
                   2656:     make_button ("New hardfile...", buttonbox, did_newhdf);
                   2657:     make_button ("Mount floppy as HD...", buttonbox, did_newadf);
                   2658: 
                   2659:     buttonbox = gtk_hbox_new (FALSE, 4);
                   2660:     gtk_widget_show (buttonbox);
                   2661:     gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, FALSE, 0);
                   2662:     hdchange_button = make_button ("Change...", buttonbox, did_hdchange);
                   2663:     hddel_button = make_button ("Delete", buttonbox, did_hddel);
                   2664: 
                   2665:     bootrom_widget = gtk_check_button_new_with_label ("Enable bootrom - needed for filesystem, Picasso96 and better mouse support;\ndisable only in case of (unlikely) compatibility issues");
                   2666:     add_centered_to_vbox (dvbox, bootrom_widget, 0);
                   2667:     gtk_widget_show (bootrom_widget);
                   2668:     gtk_signal_connect (GTK_OBJECT (bootrom_widget), "clicked",
                   2669:                        (GtkSignalFunc) bootrom_changed, NULL);
                   2670: #if 0
                   2671:     add_empty_vbox (dvbox);
                   2672: #endif
                   2673: }
                   2674: 
                   2675: static void make_presets (GtkWidget *dvbox)
                   2676: {
                   2677:     GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
                   2678:     GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
                   2679:     GtkTreeViewColumn *column;
                   2680:     GtkWidget *scrolled, *buttonbox, *vbox, *hbox;
                   2681:     int i;
                   2682: 
                   2683:     add_empty_vbox (dvbox);
                   2684: 
                   2685:     hbox = gtk_hbox_new (FALSE, 0);
                   2686:     gtk_box_pack_start (GTK_BOX (dvbox), hbox, TRUE, TRUE, 0);
                   2687:     gtk_widget_show (hbox);
                   2688: 
                   2689:     add_empty_vbox (hbox);
                   2690: 
                   2691:     vbox = gtk_vbox_new (FALSE, 4);
                   2692:     gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
                   2693:     gtk_widget_show (vbox);
                   2694: 
                   2695:     for (i = 0; i < n_predef_configs; i++) {
                   2696:        GtkTreeIter iter;
                   2697:        gtk_list_store_append (store, &iter);
                   2698: 
                   2699:        gtk_list_store_set (store, &iter,
                   2700:                            0, predef_configs[i].description,
                   2701:                            1, predef_configs[i].filename,
                   2702:                            -1);
                   2703:     }
                   2704:     preset_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
                   2705:     gtk_widget_show (preset_list);
                   2706: 
                   2707:     new_text_cell_renderer (preset_list, "Hardware configuration presets", 0, 1, 0);
                   2708: 
                   2709:     scrolled = gtk_scrolled_window_new (NULL, NULL);
                   2710:     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
                   2711:                                    GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
                   2712:     gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
                   2713:     gtk_widget_show (scrolled);
                   2714: 
                   2715:     gtk_container_add (GTK_CONTAINER (scrolled), preset_list);
                   2716: 
                   2717:     preset_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (preset_list));
                   2718:     gtk_tree_selection_set_mode (preset_selection, GTK_SELECTION_SINGLE);
                   2719:     g_signal_connect (G_OBJECT (preset_selection), "changed",
                   2720:                      G_CALLBACK (preset_changed),
                   2721:                      NULL);
                   2722: 
                   2723:     /* The buttons */
                   2724:     buttonbox = gtk_hbox_new (FALSE, 4);
                   2725:     gtk_widget_show (buttonbox);
                   2726:     gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, FALSE, 0);
                   2727:     preset_button = make_buttons_1 ("Set configuration to chosen preset", buttonbox, did_set_preset,
                   2728:                                    gtk_button_new_with_label, 0);
                   2729: 
                   2730:     add_empty_vbox (hbox);
                   2731: 
                   2732:     add_empty_vbox (dvbox);
                   2733: }
                   2734: 
                   2735: static void make_about_widgets (GtkWidget *dvbox)
                   2736: {
                   2737:     GtkWidget *lab_version;
                   2738:     GtkStyle *style;
                   2739:     GdkFont *font;
                   2740:     char t[20];
                   2741: 
                   2742:     add_empty_vbox (dvbox);
                   2743: 
                   2744:     sprintf (t, "%s %s", PACKAGE_NAME, PACKAGE_VERSION);
                   2745:     lab_version = gtk_label_new (t);
                   2746:     lab_info = gtk_label_new ("Choose your settings, then deselect the Pause button to start!");
                   2747: 
                   2748:     style = gtk_style_copy (GTK_WIDGET (lab_version)->style);
                   2749:     pango_font_description_free (style->font_desc);
                   2750:     style->font_desc = pango_font_description_from_string ("Sans 24");
                   2751:     gtk_widget_set_style (lab_version, style);
                   2752: 
                   2753:     add_centered_to_vbox (dvbox, lab_version, 0);
                   2754:     add_centered_to_vbox (dvbox, lab_info, 0);
                   2755:     gtk_widget_show (lab_version);
                   2756:     if (currprefs.start_gui == 1)
                   2757:        gtk_widget_show (lab_info);
                   2758: 
                   2759:     add_empty_vbox (dvbox);
                   2760: }
                   2761: 
                   2762: static void create_guidlg (void)
                   2763: {
                   2764:     GtkWidget *window;
                   2765:     GtkWidget *buttonbox, *vbox, *hbox;
                   2766:     GtkWidget *thing;
                   2767:     unsigned int i;
                   2768:     int argc = 1;
                   2769:     char *a[] = {"UAE"};
                   2770:     char **argv = a;
                   2771:     static const struct _pages {
                   2772:        const char *title;
                   2773:        void (*createfunc)(GtkWidget *);
                   2774:     } pages[] = {
                   2775:        /* ??? If this isn't the first page, there are errors in draw_led.  */
                   2776:        { "Floppies", make_floppy_disks },
                   2777:        { "ROM", make_rom_widgets },
                   2778:        { "RAM", make_ram_widgets },
                   2779:        { "CPU", make_cpu_widgets },
                   2780:        { "Graphics", make_gfx_widgets },
                   2781:        { "Chipset", make_chipset_widgets },
                   2782:        { "Sound", make_sound_widgets },
                   2783:        { "Input devices", make_joy_widgets },
                   2784:        { "Harddisks", make_hd_widgets },
                   2785:        { "Presets", make_presets },
                   2786:        { "About", make_about_widgets }
                   2787:     };
                   2788: 
                   2789:     gtk_init (&argc, &argv);
                   2790:     gtk_rc_parse ("uaegtkrc");
                   2791: 
                   2792:     gui_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
                   2793:     gtk_window_set_title (GTK_WINDOW (gui_window), "UAE control");
                   2794: 
                   2795:     gtk_signal_connect (GTK_OBJECT (gui_window), "delete_event",
                   2796:                        GTK_SIGNAL_FUNC (gui_delete_event), NULL);
                   2797: 
                   2798:     vbox = gtk_vbox_new (FALSE, 4);
                   2799:     gtk_container_add (GTK_CONTAINER (gui_window), vbox);
                   2800:     gtk_container_set_border_width (GTK_CONTAINER (gui_window), 10);
                   2801: 
                   2802:     /* First line - buttons and power LED */
                   2803:     hbox = gtk_hbox_new (FALSE, 10);
                   2804:     gtk_widget_show (hbox);
                   2805:     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
                   2806: 
                   2807:     /* The buttons */
                   2808:     buttonbox = gtk_hbox_new (TRUE, 4);
                   2809:     gtk_widget_show (buttonbox);
                   2810:     gtk_box_pack_start (GTK_BOX (hbox), buttonbox, TRUE, TRUE, 0);
                   2811:     make_button ("Reset", buttonbox, did_reset);
                   2812:     make_button ("Debug", buttonbox, did_debug);
                   2813:     make_button ("Quit", buttonbox, did_quit);
                   2814:     make_button ("Save config", buttonbox, save_config);
                   2815:     pause_uae_widget = make_buttons ("Pause", buttonbox, pause_uae, gtk_toggle_button_new_with_label);
                   2816: 
                   2817:     /* The LED */
                   2818:     thing = make_led (0);
                   2819:     thing = make_labelled_widget ("Power:", thing, FALSE);
                   2820:     gtk_widget_show (thing);
                   2821:     gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, TRUE, 0);
                   2822: 
                   2823:     /* More buttons */
                   2824:     buttonbox = gtk_hbox_new (TRUE, 4);
                   2825:     gtk_widget_show (buttonbox);
                   2826:     gtk_box_pack_start (GTK_BOX (vbox), buttonbox, TRUE, TRUE, 0);
                   2827:     snap_save_widget = make_button ("Save state", buttonbox, did_savestate);
                   2828:     snap_load_widget = make_button ("Load state", buttonbox, did_loadstate);
                   2829: 
                   2830:     /* Place a separator below those buttons.  */
                   2831:     thing = gtk_hseparator_new ();
                   2832:     gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
                   2833:     gtk_widget_show (thing);
                   2834: 
                   2835:     /* Now the notebook */
                   2836:     notebook = gtk_notebook_new ();
                   2837:     gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
                   2838:     gtk_widget_show (notebook);
                   2839: 
                   2840:     for (i = 0; i < sizeof pages / sizeof (struct _pages); i++) {
                   2841:        thing = gtk_vbox_new (FALSE, 4);
                   2842:        gtk_widget_show (thing);
                   2843:        gtk_container_set_border_width (GTK_CONTAINER (thing), 10);
                   2844:        pages[i].createfunc (thing);
                   2845:        gtk_notebook_append_page (GTK_NOTEBOOK (notebook), thing, gtk_label_new (pages[i].title));
                   2846:     }
                   2847: 
                   2848:     /* Put "about" screen first.  */
                   2849:     gtk_notebook_set_page (GTK_NOTEBOOK (notebook), i - 1);
                   2850:     enable_disk_buttons (1);
                   2851: 
                   2852:     gtk_widget_show (vbox);
                   2853: 
                   2854:     gtk_timeout_add (1000, (GtkFunction)my_idle, 0);
                   2855: }
                   2856: 
                   2857: static void *gtk_gui_thread (void *dummy)
                   2858: {
                   2859:     gui_available = 1;
                   2860:     gtk_main ();
                   2861: 
                   2862:     gui_available = 0;
                   2863:     uae_sem_post (&gui_quit_sem);
                   2864:     return 0;
                   2865: }
                   2866: 
                   2867: void gui_fps (int x)
                   2868: {
                   2869: }
                   2870: 
                   2871: void gui_display (int shortcut)
                   2872: {
                   2873:     if (shortcut == -1 && !gui_available) {
                   2874:        gui_init (0);
                   2875:     }
                   2876: }
                   2877: 
                   2878: void gui_led (int num, int on)
                   2879: {
                   2880:     if (no_gui)
                   2881:        return;
                   2882: 
                   2883: /*    if (num == 0)
                   2884:        return;
                   2885:     printf("LED %d %d\n", num, on);
                   2886:     write_comm_pipe_int (&to_gui_pipe, 1, 0);
                   2887:     write_comm_pipe_int (&to_gui_pipe, num == 0 ? 4 : num - 1, 0);
                   2888:     write_comm_pipe_int (&to_gui_pipe, on, 1);
                   2889:     printf("#LED %d %d\n", num, on);*/
                   2890: }
                   2891: 
                   2892: void gui_filename (int num, const char *name)
                   2893: {
                   2894:     if (no_gui)
                   2895:        return;
                   2896: 
                   2897:     write_comm_pipe_int (&to_gui_pipe, GUICMD_DISKCHANGE, 0);
                   2898:     write_comm_pipe_int (&to_gui_pipe, num, 1);
                   2899: 
                   2900: /*    gui_update ();*/
                   2901: }
                   2902: 
                   2903: void gui_handle_events (void)
                   2904: {
                   2905:     int pause_uae = FALSE;
                   2906: 
                   2907:     if (no_gui)
                   2908:        return;
                   2909: 
                   2910:     do {
                   2911:        while (pause_uae || comm_pipe_has_data (&from_gui_pipe)) {
                   2912:            int cmd = read_comm_pipe_int_blocking (&from_gui_pipe);
                   2913:            int n;
                   2914:            switch (cmd) {
                   2915:            case 0:
                   2916:                n = read_comm_pipe_int_blocking (&from_gui_pipe);
                   2917:                changed_prefs.df[n][0] = '\0';
                   2918:                break;
                   2919:            case 1:
                   2920:                n = read_comm_pipe_int_blocking (&from_gui_pipe);
                   2921:                uae_sem_wait (&gui_sem);
                   2922:                strncpy (changed_prefs.df[n], new_disk_string[n], 255);
                   2923:                free (new_disk_string[n]);
                   2924:                new_disk_string[n] = 0;
                   2925:                changed_prefs.df[n][255] = '\0';
                   2926:                uae_sem_post (&gui_sem);
                   2927:                break;
                   2928:            case 2:
                   2929:                uae_reset (1);
                   2930:                end_pause_uae ();
                   2931:                break;
                   2932:            case 3:
                   2933:                activate_debugger ();
                   2934:                end_pause_uae ();
                   2935:                break;
                   2936:            case 4:
                   2937:                uae_quit ();
                   2938:                end_pause_uae ();
                   2939:                break;
                   2940:            case 5:
                   2941:                pause_uae = TRUE;
                   2942:                break;
                   2943:            case 6:
                   2944:                pause_uae = FALSE;
                   2945:                break;
                   2946:            case 7:
                   2947:                printf ("STATESAVE\n");
                   2948:                savestate_state = read_comm_pipe_int_blocking (&from_gui_pipe);
                   2949:                uae_sem_wait (&gui_sem);
                   2950:                savestate_filename = gui_snapname;
                   2951:                uae_sem_post (&gui_sem);
                   2952:                break;
                   2953:            case 8:
                   2954:                uae_sem_wait (&gui_sem);
                   2955:                strncpy (changed_prefs.romfile, gui_romname, 255);
                   2956:                changed_prefs.romfile[255] = '\0';
                   2957:                free (gui_romname);
                   2958:                uae_sem_post (&gui_sem);
                   2959:                break;
                   2960:            case 9:
                   2961:                uae_sem_wait (&gui_sem);
                   2962:                strncpy (changed_prefs.keyfile, gui_keyname, 255);
                   2963:                changed_prefs.keyfile[255] = '\0';
                   2964:                free (gui_keyname);
                   2965:                uae_sem_post (&gui_sem);
                   2966:                break;
                   2967:            case 10:
                   2968:                uae_sem_wait (&gui_sem);
                   2969:                strncpy (changed_prefs.path_rom, gui_romname, 255);
                   2970:                changed_prefs.path_rom[255] = '\0';
                   2971:                free (gui_romname);
                   2972:                uae_sem_post (&gui_sem);
                   2973:                break;
                   2974:            case 11:
                   2975:                uae_sem_wait (&gui_sem);
                   2976:                changed_prefs.gfx_w = gfx_w;
                   2977:                changed_prefs.gfx_f = gfx_f;
                   2978:                uae_sem_post (&gui_sem);
                   2979:                break;
                   2980:            }
                   2981:        }
                   2982:     } while (pause_uae);
                   2983: }
                   2984: 
                   2985: void gui_update_gfx (void)
                   2986: {
                   2987:     if (no_gui)
                   2988:        return;
                   2989: 
                   2990:     write_comm_pipe_int (&to_gui_pipe, GUICMD_FULLSCREEN, 1);
                   2991: }
                   2992: 
                   2993: int gui_init (int at_start)
                   2994: {
                   2995:     uae_thread_id tid;
                   2996: 
                   2997:     if (gui_available)
                   2998:        return 0;
                   2999: 
                   3000:     if (at_start) {
                   3001:        init_comm_pipe (&to_gui_pipe, 20, 1);
                   3002:        init_comm_pipe (&from_gui_pipe, 20, 1);
                   3003:        uae_sem_init (&gui_sem, 0, 1);
                   3004:        uae_sem_init (&gui_init_sem, 0, 0);
                   3005:        uae_sem_init (&gui_quit_sem, 0, 0);
                   3006:     }
                   3007: 
                   3008:     create_guidlg ();
                   3009:     if (at_start)
                   3010:        uae_start_thread (gtk_gui_thread, NULL, &tid);
                   3011: 
                   3012:     gui_update ();
                   3013: 
                   3014:     if (at_start && currprefs.start_gui == 1) {
                   3015:        write_comm_pipe_int (&to_gui_pipe, GUICMD_PAUSE, 1);
                   3016:        write_comm_pipe_int (&from_gui_pipe, 5, 1);
                   3017:        /* Handle events until Pause is unchecked.  */
                   3018:        gui_handle_events ();
                   3019:        /* Quit requested?  */
                   3020:        if (quit_program == -1) {
                   3021:            gui_exit ();
                   3022:            return -2;
                   3023:        }
                   3024:     }
                   3025: 
                   3026:     return 1;
                   3027: }
                   3028: 
                   3029: int gui_update (void)
                   3030: {
                   3031:     if (!gui_available)
                   3032:        return 0;
                   3033: 
                   3034:     write_comm_pipe_int (&to_gui_pipe, GUICMD_UPDATE, 1);
                   3035:     uae_sem_wait (&gui_init_sem);
                   3036:     return 0;
                   3037: }
                   3038: 
                   3039: void gui_romlist_changed (void)
                   3040: {
                   3041:     if (!gui_available)
                   3042:        return;
                   3043: 
                   3044:     write_comm_pipe_int (&to_gui_pipe, GUICMD_NEW_ROMLIST, 1);
                   3045:     return;
                   3046: }
                   3047: 
                   3048: void gui_exit (void)
                   3049: {
                   3050:     if (!gui_available)
                   3051:        return;
                   3052: 
                   3053:     quit_gui = 1;
                   3054:     uae_sem_wait (&gui_quit_sem);
                   3055: }
                   3056: 
                   3057: void gui_lock (void)
                   3058: {
                   3059:     if (!gui_available)
                   3060:        return;
                   3061:     uae_sem_wait (&gui_sem);
                   3062: }
                   3063: 
                   3064: void gui_unlock (void)
                   3065: {
                   3066:     if (!gui_available)
                   3067:        return;
                   3068: 
                   3069:     uae_sem_post (&gui_sem);
                   3070: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.