Annotation of uae/src/gtkui.c, revision 1.1.1.3

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
1.1.1.2   root        7:  * Copyright 1998 Michael Krause
1.1       root        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 "config.h"
                     20: #include "options.h"
                     21: #include "uae.h"
                     22: #include "memory.h"
                     23: #include "custom.h"
                     24: #include "readcpu.h"
                     25: #include "gui.h"
                     26: #include "newcpu.h"
                     27: #include "threaddep/penguin.h"
1.1.1.2   root       28: #include "sounddep/sound.h"
1.1       root       29: 
                     30: #include <gtk/gtk.h>
                     31: 
                     32: static int gui_active;
                     33: 
                     34: static GtkWidget *disk_insert_widget[4], *disk_eject_widget[4], *disk_text_widget[4];
                     35: static char *new_disk_string[4];
                     36: 
                     37: static GtkAdjustment *cpuspeed_adj;
1.1.1.3 ! root       38: static GtkWidget *cpuspeed_widgets[4], *cpuspeed_scale;
1.1       root       39: static GtkWidget *cpu_widget[4], *a24m_widget, *ccpu_widget;
1.1.1.2   root       40: static GtkWidget *sound_widget[4], *sound_bits_widget[2], *sound_freq_widget[3], *sound_ch_widget[2];
1.1       root       41: 
                     42: static GtkAdjustment *framerate_adj;
                     43: static GtkWidget *bimm_widget, *b32_widget;
                     44: 
                     45: static GtkWidget *joy_widget[2][6];
                     46: 
                     47: static GtkWidget *led_widgets[5];
                     48: static GdkColor led_on[5], led_off[5];
                     49: static unsigned int prevledstate;
                     50: 
1.1.1.2   root       51: static smp_comm_pipe to_gui_pipe, from_gui_pipe;
                     52: static uae_sem_t gui_sem, gui_quit_sem; /* gui_sem protects the DFx fields */
                     53: 
                     54: static volatile int quit_gui = 0, quitted_gui = 0;
                     55: 
1.1       root       56: static void save_config (void)
                     57: {
                     58:     FILE *f;
                     59:     char tmp[257];
                     60: 
                     61:     /* Backup the options file.  */
                     62:     strcpy (tmp, optionsfile);
                     63:     strcat (tmp, "~");
                     64:     rename (optionsfile, tmp);
                     65: 
                     66:     f = fopen (optionsfile, "w");
                     67:     if (f == NULL) {
1.1.1.2   root       68:        fprintf (stderr, "Error saving options file!\n");
1.1       root       69:        return;
                     70:     }
                     71:     save_options (f);
                     72:     fclose (f);
                     73: }
                     74: 
                     75: static int nr_for_led (GtkWidget *led)
                     76: {
                     77:     int i;
                     78:     i = 0;
                     79:     while (led_widgets[i] != led)
                     80:        i++;
                     81:     return i;
                     82: }
                     83: 
                     84: static void enable_disk_buttons (int enable)
                     85: {
                     86:     int i;
                     87:     for (i = 0; i < 4; i++) {
                     88:        gtk_widget_set_sensitive (disk_insert_widget[i], enable);
                     89:        gtk_widget_set_sensitive (disk_eject_widget[i], enable);
                     90:     }
                     91: }
                     92: 
                     93: static void set_cpu_state (void)
                     94: {
                     95:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (a24m_widget), changed_prefs.address_space_24 != 0);
                     96:     gtk_widget_set_sensitive (a24m_widget, changed_prefs.cpu_level > 1);
                     97:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ccpu_widget), changed_prefs.cpu_compatible != 0);
                     98:     gtk_widget_set_sensitive (ccpu_widget, changed_prefs.cpu_level == 0);
1.1.1.3 ! root       99:     gtk_widget_set_sensitive (cpuspeed_scale, changed_prefs.m68k_speed > 0);
1.1       root      100: }
                    101: 
                    102: static void set_cpu_widget (void)
                    103: {
                    104:     int nr = changed_prefs.cpu_level;
                    105:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (cpu_widget[nr]), TRUE);
1.1.1.3 ! root      106:     nr = currprefs.m68k_speed + 1 < 3 ? currprefs.m68k_speed + 1 : 2;
        !           107:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (cpuspeed_widgets[nr]), TRUE);
1.1       root      108: }
                    109: 
                    110: static void set_gfx_state (void)
                    111: {
                    112:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (bimm_widget), currprefs.immediate_blits != 0);
                    113:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (b32_widget), currprefs.blits_32bit_enabled != 0);
                    114: }
                    115: 
1.1.1.2   root      116: static void set_sound_state (void)
                    117: {
                    118:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (sound_widget[currprefs.produce_sound]), 1);
                    119:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (sound_ch_widget[currprefs.stereo]), 1);
                    120:     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (sound_bits_widget[currprefs.sound_bits == 16]), 1);
                    121: }
                    122: 
1.1       root      123: static void set_joy_state (void)
                    124: {
                    125:     int j0t = changed_prefs.fake_joystick & 255;
                    126:     int j1t = (changed_prefs.fake_joystick >> 8) & 255;
                    127:     int i;
                    128: 
                    129:     if (j0t == j1t) {
                    130:        /* Can't happen */
                    131:        j0t++;
                    132:        j0t %= 6;
                    133:     }
                    134:     for (i = 0; i < 6; i++) {
                    135:        gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (joy_widget[0][i]), j0t == i);
                    136:        gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (joy_widget[1][i]), j1t == i);
                    137:        gtk_widget_set_sensitive (joy_widget[0][i], j1t != i);
                    138:        gtk_widget_set_sensitive (joy_widget[1][i], j0t != i);
                    139:     }
                    140: }
                    141: 
                    142: static void draw_led (int nr)
                    143: {
                    144:     GtkWidget *thing = led_widgets[nr];
                    145:     GdkWindow *window = thing->window;
                    146:     GdkGC *gc = gdk_gc_new (window);
                    147:     GdkColor *col;
                    148: 
                    149:     if (gui_ledstate & (1 << nr))
                    150:        col = led_on + nr;
                    151:     else
                    152:        col = led_off + nr;
                    153:     gdk_gc_set_foreground (gc, col);
                    154:     gdk_draw_rectangle (window, gc, 1, 0, 0, -1, -1);
                    155:     gdk_gc_destroy (gc);
                    156: }
                    157: 
                    158: static int my_idle (void)
                    159: {
                    160:     unsigned int leds = gui_ledstate;
                    161:     int i;
                    162: 
                    163:     if (quit_gui) {
                    164:        /*printf("Foo...\n");*/
                    165:        gtk_main_quit ();
                    166:        goto out;
                    167:     }
                    168:     while (comm_pipe_has_data (&to_gui_pipe)) {
                    169:        int cmd = read_comm_pipe_int_blocking (&to_gui_pipe);
                    170:        int n;
                    171:        /*printf ("cmd %d\n", cmd);*/
                    172:        switch (cmd) {
                    173:         case 0:
                    174:            n = read_comm_pipe_int_blocking (&to_gui_pipe);
                    175:            gtk_label_set (GTK_LABEL (disk_text_widget[n]), currprefs.df[n]);
                    176:            break;
                    177:         case 1:
                    178:            /* Initialization.  */
                    179:            set_cpu_widget ();
                    180:            set_cpu_state ();
                    181:            set_gfx_state ();
                    182:            set_joy_state ();
1.1.1.2   root      183:            set_sound_state ();
1.1.1.3 ! root      184: 
1.1       root      185:            gui_active = 1;
                    186:            break;
                    187:        }
                    188:     }
                    189:     
                    190:     for (i = 0; i < 5; i++) {
                    191:        unsigned int mask = 1 << i;
1.1.1.2   root      192:        unsigned int on = leds & mask;
1.1       root      193: 
                    194:        if (on == (prevledstate & mask))
                    195:            continue;
                    196: 
                    197: /*     printf(": %d %d\n", i, on);*/
                    198:        draw_led (i);
                    199:     }
                    200:     prevledstate = leds;
                    201: out:
                    202:     return 1;
                    203: }
                    204: 
1.1.1.2   root      205: static int find_current_toggle (GtkWidget **widgets, int count)
                    206: {
                    207:     int i;
                    208:     for (i = 0; i < count; i++)
                    209:        if (GTK_TOGGLE_BUTTON (*widgets++)->active)
                    210:            return i;
                    211:     fprintf (stderr, "GTKUI: Can't happen!\n");
                    212:     return -1;
                    213: }
                    214: 
1.1       root      215: static void joy_changed (void)
                    216: {
                    217:     int j0t = 0, j1t = 0;
                    218:     int i;
                    219:     if (! gui_active)
                    220:        return;
                    221: 
1.1.1.2   root      222:     j0t = find_current_toggle (joy_widget[0], 6);
                    223:     j1t = find_current_toggle (joy_widget[1], 6);
                    224: 
1.1       root      225:     changed_prefs.fake_joystick = j0t | (j1t << 8);
                    226:     set_joy_state ();
                    227: }
                    228: 
1.1.1.2   root      229: static void custom_changed (void)
1.1       root      230: {
                    231:     changed_prefs.framerate = framerate_adj->value;
                    232:     changed_prefs.blits_32bit_enabled = GTK_TOGGLE_BUTTON (b32_widget)->active;
                    233:     changed_prefs.immediate_blits = GTK_TOGGLE_BUTTON (bimm_widget)->active;
                    234: }
                    235: 
                    236: static void cpuspeed_changed (void)
                    237: {
1.1.1.3 ! root      238:     int which = find_current_toggle (cpuspeed_widgets, 3);
        !           239:     changed_prefs.m68k_speed = (which == 0 ? -1
        !           240:                                : which == 1 ? 0
        !           241:                                : cpuspeed_adj->value);
        !           242:     set_cpu_state ();
1.1       root      243: }
                    244: 
                    245: static void cputype_changed (void)
                    246: {
                    247:     int i, oldcl;
                    248:     if (! gui_active)
                    249:        return;
                    250: 
                    251:     oldcl = changed_prefs.cpu_level;
                    252: 
1.1.1.3 ! root      253:     changed_prefs.cpu_level = find_current_toggle (cpu_widget, 4);
1.1       root      254:     changed_prefs.cpu_compatible = GTK_TOGGLE_BUTTON (ccpu_widget)->active;
                    255:     changed_prefs.address_space_24 = GTK_TOGGLE_BUTTON (a24m_widget)->active;
                    256: 
                    257:     if (changed_prefs.cpu_level != 0)
                    258:        changed_prefs.cpu_compatible = 0;
                    259:     /* 68000/68010 always have a 24 bit address space.  */
                    260:     if (changed_prefs.cpu_level < 2)
                    261:        changed_prefs.address_space_24 = 1;
                    262:     /* Changing from 68000/68010 to 68020 should set a sane default.  */
                    263:     else if (oldcl < 2)
                    264:        changed_prefs.address_space_24 = 0;
                    265:     
                    266:     set_cpu_state ();
                    267: }
                    268: 
1.1.1.2   root      269: static void sound_changed (void)
                    270: {
                    271:     changed_prefs.produce_sound = find_current_toggle (sound_widget, 4);
                    272:     changed_prefs.stereo = find_current_toggle (sound_ch_widget, 2);
                    273:     changed_prefs.sound_bits = (find_current_toggle (sound_bits_widget, 2) + 1) * 8;
                    274: }
                    275: 
1.1       root      276: static void did_reset (void)
                    277: {
                    278:     if (quit_gui)
                    279:        return;
                    280:     
                    281:     write_comm_pipe_int (&from_gui_pipe, 2, 1);
                    282: }
                    283: 
                    284: static void did_debug (void)
                    285: {
                    286:     if (quit_gui)
                    287:        return;
                    288:     
                    289:     write_comm_pipe_int (&from_gui_pipe, 3, 1);
                    290: }
                    291: 
                    292: static void did_quit (void)
                    293: {
                    294:     if (quit_gui)
                    295:        return;
                    296:     
                    297:     write_comm_pipe_int (&from_gui_pipe, 4, 1);
                    298: }
                    299: 
1.1.1.2   root      300: static void did_eject (GtkWidget *w, gpointer data)
                    301: {
1.1       root      302:     if (quit_gui)
                    303:        return;
                    304:     
                    305:     write_comm_pipe_int (&from_gui_pipe, 0, 0);
1.1.1.2   root      306:     write_comm_pipe_int (&from_gui_pipe, (int)data, 1);
1.1       root      307: }
                    308: 
                    309: static int filesel_active = -1;
                    310: static GtkWidget *selector;
                    311: 
                    312: static void did_close_insert (GtkObject *o, GtkWidget *w)
                    313: {
                    314:     filesel_active = -1;
                    315:     enable_disk_buttons (1);
                    316:     gtk_widget_hide (selector);
                    317: }
                    318: 
                    319: static void did_cancel_insert (GtkObject *o)
                    320: {
                    321:     filesel_active = -1;
                    322:     enable_disk_buttons (1);
                    323:     gtk_widget_hide (selector);
                    324: }
                    325: 
                    326: static void did_insert_select (GtkObject *o)
                    327: {
                    328:     char *s = gtk_file_selection_get_filename (GTK_FILE_SELECTION (selector));
                    329:     printf ("%s\n", s);
                    330:     if (quit_gui)
                    331:        return;
                    332: 
                    333:     uae_sem_wait (&gui_sem);
                    334:     if (new_disk_string[filesel_active] != 0)
                    335:        free (new_disk_string[filesel_active]);
                    336:     new_disk_string[filesel_active] = strdup (s);
                    337:     uae_sem_post (&gui_sem);
                    338:     write_comm_pipe_int (&from_gui_pipe, 1, 0);
                    339:     write_comm_pipe_int (&from_gui_pipe, filesel_active, 1);
                    340:     filesel_active = -1;
                    341:     enable_disk_buttons (1);
                    342:     gtk_widget_hide (selector);
                    343: }
                    344: 
                    345: static char fsbuffer[100];
                    346: 
1.1.1.2   root      347: static void did_insert (GtkWidget *w, gpointer data)
1.1       root      348: {
1.1.1.2   root      349:     int n = (int)data;
1.1       root      350:     if (filesel_active != -1)
                    351:        return;
                    352:     filesel_active = n;
                    353:     enable_disk_buttons (0);
                    354: 
                    355:     sprintf (fsbuffer, "Select a disk image file for DF%d", n);
                    356:     gtk_window_set_title (GTK_WINDOW (selector), fsbuffer);
                    357: 
                    358:     /*printf("%p\n", selector);*/
                    359:     gtk_widget_show (selector);
                    360: }
                    361: 
                    362: static gint driveled_event (GtkWidget *thing, GdkEvent *event)
                    363: {
                    364:     int lednr = nr_for_led (thing);
                    365: 
                    366:     switch (event->type) {
                    367:      case GDK_MAP:
                    368:        draw_led (lednr);
                    369:        break;
                    370:      case GDK_EXPOSE:
                    371:        draw_led (lednr);
                    372:        break;
                    373:      default:
                    374:        break;
                    375:     }
                    376: 
                    377:   return 0;
                    378: }
                    379: 
1.1.1.2   root      380: static void add_empty_vbox (GtkWidget *tobox)
                    381: {
                    382:     GtkWidget *thing = gtk_vbox_new (FALSE, 0);
                    383:     gtk_widget_show (thing);
                    384:     gtk_box_pack_start (GTK_BOX (tobox), thing, TRUE, TRUE, 0);
                    385: }
                    386: 
1.1.1.3 ! root      387: static void add_empty_hbox (GtkWidget *tobox)
        !           388: {
        !           389:     GtkWidget *thing = gtk_hbox_new (FALSE, 0);
        !           390:     gtk_widget_show (thing);
        !           391:     gtk_box_pack_start (GTK_BOX (tobox), thing, TRUE, TRUE, 0);
        !           392: }
        !           393: 
1.1.1.2   root      394: static void add_centered_to_vbox (GtkWidget *vbox, GtkWidget *w)
                    395: {
                    396:     GtkWidget *hbox = gtk_hbox_new (TRUE, 0);
                    397:     gtk_widget_show (hbox);
                    398:     gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, FALSE, 0);
                    399:     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
                    400: }
                    401: 
                    402: static GtkWidget *make_labelled_widget (const char *str, GtkWidget *thing)
                    403: {
                    404:     GtkWidget *label = gtk_label_new (str);
                    405:     GtkWidget *hbox2 = gtk_hbox_new (FALSE, 4);
                    406: 
                    407:     gtk_widget_show (label);
                    408:     gtk_widget_show (thing);
                    409: 
                    410:     gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
                    411:     gtk_box_pack_start (GTK_BOX (hbox2), thing, FALSE, TRUE, 0);
                    412: 
                    413:     return hbox2;
                    414: }
                    415: 
1.1.1.3 ! root      416: static GtkWidget *add_labelled_widget_centered (const char *str, GtkWidget *thing, GtkWidget *vbox)
1.1.1.2   root      417: {
                    418:     GtkWidget *w = make_labelled_widget (str, thing);
                    419:     gtk_widget_show (w);
                    420:     add_centered_to_vbox (vbox, w);
1.1.1.3 ! root      421:     return w;
1.1.1.2   root      422: }
                    423: 
                    424: static void make_radio_group (const char **labels, GtkWidget *tobox,
                    425:                              GtkWidget **saveptr, gint t1, gint t2,
                    426:                              void (*sigfunc) (void))
                    427: {
                    428:     GtkWidget *thing = NULL;
                    429: 
                    430:     while (*labels) {
                    431:        thing = gtk_radio_button_new_with_label ((thing
                    432:                                                  ? gtk_radio_button_group (GTK_RADIO_BUTTON (thing))
                    433:                                                  : 0),
                    434:                                                 *labels++);
                    435:        *saveptr++ = thing;
                    436:        gtk_widget_show (thing);
                    437:        gtk_box_pack_start (GTK_BOX (tobox), thing, t1, t2, 0);
                    438:        gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
                    439:     }
                    440: }
                    441: 
                    442: static GtkWidget *make_radio_group_box (const char *title, const char **labels,
                    443:                                        GtkWidget **saveptr, int horiz,
                    444:                                        void (*sigfunc) (void))
                    445: {
                    446:     GtkWidget *frame, *newbox;
                    447: 
                    448:     frame = gtk_frame_new (title);
                    449:     newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (FALSE, 4);
                    450:     gtk_widget_show (newbox);
                    451:     gtk_container_border_width (GTK_CONTAINER (newbox), 4);
                    452:     gtk_container_add (GTK_CONTAINER (frame), newbox);
                    453:     make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc);
                    454:     return frame;
                    455: }
                    456: 
1.1       root      457: static GtkWidget *make_led (int nr)
                    458: {
                    459:     GtkWidget *subframe, *the_led, *thing;
                    460:     GdkColormap *colormap;
                    461: 
                    462:     the_led = gtk_vbox_new (FALSE, 0);
                    463:     gtk_widget_show (the_led);
                    464: 
                    465:     thing = gtk_preview_new (GTK_PREVIEW_COLOR);
                    466:     gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
                    467:     gtk_widget_show (thing);
                    468: 
                    469:     subframe = gtk_frame_new (NULL);
                    470:     gtk_box_pack_start (GTK_BOX (the_led), subframe, TRUE, TRUE, 0);
                    471:     gtk_widget_show (subframe);
                    472: 
                    473:     thing = gtk_drawing_area_new ();
                    474:     gtk_drawing_area_size (GTK_DRAWING_AREA (thing), 20, 5);
                    475:     gtk_widget_set_events (thing, GDK_EXPOSURE_MASK);
                    476:     gtk_container_add (GTK_CONTAINER (subframe), thing);
                    477:     colormap = gtk_widget_get_colormap (thing);
                    478:     led_on[nr].red = nr == 0 ? 0xEEEE : 0xCCCC;
                    479:     led_on[nr].green = nr == 0 ? 0: 0xFFFF;
                    480:     led_on[nr].blue = 0;
                    481:     led_on[nr].pixel = 0;
                    482:     led_off[nr].red = 0;
                    483:     led_off[nr].green = 0;
                    484:     led_off[nr].blue = 0;
                    485:     led_off[nr].pixel = 0;
                    486:     gdk_color_alloc (colormap, led_on + nr);
                    487:     gdk_color_alloc (colormap, led_off + nr);
                    488:     led_widgets[nr] = thing;
                    489:     gtk_signal_connect (GTK_OBJECT (thing), "event",
                    490:                        (GtkSignalFunc) driveled_event, (gpointer) thing);
                    491:     gtk_widget_show (thing);
                    492: 
                    493:     thing = gtk_preview_new (GTK_PREVIEW_COLOR);
                    494:     gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
                    495:     gtk_widget_show (thing);
                    496:     
                    497:     return the_led;
                    498: }
                    499: 
                    500: static void make_floppy_disks (GtkWidget *vbox)
                    501: {
1.1.1.2   root      502:     GtkWidget *thing, *subthing, *subframe, *buttonbox;
                    503:     char buf[5];
1.1       root      504:     int i;
1.1.1.2   root      505: 
                    506:     add_empty_vbox (vbox);
                    507: 
1.1       root      508:     for (i = 0; i < 4; i++) {
1.1.1.2   root      509:        /* Frame with an hbox and the "DFx:" title */
1.1       root      510:        sprintf (buf, "DF%d:", i);
1.1.1.2   root      511:        thing = gtk_frame_new (buf);
                    512:        buttonbox = gtk_hbox_new (FALSE, 4);
                    513:        gtk_container_border_width (GTK_CONTAINER (buttonbox), 4);
                    514:        gtk_container_add (GTK_CONTAINER (thing), buttonbox);
                    515:         gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
1.1       root      516:        gtk_widget_show (buttonbox);
                    517:        gtk_widget_show (thing);
                    518: 
1.1.1.2   root      519:        /* LED */
1.1       root      520:        subthing = make_led (i + 1);
                    521:        gtk_box_pack_start (GTK_BOX (buttonbox), subthing, FALSE, TRUE, 0);
                    522: 
1.1.1.2   root      523:        /* Current file display */
1.1       root      524:        subframe = gtk_frame_new (NULL);
                    525:        gtk_frame_set_shadow_type (GTK_FRAME (subframe), GTK_SHADOW_ETCHED_OUT);
1.1.1.2   root      526:        gtk_box_pack_start (GTK_BOX (buttonbox), subframe, TRUE, TRUE, 0);
1.1       root      527:        gtk_widget_show (subframe);
                    528:        subthing = gtk_vbox_new (FALSE, 0);
                    529:        gtk_widget_show (subthing);
                    530:        gtk_container_add (GTK_CONTAINER (subframe), subthing);
                    531:        thing = gtk_label_new ("");
                    532:        disk_text_widget[i] = thing;
                    533:        gtk_widget_show (thing);
1.1.1.2   root      534:        gtk_box_pack_start (GTK_BOX (subthing), thing, TRUE, TRUE, 0);
1.1       root      535: 
                    536:        /* Now, the buttons.  */
                    537:        thing = gtk_button_new_with_label ("Eject");
                    538:        gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
                    539:        gtk_widget_show (thing);
                    540:        disk_eject_widget[i] = thing;
1.1.1.2   root      541:        gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_eject, (gpointer) i);
1.1       root      542: 
                    543:        thing = gtk_button_new_with_label ("Insert");
                    544:        gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
                    545:        gtk_widget_show (thing);
                    546:        disk_insert_widget[i] = thing;
1.1.1.2   root      547:        gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_insert, (gpointer) i);
1.1       root      548:     }
1.1.1.2   root      549: 
                    550:     add_empty_vbox (vbox);
1.1       root      551: }
                    552: 
1.1.1.3 ! root      553: static GtkWidget *make_cpu_speed_sel (void)
        !           554: {
        !           555:     static const char *labels[] = {
        !           556:        "Optimize for host CPU speed","Approximate 68000/7MHz speed", "Adjustable",
        !           557:        NULL
        !           558:     };
        !           559:     GtkWidget *frame, *newbox;
        !           560: 
        !           561:     frame = gtk_frame_new ("CPU speed");
        !           562:     newbox = gtk_vbox_new (FALSE, 4);
        !           563:     gtk_widget_show (newbox);
        !           564:     gtk_container_border_width (GTK_CONTAINER (newbox), 4);
        !           565:     gtk_container_add (GTK_CONTAINER (frame), newbox);
        !           566:     make_radio_group (labels, newbox, cpuspeed_widgets, 0, 1, cpuspeed_changed);
        !           567: 
        !           568:     cpuspeed_adj = GTK_ADJUSTMENT (gtk_adjustment_new (currprefs.m68k_speed, 1.0, 10.0, 1.0, 1.0, 1.0));
        !           569:     gtk_signal_connect (GTK_OBJECT (cpuspeed_adj), "value_changed",
        !           570:                        GTK_SIGNAL_FUNC (cpuspeed_changed), NULL);
        !           571: 
        !           572:     cpuspeed_scale = gtk_hscale_new (cpuspeed_adj);
        !           573:     gtk_range_set_update_policy (GTK_RANGE (cpuspeed_scale), GTK_UPDATE_DELAYED);
        !           574:     gtk_scale_set_digits (GTK_SCALE (cpuspeed_scale), 0);
        !           575:     gtk_scale_set_value_pos (GTK_SCALE (cpuspeed_scale), GTK_POS_RIGHT);
        !           576:     cpuspeed_scale = add_labelled_widget_centered ("Cycles per instruction:", cpuspeed_scale, newbox);
        !           577: 
        !           578:     return frame;
        !           579: }
        !           580: 
1.1.1.2   root      581: static void make_cpu_widgets (GtkWidget *vbox)
1.1       root      582: {
                    583:     int i;
1.1.1.3 ! root      584:     GtkWidget *newbox, *hbox, *frame;
1.1       root      585:     GtkWidget *thing;
1.1.1.2   root      586:     static const char *radiolabels[] = {
                    587:        "68000", "68010", "68020", "68020+68881",
                    588:        NULL
                    589:     };
                    590: 
                    591:     add_empty_vbox (vbox);
                    592: 
1.1.1.3 ! root      593:     hbox = gtk_hbox_new (FALSE, 0);
        !           594:     add_empty_vbox (hbox);
        !           595: 
        !           596:     newbox = make_radio_group_box ("CPU type", radiolabels, cpu_widget, 0, cputype_changed);
1.1.1.2   root      597:     gtk_widget_show (newbox);
1.1.1.3 ! root      598:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
        !           599: 
        !           600:     newbox = make_cpu_speed_sel ();
        !           601:     gtk_widget_show (newbox);
        !           602:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
        !           603: 
        !           604:     add_empty_vbox (hbox);
        !           605:     gtk_widget_show (hbox); 
        !           606:     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1.1       root      607: 
                    608:     frame = gtk_frame_new ("CPU flags");
1.1.1.2   root      609:     add_centered_to_vbox (vbox, frame);
1.1       root      610:     gtk_widget_show (frame);
1.1.1.2   root      611:     newbox = gtk_vbox_new (FALSE, 4);
                    612:     gtk_widget_show (newbox);
                    613:     gtk_container_border_width (GTK_CONTAINER (newbox), 4);
                    614:     gtk_container_add (GTK_CONTAINER (frame), newbox);
1.1       root      615: 
                    616:     a24m_widget = gtk_check_button_new_with_label ("24 bit address space");
1.1.1.2   root      617:     add_centered_to_vbox (newbox, a24m_widget);
1.1       root      618:     gtk_widget_show (a24m_widget);
                    619:     ccpu_widget = gtk_check_button_new_with_label ("Slow but compatible");
1.1.1.2   root      620:     add_centered_to_vbox (newbox, ccpu_widget);
1.1       root      621:     gtk_widget_show (ccpu_widget);
1.1.1.3 ! root      622:     
1.1.1.2   root      623:     add_empty_vbox (vbox);
                    624: 
1.1       root      625:     gtk_signal_connect (GTK_OBJECT (ccpu_widget), "clicked",
                    626:                        (GtkSignalFunc) cputype_changed, NULL);
                    627:     gtk_signal_connect (GTK_OBJECT (a24m_widget), "clicked",
                    628:                        (GtkSignalFunc) cputype_changed, NULL);    
                    629: }
                    630: 
1.1.1.2   root      631: static void make_gfx_widgets (GtkWidget *vbox)
1.1       root      632: {
                    633:     GtkWidget *thing;
                    634: 
1.1.1.2   root      635:     add_empty_vbox (vbox);
1.1       root      636: 
                    637:     framerate_adj = GTK_ADJUSTMENT (gtk_adjustment_new (currprefs.framerate, 1.0, 21.0, 1.0, 1.0, 1.0));
                    638:     gtk_signal_connect (GTK_OBJECT (framerate_adj), "value_changed",
1.1.1.2   root      639:                        GTK_SIGNAL_FUNC (custom_changed), NULL);
1.1       root      640: 
                    641:     thing = gtk_hscale_new (framerate_adj);
                    642:     gtk_range_set_update_policy (GTK_RANGE (thing), GTK_UPDATE_DELAYED);
                    643:     gtk_scale_set_digits (GTK_SCALE (thing), 0);
                    644:     gtk_scale_set_value_pos (GTK_SCALE (thing), GTK_POS_RIGHT);
1.1.1.2   root      645:     add_labelled_widget_centered ("Framerate:", thing, vbox);
1.1       root      646: 
                    647:     b32_widget = gtk_check_button_new_with_label ("32 bit blitter");
1.1.1.2   root      648:     add_centered_to_vbox (vbox, b32_widget);
1.1       root      649:     gtk_widget_show (b32_widget);
1.1.1.2   root      650: 
1.1       root      651:     bimm_widget = gtk_check_button_new_with_label ("Immediate blits");
1.1.1.2   root      652:     add_centered_to_vbox (vbox, bimm_widget);
1.1       root      653:     gtk_widget_show (bimm_widget);
                    654: 
1.1.1.2   root      655:     add_empty_vbox (vbox);
                    656: 
1.1       root      657:     gtk_signal_connect (GTK_OBJECT (bimm_widget), "clicked",
1.1.1.2   root      658:                        (GtkSignalFunc) custom_changed, NULL);
1.1       root      659:     gtk_signal_connect (GTK_OBJECT (b32_widget), "clicked",
1.1.1.2   root      660:                        (GtkSignalFunc) custom_changed, NULL);
                    661: }
                    662: 
                    663: static void make_sound_widgets (GtkWidget *vbox)
                    664: {
                    665:     GtkWidget *frame, *newbox;
                    666:     int i;
                    667:     GtkWidget *hbox;
                    668:     static const char *soundlabels1[] = {
                    669:        "None", "No output", "Normal", "Accurate",
                    670:        NULL
                    671:     }, *soundlabels2[] = {
                    672:        "8 bit", "16 bit",
                    673:        NULL
                    674:     }, *soundlabels3[] = {
                    675:        "Mono", "Stereo",
                    676:        NULL
                    677:     };
                    678: 
                    679:     add_empty_vbox (vbox);
                    680: 
                    681:     newbox = make_radio_group_box ("Mode", soundlabels1, sound_widget, 1, sound_changed);
                    682:     gtk_widget_show (newbox);
                    683:     add_centered_to_vbox (vbox, newbox);
                    684: 
                    685:     hbox = gtk_hbox_new (FALSE, 10);
                    686:     gtk_widget_show (hbox);
                    687:     add_centered_to_vbox (vbox, hbox);
                    688:     newbox = make_radio_group_box ("Channels", soundlabels3, sound_ch_widget, 1, sound_changed);
                    689:     gtk_widget_show (newbox);
                    690:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
                    691:     newbox = make_radio_group_box ("Resolution", soundlabels2, sound_bits_widget, 1, sound_changed);
                    692:     gtk_widget_show (newbox);
                    693:     gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
1.1.1.3 ! root      694: 
1.1.1.2   root      695:     add_empty_vbox (vbox);
1.1       root      696: }
                    697: 
1.1.1.2   root      698: static void make_joy_widgets (GtkWidget *dvbox)
1.1       root      699: {
                    700:     int i;
1.1.1.2   root      701:     GtkWidget *hbox = gtk_hbox_new (FALSE, 10);
                    702:     static const char *joylabels[] = {
                    703:        "Joystick 0", "Joystick 1", "Mouse", "Numeric pad",
                    704:        "Cursor keys/Right Ctrl", "T/F/H/B/Left Alt",
                    705:        NULL
                    706:     };
                    707: 
                    708:     add_empty_vbox (dvbox);
                    709:     gtk_widget_show (hbox);
                    710:     add_centered_to_vbox (dvbox, hbox);
1.1       root      711: 
                    712:     for (i = 0; i < 2; i++) {
                    713:        GtkWidget *vbox, *frame;
                    714:        GtkWidget *thing;
                    715:        char buffer[20];
                    716:        int j;
                    717: 
                    718:        sprintf (buffer, "Port %d", i);
1.1.1.2   root      719:        frame = make_radio_group_box (buffer, joylabels, joy_widget[i], 0, joy_changed);
1.1       root      720:        gtk_widget_show (frame);
1.1.1.2   root      721:        gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
1.1       root      722:     }
1.1.1.2   root      723: 
                    724:     add_empty_vbox (dvbox);
                    725: }
                    726: 
                    727: static void make_button (const char *label, GtkWidget *box, void (*sigfunc) (void))
                    728: {
                    729:     GtkWidget *thing = gtk_button_new_with_label (label);
                    730:     gtk_widget_show (thing);
                    731:     gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
                    732:     gtk_box_pack_start (GTK_BOX (box), thing, TRUE, TRUE, 0);
1.1       root      733: }
                    734: 
                    735: static void *gtk_penguin (void *dummy)
                    736: {
                    737:     GtkWidget *window, *notebook;
1.1.1.2   root      738:     GtkWidget *buttonbox, *vbox, *hbox;
1.1       root      739:     GtkWidget *thing;
                    740:     int i;
                    741:     int argc = 1;
                    742:     char *a[] = {"UAE"};
                    743:     char **argv = a;
1.1.1.2   root      744:     static const struct _pages {
                    745:        const char *title;
                    746:        void (*createfunc)(GtkWidget *);
                    747:     } pages[] = {
                    748:        { "Floppy disks", make_floppy_disks },
                    749:        { "CPU emulation", make_cpu_widgets },
                    750:        { "Graphics", make_gfx_widgets },
                    751:        { "Sound", make_sound_widgets },
                    752:        { "Game ports", make_joy_widgets }
                    753:     };
1.1       root      754: 
                    755:     gtk_init (&argc, &argv);
                    756:     gtk_rc_parse ("uaegtkrc");
                    757: 
                    758:     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1.1.1.2   root      759:     gtk_window_set_title (GTK_WINDOW (window), "UAE control");
1.1       root      760: 
                    761:     vbox = gtk_vbox_new (FALSE, 4);
                    762:     gtk_container_add (GTK_CONTAINER (window), vbox);
1.1.1.2   root      763:     gtk_container_border_width (GTK_CONTAINER (window), 10);
1.1       root      764: 
1.1.1.2   root      765:     /* First line - buttons and power LED */
                    766:     hbox = gtk_hbox_new (FALSE, 10);
                    767:     gtk_widget_show (hbox);
                    768:     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1.1       root      769: 
1.1.1.2   root      770:     /* The buttons */
                    771:     buttonbox = gtk_hbox_new (TRUE, 4);
1.1       root      772:     gtk_widget_show (buttonbox);
1.1.1.2   root      773:     gtk_box_pack_start (GTK_BOX (hbox), buttonbox, TRUE, TRUE, 0);
                    774:     make_button ("Reset", buttonbox, did_reset);
                    775:     make_button ("Debug", buttonbox, did_debug);
                    776:     make_button ("Quit", buttonbox, did_quit);
                    777:     make_button ("Save config", buttonbox, save_config);
1.1       root      778: 
1.1.1.2   root      779:     /* The LED */
                    780:     thing = make_led (0);
                    781:     thing = make_labelled_widget ("Power:", thing);
1.1       root      782:     gtk_widget_show (thing);
1.1.1.2   root      783:     gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, TRUE, 0);
1.1       root      784: 
1.1.1.2   root      785:     /* Place a separator below those buttons.  */
1.1       root      786:     thing = gtk_hseparator_new ();
                    787:     gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
                    788:     gtk_widget_show (thing);
                    789: 
1.1.1.2   root      790:     /* Now the notebook */
1.1       root      791:     notebook = gtk_notebook_new ();
1.1.1.2   root      792:     gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
1.1       root      793:     gtk_widget_show (notebook);
                    794: 
1.1.1.2   root      795:     for (i = 0; i < sizeof pages / sizeof (struct _pages); i++) {
                    796:        thing = gtk_vbox_new (FALSE, 4);
                    797:        gtk_widget_show (thing);
                    798:        gtk_container_border_width (GTK_CONTAINER (thing), 10);
                    799:        pages[i].createfunc (thing);
                    800:        gtk_notebook_append_page (GTK_NOTEBOOK (notebook), thing, gtk_label_new (pages[i].title));
                    801:     }
1.1       root      802: 
                    803:     enable_disk_buttons (1);
                    804: 
                    805:     gtk_widget_show (vbox);
                    806:     gtk_widget_show (window);
                    807: 
                    808:     /* We're going to need that later.  */
                    809:     selector = gtk_file_selection_new ("");
                    810:     gtk_signal_connect (GTK_OBJECT (selector), "destroy",
                    811:                        (GtkSignalFunc) did_close_insert, selector);
                    812: 
                    813:     gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->ok_button),
                    814:                               "clicked", (GtkSignalFunc) did_insert_select,
                    815:                               GTK_OBJECT (selector));
                    816:     gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->cancel_button),
                    817:                               "clicked", (GtkSignalFunc) did_cancel_insert,
                    818:                               GTK_OBJECT (selector));
                    819:     filesel_active = -1;
                    820: 
                    821:     gtk_timeout_add (1000, (GtkFunction)my_idle, 0);
                    822:     gtk_main ();
                    823:     
                    824:     quitted_gui = 1;
                    825:     uae_sem_post (&gui_quit_sem);
                    826:     return 0;
                    827: }
                    828: 
                    829: void gui_changesettings(void)
                    830: {
                    831:     
                    832: }
                    833: 
                    834: int gui_init (void)
                    835: {
                    836:     penguin_id tid;
                    837: 
                    838:     gui_active = 0;
                    839:     
                    840:     init_comm_pipe (&to_gui_pipe, 20, 1);
                    841:     init_comm_pipe (&from_gui_pipe, 20, 1);
                    842:     uae_sem_init (&gui_sem, 0, 1);
                    843:     uae_sem_init (&gui_quit_sem, 0, 0);
                    844:     start_penguin (gtk_penguin, NULL, &tid);
                    845:     return 1;
                    846: }
                    847: 
                    848: int gui_update (void)
                    849: {
                    850:     if (no_gui)
                    851:        return 0;
                    852: 
                    853:     write_comm_pipe_int (&to_gui_pipe, 1, 1);    
                    854:     return 0;
                    855: }
                    856: 
                    857: void gui_exit (void)
                    858: {
                    859:     if (no_gui)
                    860:        return;
                    861: 
                    862:     quit_gui = 1;
                    863:     uae_sem_wait (&gui_quit_sem);
                    864: }
                    865: 
                    866: void gui_led(int num, int on)
                    867: {
                    868:     if (no_gui)
                    869:        return;
                    870: 
                    871: /*    if (num == 0)
                    872:        return;
                    873:     printf("LED %d %d\n", num, on);
                    874:     write_comm_pipe_int (&to_gui_pipe, 1, 0);
                    875:     write_comm_pipe_int (&to_gui_pipe, num == 0 ? 4 : num - 1, 0);
                    876:     write_comm_pipe_int (&to_gui_pipe, on, 1);
                    877:     printf("#LED %d %d\n", num, on);*/
                    878: }
                    879: 
                    880: void gui_filename(int num, const char *name)
                    881: {
                    882:     if (no_gui)
                    883:        return;
                    884: 
                    885:     write_comm_pipe_int (&to_gui_pipe, 0, 0);
                    886:     write_comm_pipe_int (&to_gui_pipe, num, 1);
                    887: 
                    888: /*    gui_update ();*/
                    889: }
                    890: 
                    891: void gui_handle_events(void)
                    892: {
                    893:     if (no_gui)
                    894:        return;
                    895: 
                    896:     while (comm_pipe_has_data (&from_gui_pipe)) {
                    897:        int cmd = read_comm_pipe_int_blocking (&from_gui_pipe);
                    898:        int n;
                    899:        switch (cmd) {
                    900:         case 0:
                    901:            n = read_comm_pipe_int_blocking (&from_gui_pipe);
                    902:            changed_prefs.df[n][0] = '\0';
                    903:            break;
                    904:         case 1:
                    905:            n = read_comm_pipe_int_blocking (&from_gui_pipe);
                    906:            uae_sem_wait (&gui_sem);
                    907:            strncpy (changed_prefs.df[n], new_disk_string[n], 255);
                    908:            changed_prefs.df[n][255] = '\0';
                    909:            uae_sem_post (&gui_sem);
                    910:            break;
                    911:         case 2:
                    912:            uae_reset ();
                    913:            break;
                    914:         case 3:
                    915:            activate_debugger ();
                    916:            break;
                    917:         case 4:
                    918:            uae_quit ();
                    919:            break;
                    920:        }
                    921:     }
                    922:     
                    923: }

unix.superglobalmegacorp.com

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