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