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