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