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