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