|
|
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
7: * Copyright 1998 Michael Krause
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 "options.h"
20: #include "uae.h"
21: #include "memory.h"
22: #include "custom.h"
23: #include "audio.h"
24: #include "gui.h"
25: #include "newcpu.h"
26: #include "autoconf.h"
27: #include "filesys.h"
28: #include "threaddep/thread.h"
29: #include "sounddep/sound.h"
30: #include "savestate.h"
31: #include "debug.h"
32: #include "inputdevice.h"
33: #include "romlist.h"
34: #include "zfile.h"
35:
36: #include <gtk/gtk.h>
37: #include <gdk/gdk.h>
38:
39: /* One of the 1.1.6 "features" is a gratuitous name change */
40: #ifndef HAVE_GTK_FEATURES_1_1_6
41: #define gtk_container_set_border_width gtk_container_border_width
42: #endif
43: /* Likewise for 1.1.8. */
44: #ifndef HAVE_GTK_FEATURES_1_1_8
45: #define gtk_label_set_text gtk_label_set
46: #endif
47: /* This is beginning to suck... */
48: #ifndef HAVE_GTK_FEATURES_1_1_13
49: #define gtk_toggle_button_set_active gtk_toggle_button_set_state
50: #endif
51:
52: #include "util.h"
53:
54: static int gui_active, gui_available;
55:
56: static GtkWidget *gui_window;
57:
58: static GtkWidget *pause_uae_widget, *snap_save_widget, *snap_load_widget;
59:
60: static GtkWidget *chipsize_widget[5];
61: static GtkWidget *bogosize_widget[4];
62: static GtkWidget *fastsize_widget[5];
63: static GtkWidget *z3size_widget[10];
64: static GtkWidget *p96size_widget[7];
65: static GtkWidget *rom_text_widget, *rom_path_widget, *key_text_widget;
66: static GtkWidget *romlist_widget, *romsel_button;
67: static int romlist_nr_entries;
68:
69: static GtkWidget *disk_insert_widget[4], *disk_eject_widget[4], *disk_text_widget[4];
70: static GtkWidget *dftype_widget[4];
71: static GtkWidget *disk_type_widget[4];
72:
73: static GtkAdjustment *cpuspeed_adj;
74: static GtkWidget *cpuspeed_widgets[4], *cpuspeed_scale;
75: static GtkWidget *cpu_widget[7], *fpu_widget[5];
76: static GtkWidget *sound_widget[4], *sound_ch_widget[3], *sound_interpol_widget[5];
77: static GtkWidget *sound_filter_widget[5];
78: static GtkAdjustment *stereo_sep_adj, *stereo_delay_adj;
79: static GtkWidget *stereo_sep_scale, *stereo_delay_scale;
80:
81: static GtkWidget *coll_widget[4], *cslevel_widget[4], *ntsc_widget[2];
82: static GtkWidget *mbtype_widget, *mbtype_labelled;
83: static GtkWidget *fcop_widget;
84:
85: static GtkAdjustment *framerate_adj;
86: static GtkWidget *bimm_widget, *b32_widget, *afscr_widget, *pfscr_widget;
87:
88: struct scrmode_widgets
89: {
90: GtkWidget *frame, *modelist;
91: GtkWidget *hcenter, *vcenter, *aspect, *linedbl, *leds;
92: GtkWidget *hc_label, *vc_label, *ld_label;
93: };
94:
95: static struct scrmode_widgets gw_windowed, gw_fullscreen;
96:
97: static GtkWidget *joy_widget[2][6], *legacy_widget, *kbdlang_widget;
98:
99: static GtkWidget *led_widgets[5];
100: static GdkColor led_on[5], led_off[5];
101: static unsigned int prevledstate;
102:
103: static GtkListStore *hd_store;
104: static GtkWidget *hdlist_widget, *bootrom_widget;
105: static GtkWidget *hdchange_button, *hddel_button;
106: static GtkTreeSelection *hd_selection;
107:
108: static GtkWidget *preset_list, *preset_button;
109: static GtkTreeSelection *preset_selection;
110:
111: static GtkWidget *req68020, *req68ec020, *req68030, *reqa4000, *reqa1000;
112: static int rom_req;
113:
114: static GtkWidget *lab_info;
115: static GtkWidget *notebook;
116:
117: GtkWidget *disk_selector;
118:
119: static uae_sem_t gui_sem;
120:
121: /* Copies of certain changed_prefs elements, local to the GUI thread and
122: protected by the gui_sem. */
123: static struct gfx_params gfx_w, gfx_f;
124: static char *gui_snapname, *gui_romname, *gui_keyname;
125: static char *new_disk_string[4];
126:
127:
128: static smp_comm_pipe to_gui_pipe, from_gui_pipe;
129:
130: /* Set to ignore the widget callbacks while we're in the process of updating
131: them with new data. */
132: static int ignore_gui_changes;
133:
134: /*
135: * Messages sent to GUI from UAE via to_gui_pipe
136: */
137: enum gui_commands {
138: GUICMD_SHOW, // Show yourself
139: GUICMD_UPDATE, // Refresh your state from changed preferences
140: GUICMD_DISKCHANGE, // Hey! A disk has been changed. Do something!
141: GUICMD_MSGBOX, // Display a message box for me, please
142: GUICMD_NEW_ROMLIST, // The ROM list has been updated.
143: GUICMD_FLOPPYDLG, // Open a floppy insert dialog
144: GUICMD_FULLSCREEN, // Fullscreen mode was toggled; update checkboxes
145: GUICMD_PAUSE, // We're now paused, in case you didn't notice
146: GUICMD_UNPAUSE // We're now running.
147: };
148:
149: static uae_sem_t gui_sem, gui_init_sem, gui_quit_sem; /* gui_sem protects the DFx fields */
150:
151: static volatile int quit_gui = 0;
152:
153: /* Message box functions. */
154:
155:
156: static GtkWidget *make_labelled_button (guchar *label, GtkAccelGroup *accel_group)
157: {
158: return gtk_button_new_with_mnemonic (label);
159: }
160:
161: static int find_current_toggle (GtkWidget **widgets, int count)
162: {
163: int i;
164: for (i = 0; i < count; i++)
165: if (GTK_TOGGLE_BUTTON (*widgets++)->active)
166: return i;
167: write_log ("GTKUI: Can't happen!\n");
168: return -1;
169: }
170:
171: /*
172: * make_message_box()
173: *
174: * This does the actual work of constructing the message dialog.
175: *
176: * title - displayed in the dialog's titlebar
177: * message - the message itself
178: * modal - whether the dialog should block input to the rest of the GUI
179: * sem - semaphore used for signalling that the dialog's finished
180: *
181: * TODO: Make that semaphore go away. We shouldn't need to know about it here.
182: */
183:
184: static void make_message_box (const char *title, const char *message, int modal)
185: {
186: GtkWidget *dialog;
187: GtkWidget *vbox, *hbox;
188: GtkWidget *label;
189:
190: if (title == NULL || strlen (title) == 0)
191: title = PACKAGE_NAME " information";
192: dialog = gtk_dialog_new_with_buttons (title, NULL,
193: (modal ? GTK_DIALOG_MODAL : 0),
194: GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
195: NULL);
196:
197: gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
198:
199: vbox = GTK_DIALOG (dialog)->vbox;
200:
201: hbox = gtk_hbox_new (FALSE, 0);
202: gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 20);
203: gtk_widget_show (hbox);
204:
205: label = gtk_label_new (message);
206: gtk_widget_show (label);
207: gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 20);
208: gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
209:
210: gtk_dialog_run (GTK_DIALOG (dialog));
211:
212: gtk_widget_destroy (dialog);
213: }
214:
215: static void mkmsgbox (const char *title, const char *message)
216: {
217: make_message_box (title, message, 1);
218: }
219:
220: /*
221: * handle_message_box_request()
222: *
223: * This is called from the GUI's context in repsonse to do_message_box()
224: * to actually create the dialog box
225: */
226: static void handle_message_box_request (smp_comm_pipe *msg_pipe)
227: {
228: const char *title = (const char *) read_comm_pipe_pvoid_blocking (msg_pipe);
229: const char *msg = (const char *) read_comm_pipe_pvoid_blocking (msg_pipe);
230: int modal = read_comm_pipe_int_blocking (msg_pipe);
231: uae_sem_t *msg_quit_sem = (uae_sem_t *) read_comm_pipe_pvoid_blocking (msg_pipe);
232:
233: make_message_box (title, msg, modal);
234: uae_sem_post (msg_quit_sem);
235: }
236:
237: /*
238: * do_message_box()
239: *
240: * This makes up for GTK's lack of a function for creating simple message dialogs.
241: * It can be called from any context. gui_init() must have been called at some point
242: * previously.
243: *
244: * title - will be displayed in the dialog's titlebar (or NULL for default)
245: * message - the message itself
246: * modal - should the dialog block input to the rest of the GUI
247: * wait - should the dialog wait until the user has acknowledged it
248: */
249: static void do_message_box (const guchar *title, const guchar *message, gboolean modal, gboolean wait)
250: {
251: uae_sem_t msg_quit_sem;
252:
253: // If we a need reply, then this semaphore which will be used
254: // to signal us when the dialog has been exited.
255: uae_sem_init (&msg_quit_sem, 0, 0);
256:
257: write_comm_pipe_int (&to_gui_pipe, GUICMD_MSGBOX, 0);
258: write_comm_pipe_pvoid (&to_gui_pipe, (void *) title, 0);
259: write_comm_pipe_pvoid (&to_gui_pipe, (void *) message, 0);
260: write_comm_pipe_int (&to_gui_pipe, (int) modal, 0);
261: write_comm_pipe_pvoid (&to_gui_pipe, wait?&msg_quit_sem:NULL, 1);
262:
263: if (wait)
264: uae_sem_wait (&msg_quit_sem);
265: }
266:
267: void gui_message (const char *format, ...)
268: {
269: char msg[2048];
270: va_list parms;
271:
272: va_start (parms,format);
273: vsprintf ( msg, format, parms);
274: va_end (parms);
275:
276: if (gui_available)
277: do_message_box (NULL, msg, TRUE, TRUE);
278:
279: write_log (msg);
280: }
281:
282: /* Config save/load. */
283:
284: static void save_config (void)
285: {
286: FILE *f;
287: char tmp[257];
288:
289: /* Backup the options file. */
290: strcpy (tmp, optionsfile);
291: strcat (tmp, "~");
292: rename (optionsfile, tmp);
293:
294: f = fopen (optionsfile, "w");
295: if (f == NULL) {
296: write_log ("Error saving options file!\n");
297: return;
298: }
299: save_options (f, &changed_prefs);
300: fclose (f);
301: }
302:
303: static int nr_for_led (GtkWidget *led)
304: {
305: int i;
306: i = 0;
307: while (led_widgets[i] != led)
308: i++;
309: return i;
310: }
311:
312: static void enable_disk_buttons (int enable)
313: {
314: int i;
315: for (i = 0; i < 4; i++) {
316: drive_type t = changed_prefs.dfxtype[i];
317: gtk_widget_set_sensitive (disk_insert_widget[i], enable && t != DRV_NONE);
318: gtk_widget_set_sensitive (disk_eject_widget[i], enable && t != DRV_NONE);
319: gtk_widget_set_sensitive (dftype_widget[i], enable);
320: }
321: }
322:
323: static void set_disk_state (void)
324: {
325: int i;
326: ignore_gui_changes++;
327: for (i = 0; i < 4; i++) {
328: drive_type t = changed_prefs.dfxtype[i];
329: int n;
330: if (i == 0)
331: n = t == DRV_35_DD ? 0 : 1;
332: else
333: n = t == DRV_35_DD ? 1 : t == DRV_35_HD ? 2 : 0;
334: gtk_combo_box_set_active (GTK_COMBO_BOX (dftype_widget[i]), n);
335: }
336: ignore_gui_changes--;
337: }
338:
339: static void set_romlist_state (void)
340: {
341: int i;
342: int active_entry = 0;
343:
344: for (i = 1; i < romlist_nr_entries; i++)
345: gtk_combo_box_remove_text (GTK_COMBO_BOX (romlist_widget), 1);
346: romlist_nr_entries = 1;
347:
348: for (i = 0;; i++) {
349: struct romlist *rl = romlist_from_idx (i, ROMTYPE_KICK, 1);
350: if (!rl)
351: break;
352: if ((changed_prefs.rom_crc32 != 0 && rl->rd->crc32 == changed_prefs.rom_crc32)
353: || (changed_prefs.rom_crc32 == 0 && strcmp (rl->path, changed_prefs.romfile) == 0))
354: active_entry = romlist_nr_entries;
355: gtk_combo_box_append_text (GTK_COMBO_BOX (romlist_widget), rl->rd->name);
356: romlist_nr_entries++;
357: }
358: gtk_combo_box_set_active (GTK_COMBO_BOX (romlist_widget), active_entry);
359: gtk_widget_set_sensitive (romsel_button, active_entry == 0);
360: gtk_widget_set_sensitive (rom_text_widget, active_entry == 0);
361: }
362:
363: static void set_cpu_state (void)
364: {
365: gtk_widget_set_sensitive (cpuspeed_scale, changed_prefs.m68k_speed > 0);
366:
367: gtk_widget_set_sensitive (fpu_widget[0], changed_prefs.cpu_model != 68040 && changed_prefs.cpu_model != 68060);
368: gtk_widget_set_sensitive (fpu_widget[1], changed_prefs.cpu_model == 68020 || changed_prefs.cpu_model == 68030);
369: gtk_widget_set_sensitive (fpu_widget[2], changed_prefs.cpu_model == 68020 || changed_prefs.cpu_model == 68030);
370: gtk_widget_set_sensitive (fpu_widget[3], changed_prefs.cpu_model == 68040);
371: gtk_widget_set_sensitive (fpu_widget[4], changed_prefs.cpu_model == 68060);
372: }
373:
374: static void set_cpu_widget (void)
375: {
376: int nr = (changed_prefs.cpu_model == 68000 ? 0
377: : changed_prefs.cpu_model == 68010 ? 1
378: : changed_prefs.cpu_model == 68020 ? 2
379: : changed_prefs.cpu_model == 68030 ? 4
380: : changed_prefs.cpu_model == 68040 ? 5
381: : 6);
382:
383: if (nr == 2 && !changed_prefs.address_space_24)
384: nr++;
385: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cpu_widget[nr]), TRUE);
386:
387: nr = (changed_prefs.fpu_model == 68881 ? 1
388: : changed_prefs.fpu_model == 68882 ? 2
389: : changed_prefs.cpu_model == 68040 ? 3
390: : changed_prefs.cpu_model == 68060 ? 4
391: : 0);
392: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fpu_widget[nr]), TRUE);
393: nr = changed_prefs.m68k_speed + 1 < 3 ? changed_prefs.m68k_speed + 1 : 2;
394: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cpuspeed_widgets[nr]), TRUE);
395: }
396:
397: /* The idea behind this is to keep entries in aspect/centering boxes even
398: if a screen mode is selected where they are unnecessary, but set the
399: prefs to sane values. */
400: static void adjust_gfx_prefs (struct gfx_params *gp, struct scrmode_widgets *w)
401: {
402: int need_hcenter, need_vcenter, need_aspect, need_linedbl;
403: need_hcenter = gp->width < 400 || (gp->width > 512 && gp->width < 800);
404: need_vcenter = gp->height <= 256 || (gp->height > 300 && gp->height <= 512);
405: need_linedbl = gp->height >= 400;
406: need_aspect = ((gp->height < 256 || (gp->height > 300 && gp->height < 512))
407: && gp->height * 5 / 4 < gp->width);
408:
409: gtk_widget_set_sensitive (w->vc_label, need_vcenter);
410: gtk_widget_set_sensitive (w->hc_label, need_hcenter);
411: gtk_widget_set_sensitive (w->aspect, need_aspect);
412: gtk_widget_set_sensitive (w->ld_label, need_linedbl);
413:
414: if (!need_linedbl)
415: gp->linedbl = 0;
416: if (!need_aspect)
417: gp->correct_aspect = FALSE;
418: if (!need_vcenter)
419: gp->ycenter = 0;
420: if (!need_hcenter)
421: gp->xcenter = 0;
422: }
423:
424: static void set_gfx_mode_state (struct gfx_params *gp, struct scrmode_widgets *w)
425: {
426: ignore_gui_changes++;
427:
428: gtk_combo_box_set_active (GTK_COMBO_BOX (w->linedbl), gp->linedbl ? gp->linedbl - 1 : 1);
429: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w->aspect), gp->correct_aspect);
430: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w->leds), gp->leds_on_screen);
431:
432: gtk_combo_box_set_active (GTK_COMBO_BOX (w->hcenter), gp->xcenter);
433: gtk_combo_box_set_active (GTK_COMBO_BOX (w->vcenter), gp->ycenter);
434: ignore_gui_changes--;
435: }
436:
437: static void set_fullscreen_state (void)
438: {
439: ignore_gui_changes++;
440: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (afscr_widget), changed_prefs.gfx_afullscreen != 0);
441: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pfscr_widget), changed_prefs.gfx_pfullscreen != 0);
442: ignore_gui_changes--;
443: }
444:
445: static void set_gfx_state (void)
446: {
447: int t;
448:
449: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bimm_widget), changed_prefs.immediate_blits != 0);
450:
451: ignore_gui_changes++;
452: uae_sem_wait (&gui_sem);
453: t = fixup_prefs_dimensions (&gfx_w, gfx_windowed_modes, n_windowed_modes);
454: gtk_combo_box_set_active (GTK_COMBO_BOX (gw_windowed.modelist), t);
455: t = fixup_prefs_dimensions (&gfx_f, gfx_fullscreen_modes, n_fullscreen_modes);
456: gtk_combo_box_set_active (GTK_COMBO_BOX (gw_fullscreen.modelist), t);
457: ignore_gui_changes--;
458:
459: adjust_gfx_prefs (&gfx_w, &gw_windowed);
460: adjust_gfx_prefs (&gfx_f, &gw_fullscreen);
461: uae_sem_post (&gui_sem);
462:
463: set_gfx_mode_state (&gfx_w, &gw_windowed);
464: set_gfx_mode_state (&gfx_f, &gw_fullscreen);
465:
466: set_fullscreen_state ();
467: #if 0
468: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b32_widget), changed_prefs.blits_32bit_enabled != 0);
469: #endif
470: }
471:
472: /* The intended behaviour here is that on startup, and when loading a state
473: file, we examine the prefs to see if they match a given motherboard, and
474: initialize the combo box accordingly. When the user changes it, default
475: settings are automatically chosen unless the user sets "Generic", in which
476: case he has control over all the options. */
477: static void discover_cstype (void)
478: {
479: int t0;
480: int cstype = cstype_from_prefs (&changed_prefs);
481:
482: t0 = (cstype == CP_GENERIC ? 0
483: : cstype == CP_A1000 ? 1
484: : cstype == CP_A500 || cstype == CP_A500P ? 2
485: : cstype == CP_A600 ? 3
486: : cstype == CP_A1200 ? 4
487: : cstype == CP_A3000 ? 5
488: : 6);
489:
490: ignore_gui_changes++;
491: gtk_combo_box_set_active (GTK_COMBO_BOX (mbtype_widget), t0);
492: ignore_gui_changes--;
493: }
494:
495: static void set_chipset_state (void)
496: {
497: int t0 = 0;
498:
499: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (coll_widget[changed_prefs.collision_level]), TRUE);
500: if (changed_prefs.chipset_mask & CSMASK_AGA)
501: t0 = 3;
502: else if (changed_prefs.chipset_mask & CSMASK_ECS_DENISE)
503: t0 = 2;
504: else if (changed_prefs.chipset_mask & CSMASK_ECS_AGNUS)
505: t0 = 1;
506: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cslevel_widget[t0]), TRUE);
507: }
508:
509: static void set_sound_state (void)
510: {
511: int n;
512: int stereo = changed_prefs.sound_stereo;
513:
514: gtk_widget_set_sensitive (stereo_sep_scale, changed_prefs.sound_stereo != SND_MONO);
515: gtk_widget_set_sensitive (stereo_delay_scale, changed_prefs.sound_stereo != SND_MONO);
516:
517: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_widget[changed_prefs.produce_sound]), 1);
518: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_ch_widget[stereo]), 1);
519: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_interpol_widget[changed_prefs.sound_interpol]), 1);
520: n = (changed_prefs.sound_filter == FILTER_SOUND_OFF ? 0
521: : ((changed_prefs.sound_filter == FILTER_SOUND_EMUL ? 1 : 2)
522: + (changed_prefs.sound_filter_type == FILTER_SOUND_TYPE_A500 ? 0 : 2)));
523: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_filter_widget[n]), 1);
524: }
525:
526: static void set_mem_state (void)
527: {
528: int bogo2m_ok;
529: int t, t2, i;
530:
531: for (i = 0; i < 10; i++)
532: gtk_widget_set_sensitive (z3size_widget[i], ! changed_prefs.address_space_24);
533: for (i = 0; i < 7; i++)
534: gtk_widget_set_sensitive (p96size_widget[i],
535: changed_prefs.bootrom && ! changed_prefs.address_space_24);
536:
537: bogo2m_ok = !((changed_prefs.chipset_mask & CSMASK_AGA) || changed_prefs.cpu_model >= 68020);
538: gtk_widget_set_sensitive (bogosize_widget[3], bogo2m_ok);
539:
540: t = 0;
541: t2 = changed_prefs.chipmem_size;
542: while (t < 4 && t2 > 0x80000)
543: t++, t2 >>= 1;
544: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chipsize_widget[t]), 1);
545:
546: t = 0;
547: t2 = changed_prefs.bogomem_size;
548: if (t2 > 0x100000 && !bogo2m_ok)
549: t2 = 0x100000;
550: changed_prefs.bogomem_size = t2;
551: while (t < 3 && t2 >= 0x80000)
552: t++, t2 >>= 1;
553: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bogosize_widget[t]), 1);
554:
555: t = 0;
556: t2 = changed_prefs.fastmem_size;
557: while (t < 4 && t2 >= 0x100000)
558: t++, t2 >>= 1;
559: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fastsize_widget[t]), 1);
560:
561: t = 0;
562: t2 = changed_prefs.z3fastmem_size;
563: while (t < 9 && t2 >= 0x100000)
564: t++, t2 >>= 1;
565: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (z3size_widget[t]), 1);
566:
567: t = 0;
568: t2 = changed_prefs.gfxmem_size;
569: while (t < 6 && t2 >= 0x100000)
570: t++, t2 >>= 1;
571: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (p96size_widget[t]), 1);
572:
573: gtk_label_set_text (GTK_LABEL (rom_path_widget), changed_prefs.path_rom);
574: gtk_label_set_text (GTK_LABEL (rom_text_widget), changed_prefs.romfile);
575: gtk_label_set_text (GTK_LABEL (key_text_widget), changed_prefs.keyfile);
576: }
577:
578: static void set_joy_state (void)
579: {
580: int joy_count = inputdevice_get_device_total (IDTYPE_JOYSTICK);
581: int j0j = jsem_isjoy (0, &changed_prefs);
582: int j0m = jsem_ismouse (0, &changed_prefs);
583: int j0k = jsem_iskbdjoy (0, &changed_prefs);
584: int j1j = jsem_isjoy (1, &changed_prefs);
585: int j1m = jsem_ismouse (1, &changed_prefs);
586: int j1k = jsem_iskbdjoy (1, &changed_prefs);
587: int j0t = (j0j == 0 || j0j == 1 ? j0j
588: : j0m == 0 ? 2
589: : j0k + 3);
590: int j1t = (j1j == 0 || j1j == 1 ? j1j
591: : j1m == 0 ? 2
592: : j1k + 3);
593: int i;
594:
595: if (j0t == j1t) {
596: /* Can't happen */
597: j0t++;
598: j0t %= 6;
599: }
600:
601: for (i = 0; i < 6; i++) {
602: int available = i >= 2 || joy_count > i;
603: if (changed_prefs.input_selected_setting != 0)
604: available = 0;
605: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[0][i]), j0t == i);
606: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[1][i]), j1t == i);
607: gtk_widget_set_sensitive (joy_widget[0][i], available && j1t != i);
608: gtk_widget_set_sensitive (joy_widget[1][i], available && j0t != i);
609: }
610:
611: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (legacy_widget),
612: changed_prefs.input_selected_setting == 0);
613:
614: gtk_combo_box_set_active (GTK_COMBO_BOX (kbdlang_widget),
615: changed_prefs.keyboard_lang);
616: }
617:
618: static void set_hd_state (void)
619: {
620: char texts[9][256];
621: int nr = nr_units (currprefs.mountinfo);
622: int i;
623:
624: gtk_list_store_clear (hd_store);
625: for (i = 0; i < nr; i++) {
626: GtkTreeIter iter;
627: int secspertrack, surfaces, reserved, blocksize, size;
628: int cylinders, readonly, pri;
629: char *volname, *rootdir, *devname;
630: char *failure;
631:
632: /* We always use currprefs.mountinfo for the GUI. The filesystem
633: code makes a private copy which is updated every reset. */
634: failure = get_filesys_unit (currprefs.mountinfo, i,
635: &devname, &volname, &rootdir, &readonly,
636: &secspertrack, &surfaces, &reserved,
637: &cylinders, &size, &blocksize, &pri);
638:
639: if (is_hardfile (currprefs.mountinfo, i)) {
640: sprintf (texts[0], "DH%d", i );
641: sprintf (texts[3], "%d", surfaces);
642: sprintf (texts[4], "%d", cylinders);
643: sprintf (texts[5], "%d", secspertrack);
644: sprintf (texts[6], "%d", reserved);
645: sprintf (texts[7], "%d", size);
646: sprintf (texts[8], "%d", blocksize);
647: } else {
648: strcpy (texts[0], volname);
649: strcpy (texts[3], "n/a");
650: strcpy (texts[4], "n/a");
651: strcpy (texts[5], "n/a");
652: strcpy (texts[6], "n/a");
653: strcpy (texts[7], "n/a");
654: strcpy (texts[8], "n/a");
655: }
656: strcpy (texts[1], rootdir);
657: gtk_list_store_append (hd_store, &iter);
658:
659: gtk_list_store_set (hd_store, &iter,
660: 0, i,
661: 1, texts[0],
662: 2, texts[1],
663: 3, readonly,
664: 4, texts[3],
665: 5, texts[4],
666: 6, texts[5],
667: 7, texts[6],
668: 8, texts[7],
669: 9, texts[8],
670: 10, pri,
671: -1);
672: if (volname)
673: free (volname);
674: if (devname)
675: free (devname);
676: if (rootdir)
677: free (rootdir);
678: }
679: gtk_widget_set_sensitive (hdchange_button, FALSE);
680: gtk_widget_set_sensitive (hddel_button, FALSE);
681:
682: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bootrom_widget),
683: changed_prefs.bootrom != 0);
684: }
685:
686: static void rom_requirements_change (void)
687: {
688: int i, min_widget = 0;
689:
690: gtk_widget_hide (req68020);
691: gtk_widget_hide (req68ec020);
692: gtk_widget_hide (req68030);
693: gtk_widget_hide (reqa1000);
694: gtk_widget_hide (reqa4000);
695: if ((rom_req & ROMREQ_CPUMASK) == ROMREQ_68EC020) {
696: min_widget = 2;
697: gtk_widget_show (req68ec020);
698: } else if ((rom_req & ROMREQ_CPUMASK) == ROMREQ_68020) {
699: min_widget = 3;
700: gtk_widget_show (req68020);
701: } else if ((rom_req & ROMREQ_CPUMASK) == ROMREQ_68030) {
702: min_widget = 4;
703: gtk_widget_show (req68030);
704: }
705: if (rom_req & ROMREQ_A4000MB) {
706: gtk_widget_show (reqa4000);
707: gtk_combo_box_set_active (GTK_COMBO_BOX (mbtype_widget), 6);
708: gtk_widget_set_sensitive (mbtype_labelled, 0);
709: } else if (rom_req & ROMREQ_A1000) {
710: gtk_widget_show (reqa1000);
711: gtk_combo_box_set_active (GTK_COMBO_BOX (mbtype_widget), 1);
712: gtk_widget_set_sensitive (mbtype_labelled, 0);
713: } else
714: gtk_widget_set_sensitive (mbtype_labelled, 1);
715:
716: i = find_current_toggle (cpu_widget, 7);
717: if (i < min_widget)
718: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cpu_widget[min_widget]), TRUE);
719:
720: for (i = 0; i < 7; i++)
721: gtk_widget_set_sensitive (cpu_widget[i], i >= min_widget);
722: }
723:
724: static void draw_led (int nr)
725: {
726: GtkWidget *thing = led_widgets[nr];
727: GdkWindow *window = thing->window;
728: GdkGC *gc = gdk_gc_new (window);
729: GdkColor *col;
730:
731: if (gui_ledstate & (1 << nr))
732: col = led_on + nr;
733: else
734: col = led_off + nr;
735: gdk_gc_set_foreground (gc, col);
736: gdk_draw_rectangle (window, gc, 1, 0, 0, -1, -1);
737: gdk_gc_destroy (gc);
738: }
739:
740: static void set_widgets_from_config (void)
741: {
742: gfx_w = changed_prefs.gfx_w;
743: gfx_f = changed_prefs.gfx_f;
744: set_disk_state ();
745: enable_disk_buttons (1);
746: set_romlist_state ();
747: set_cpu_widget ();
748: set_cpu_state ();
749: set_gfx_state ();
750: set_joy_state ();
751: set_sound_state ();
752: set_mem_state ();
753: set_hd_state ();
754: discover_cstype ();
755: set_chipset_state ();
756: rom_requirements_change ();
757: }
758:
759: static int my_idle (void)
760: {
761: unsigned int leds = gui_ledstate;
762: int i;
763:
764: if (quit_gui) {
765: gui_active = 0;
766: gtk_main_quit ();
767: goto out;
768: }
769:
770: while (comm_pipe_has_data (&to_gui_pipe)) {
771: int cmd = read_comm_pipe_int_blocking (&to_gui_pipe);
772: int n;
773: switch (cmd) {
774: case GUICMD_DISKCHANGE:
775: n = read_comm_pipe_int_blocking (&to_gui_pipe);
776: gtk_label_set_text (GTK_LABEL (disk_text_widget[n]), currprefs.df[n]);
777: break;
778: case GUICMD_UPDATE:
779: /* Initialization. */
780: set_widgets_from_config ();
781:
782: gtk_widget_show (gui_window);
783: uae_sem_post (&gui_init_sem);
784: gui_active = 1;
785: break;
786: case GUICMD_PAUSE:
787: /* Set Pause-Button active */
788: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pause_uae_widget), TRUE);
789: break;
790: case GUICMD_UNPAUSE:
791: /* Set Pause-Button inactive */
792: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pause_uae_widget), FALSE);
793: break;
794: case GUICMD_NEW_ROMLIST:
795: set_romlist_state ();
796: break;
797: case GUICMD_FULLSCREEN:
798: set_fullscreen_state ();
799: break;
800: case GUICMD_MSGBOX:
801: handle_message_box_request(&to_gui_pipe);
802: break;
803: }
804: }
805:
806: if (gui_active) {
807: int n = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)) == 0 ? 5 : 1;
808: for (i = 0; i < n; i++) {
809: unsigned int mask = 1 << i;
810: unsigned int on = leds & mask;
811:
812: if (on == (prevledstate & mask))
813: continue;
814:
815: /* printf(": %d %d\n", i, on);*/
816: draw_led (i);
817: }
818: prevledstate = leds;
819: }
820: out:
821: return 1;
822: }
823:
824: static gint gui_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
825: {
826: gui_active = gui_available = 0;
827: gtk_widget_destroy (disk_selector);
828: disk_selector = 0;
829: return FALSE;
830: }
831:
832: static void dftype_changed (GtkWidget *w, gpointer data)
833: {
834: int i;
835:
836: if (ignore_gui_changes)
837: return;
838: for (i = 0; i < 4; i++) {
839: int which = gtk_combo_box_get_active (GTK_COMBO_BOX (dftype_widget[i]));
840: if (i == 0)
841: which++;
842: changed_prefs.dfxtype[i] = (which == 0 ? DRV_NONE : which == 1 ? DRV_35_DD : DRV_35_HD);
843: }
844: enable_disk_buttons (1);
845: }
846:
847: static void kbdlang_changed (GtkWidget *w, gpointer data)
848: {
849: int which = gtk_combo_box_get_active (GTK_COMBO_BOX (kbdlang_widget));
850: changed_prefs.keyboard_lang = which;
851: }
852:
853: static void joy_changed (void)
854: {
855: int j0t, j1t;
856: if (! gui_active)
857: return;
858:
859: j0t = find_current_toggle (joy_widget[0], 6);
860: j1t = find_current_toggle (joy_widget[1], 6);
861: changed_prefs.jport0 = (j0t == 0 || j0t == 1 ? JSEM_JOYS + j0t
862: : j0t == 2 ? JSEM_MICE
863: : JSEM_KBDLAYOUT + j0t - 3);
864: changed_prefs.jport1 = (j1t == 0 || j1t == 1 ? JSEM_JOYS + j1t
865: : j1t == 2 ? JSEM_MICE
866: : JSEM_KBDLAYOUT + j1t - 3);
867:
868: changed_prefs.input_selected_setting = GTK_TOGGLE_BUTTON (legacy_widget)->active ? 0 : 1;
869:
870: if (changed_prefs.input_selected_setting != currprefs.input_selected_setting
871: || changed_prefs.jport0 != currprefs.jport0
872: || changed_prefs.jport1 != currprefs.jport1)
873: inputdevice_config_change ();
874:
875: set_joy_state ();
876: }
877:
878: static void coll_changed (void)
879: {
880: changed_prefs.collision_level = find_current_toggle (coll_widget, 4);
881: }
882:
883: static void cslevel_changed (void)
884: {
885: int t = find_current_toggle (cslevel_widget, 4);
886: int t1 = 0;
887: if (t > 0)
888: t1 |= CSMASK_ECS_AGNUS;
889: if (t > 1)
890: t1 |= CSMASK_ECS_DENISE;
891: if (t > 2)
892: t1 |= CSMASK_AGA;
893: changed_prefs.chipset_mask = t1;
894: set_mem_state ();
895: }
896:
897: static void custom_changed (void)
898: {
899: if (ignore_gui_changes)
900: return;
901: changed_prefs.gfx_framerate = framerate_adj->value;
902: changed_prefs.immediate_blits = GTK_TOGGLE_BUTTON (bimm_widget)->active;
903: changed_prefs.gfx_afullscreen = GTK_TOGGLE_BUTTON (afscr_widget)->active;
904: changed_prefs.gfx_pfullscreen = GTK_TOGGLE_BUTTON (pfscr_widget)->active;
905: #if 0
906: changed_prefs.blits_32bit_enabled = GTK_TOGGLE_BUTTON (b32_widget)->active;
907: #endif
908: }
909:
910: static void leds_changed (void)
911: {
912: int w_leds = GTK_TOGGLE_BUTTON (gw_windowed.leds)->active;
913: int f_leds = GTK_TOGGLE_BUTTON (gw_fullscreen.leds)->active;
914: gfx_w.leds_on_screen = w_leds;
915: gfx_f.leds_on_screen = f_leds;
916: write_comm_pipe_int (&from_gui_pipe, 11, 1);
917: }
918:
919: static void aspect_changed (void)
920: {
921: int w_aspect = GTK_TOGGLE_BUTTON (gw_windowed.aspect)->active;
922: int f_aspect = GTK_TOGGLE_BUTTON (gw_fullscreen.aspect)->active;
923: int w_ldbl = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_windowed.linedbl)) + 1;
924: int f_ldbl = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_fullscreen.linedbl)) + 1;
925: int w_hc = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_windowed.hcenter));
926: int f_hc = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_fullscreen.hcenter));
927: int w_vc = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_windowed.vcenter));
928: int f_vc = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_fullscreen.vcenter));
929:
930: if (ignore_gui_changes)
931: return;
932:
933: uae_sem_wait (&gui_sem);
934: gfx_w.ycenter = w_vc;
935: gfx_w.xcenter = w_hc;
936: gfx_w.correct_aspect = w_aspect;
937: gfx_w.linedbl = w_ldbl;
938: gfx_f.ycenter = f_vc;
939: gfx_f.xcenter = f_hc;
940: gfx_f.correct_aspect = f_aspect;
941: gfx_f.linedbl = f_ldbl;
942:
943: adjust_gfx_prefs (&gfx_w, &gw_windowed);
944: adjust_gfx_prefs (&gfx_f, &gw_fullscreen);
945: uae_sem_post (&gui_sem);
946: write_comm_pipe_int (&from_gui_pipe, 11, 1);
947: }
948:
949: static void screenmode_changed (void)
950: {
951: int w = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_windowed.modelist));
952: int f = gtk_combo_box_get_active (GTK_COMBO_BOX (gw_fullscreen.modelist));
953: int need_set_w = 0, need_set_f = 0;
954:
955: if (ignore_gui_changes)
956: return;
957:
958: uae_sem_wait (&gui_sem);
959: if (w != -1) {
960: need_set_w = (gfx_w.width != gfx_windowed_modes[w].w
961: || gfx_w.height != gfx_windowed_modes[w].h);
962: gfx_w.width = gfx_windowed_modes[w].w;
963: gfx_w.height = gfx_windowed_modes[w].h;
964: }
965: if (f != -1) {
966: need_set_f = (gfx_f.width != gfx_fullscreen_modes[f].w
967: || gfx_f.height != gfx_fullscreen_modes[f].h);
968: gfx_f.width = gfx_fullscreen_modes[f].w;
969: gfx_f.height = gfx_fullscreen_modes[f].h;
970: }
971: if (need_set_w) {
972: fixup_prefs_dimensions (&gfx_w, gfx_windowed_modes, n_windowed_modes);
973: }
974: if (need_set_f) {
975: fixup_prefs_dimensions (&gfx_f, gfx_fullscreen_modes, n_fullscreen_modes);
976: }
977: uae_sem_post (&gui_sem);
978:
979: if (!need_set_w && !need_set_f)
980: return;
981:
982: /* We may have switched to a screenmode that has centering or other
983: modifiers enabled; re-set the members of the prefs structure
984: according to the new mode. See comment before adjust_gfx_prefs.
985:
986: aspect_changed also sends the message to the main thread. */
987: aspect_changed ();
988: }
989:
990: static void cpuspeed_changed (void)
991: {
992: int which = find_current_toggle (cpuspeed_widgets, 3);
993: changed_prefs.m68k_speed = (which == 0 ? -1
994: : which == 1 ? 0
995: : cpuspeed_adj->value);
996: set_cpu_state ();
997: }
998:
999: static void cputype_changed (void)
1000: {
1001: int i, oldcl;
1002: int whichtoggle;
1003: if (! gui_active)
1004: return;
1005:
1006: whichtoggle = find_current_toggle (cpu_widget, 7);
1007: changed_prefs.address_space_24 = whichtoggle < 3;
1008: if (whichtoggle >= 3)
1009: whichtoggle--;
1010:
1011: if (whichtoggle == 5)
1012: whichtoggle = 6;
1013: changed_prefs.cpu_model = 68000 + 10 * whichtoggle;
1014:
1015: if (changed_prefs.cpu_model == 68060) {
1016: changed_prefs.fpu_model = 68060;
1017: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fpu_widget[4]), 1);
1018: } else if (changed_prefs.cpu_model == 68040) {
1019: changed_prefs.fpu_model = 68040;
1020: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fpu_widget[3]), 1);
1021: } else if ((changed_prefs.cpu_model != 68020 && changed_prefs.cpu_model != 68030)
1022: || changed_prefs.fpu_model == 68040
1023: || changed_prefs.fpu_model == 68060) {
1024: changed_prefs.fpu_model = 0;
1025: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fpu_widget[0]), 1);
1026: } else {
1027: whichtoggle = find_current_toggle (fpu_widget, 5);
1028: changed_prefs.fpu_model = (whichtoggle == 0 ? 0
1029: : whichtoggle == 1 ? 68881
1030: : whichtoggle == 2 ? 68882
1031: : whichtoggle == 3 ? 68040
1032: : 68060);
1033: }
1034:
1035: set_cpu_state ();
1036: /* May influence bogomem size and Z3/GFXcard memory. */
1037: set_mem_state();
1038: }
1039:
1040: static void chipsize_changed (void)
1041: {
1042: int t = find_current_toggle (chipsize_widget, 5);
1043: changed_prefs.chipmem_size = 0x80000 << t;
1044: for (t = 0; t < 5; t++)
1045: gtk_widget_set_sensitive (fastsize_widget[t], changed_prefs.chipmem_size <= 0x200000);
1046: if (changed_prefs.chipmem_size > 0x200000) {
1047: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fastsize_widget[0]), 1);
1048: changed_prefs.fastmem_size = 0;
1049: }
1050: }
1051:
1052: static void bogosize_changed (void)
1053: {
1054: int t = find_current_toggle (bogosize_widget, 4);
1055: changed_prefs.bogomem_size = (0x40000 << t) & ~0x40000;
1056: }
1057:
1058: static void fastsize_changed (void)
1059: {
1060: int t = find_current_toggle (fastsize_widget, 5);
1061: changed_prefs.fastmem_size = (0x80000 << t) & ~0x80000;
1062: }
1063:
1064: static void z3size_changed (void)
1065: {
1066: int t = find_current_toggle (z3size_widget, 10);
1067: changed_prefs.z3fastmem_size = (0x80000 << t) & ~0x80000;
1068: }
1069:
1070: static void p96size_changed (void)
1071: {
1072: int t = find_current_toggle (p96size_widget, 7);
1073: changed_prefs.gfxmem_size = (0x80000 << t) & ~0x80000;
1074: }
1075:
1076: static void rom_combo_changed (void)
1077: {
1078: int t = gtk_combo_box_get_active (GTK_COMBO_BOX (romlist_widget));
1079: gtk_widget_set_sensitive (romsel_button, t == 0);
1080: gtk_widget_set_sensitive (rom_text_widget, t == 0);
1081:
1082: rom_req = 0;
1083:
1084: if (t == 0) {
1085: changed_prefs.rom_crc32 = 0;
1086: } else {
1087: struct romlist *rl = romlist_from_idx (t - 1, ROMTYPE_KICK, 1);
1088: if (rl) {
1089: changed_prefs.rom_crc32 = rl->rd->crc32;
1090: rom_req = rl->rd->cpu;
1091: }
1092: }
1093: rom_requirements_change ();
1094: }
1095:
1096: static void sound_changed (void)
1097: {
1098: int n;
1099:
1100: changed_prefs.produce_sound = find_current_toggle (sound_widget, 4);
1101: n = find_current_toggle (sound_ch_widget, 3);
1102: changed_prefs.sound_stereo = n == 0 ? SND_MONO : SND_STEREO;
1103: changed_prefs.sound_interpol = find_current_toggle (sound_interpol_widget, 5);
1104: n = find_current_toggle (sound_filter_widget, 5);
1105: if (n == 0)
1106: changed_prefs.sound_filter = FILTER_SOUND_OFF;
1107: else {
1108: changed_prefs.sound_filter = (n & 1) ? FILTER_SOUND_EMUL : FILTER_SOUND_ON;
1109: changed_prefs.sound_filter_type = (n > 2 ? FILTER_SOUND_TYPE_A1200 : FILTER_SOUND_TYPE_A500);
1110: }
1111: changed_prefs.sound_mixed_stereo_delay = stereo_delay_adj->value;
1112: changed_prefs.sound_stereo_separation = stereo_sep_adj->value;
1113:
1114: gtk_widget_set_sensitive (stereo_sep_scale, changed_prefs.sound_stereo == SND_STEREO);
1115: gtk_widget_set_sensitive (stereo_delay_scale, changed_prefs.sound_stereo == SND_STEREO);
1116: }
1117:
1118: static void bootrom_changed (void)
1119: {
1120: changed_prefs.bootrom = GTK_TOGGLE_BUTTON (bootrom_widget)->active ? 1 : 0;
1121: set_mem_state ();
1122: }
1123:
1124: static void ntsc_changed (void)
1125: {
1126: changed_prefs.ntscmode = find_current_toggle (ntsc_widget, 2);
1127: }
1128:
1129: static void mbtype_changed (void)
1130: {
1131: int needs_aga, allows_ocs, allows_ecs;
1132: int n, cstype;
1133:
1134: if (ignore_gui_changes)
1135: return;
1136:
1137: n = gtk_combo_box_get_active (GTK_COMBO_BOX (mbtype_widget));
1138: cstype = (n == 0 ? CP_GENERIC
1139: : n == 1 ? CP_A1000
1140: : n == 2 ? CP_A500
1141: : n == 3 ? CP_A600
1142: : n == 4 ? CP_A1200
1143: : n == 5 ? CP_A3000
1144: : CP_A4000);
1145: if (cstype != CP_GENERIC)
1146: built_in_chipset_prefs (&changed_prefs, cstype);
1147:
1148: needs_aga = cstype == CP_A1200 || cstype == CP_A4000 || cstype == CP_A4000T || cstype == CP_CD32;
1149: allows_ocs = cstype == CP_A1000 || cstype == CP_A500 || cstype == CP_A2000;
1150: allows_ecs = !needs_aga && cstype != CP_A1000;
1151:
1152: gtk_widget_set_sensitive (cslevel_widget[0], cstype == CP_GENERIC || allows_ocs);
1153: gtk_widget_set_sensitive (cslevel_widget[1], cstype == CP_GENERIC || allows_ecs);
1154: gtk_widget_set_sensitive (cslevel_widget[2], cstype == CP_GENERIC || allows_ecs);
1155: gtk_widget_set_sensitive (cslevel_widget[3], cstype == CP_GENERIC || needs_aga);
1156:
1157: if (cstype != CP_GENERIC) {
1158: if (needs_aga)
1159: changed_prefs.chipset_mask = CSMASK_AGA | CSMASK_FULL_ECS;
1160: else if (! allows_ecs)
1161: changed_prefs.chipset_mask = 0;
1162: }
1163: set_chipset_state ();
1164: }
1165:
1166: static void did_reset (void)
1167: {
1168: if (quit_gui)
1169: return;
1170:
1171: write_comm_pipe_int (&from_gui_pipe, 2, 1);
1172: }
1173:
1174: static void did_debug (void)
1175: {
1176: if (quit_gui)
1177: return;
1178:
1179: write_comm_pipe_int (&from_gui_pipe, 3, 1);
1180: }
1181:
1182: static void did_quit (void)
1183: {
1184: if (quit_gui)
1185: return;
1186:
1187: write_comm_pipe_int (&from_gui_pipe, 4, 1);
1188: }
1189:
1190: static void did_eject (GtkWidget *w, gpointer data_p)
1191: {
1192: int data = GPOINTER_TO_INT (data_p);
1193: if (quit_gui)
1194: return;
1195:
1196: write_comm_pipe_int (&from_gui_pipe, 0, 0);
1197: write_comm_pipe_int (&from_gui_pipe, data, 1);
1198: gtk_label_set_text (GTK_LABEL (disk_text_widget[data]), "");
1199: }
1200:
1201: static void pause_uae (void)
1202: {
1203: if (quit_gui)
1204: return;
1205:
1206: write_comm_pipe_int (&from_gui_pipe, GTK_TOGGLE_BUTTON (pause_uae_widget)->active ? 5 : 6, 1);
1207: if (! GTK_TOGGLE_BUTTON (pause_uae_widget)->active)
1208: gtk_widget_hide (lab_info);
1209: }
1210:
1211: static void end_pause_uae (void)
1212: {
1213: write_comm_pipe_int (&to_gui_pipe, GUICMD_UNPAUSE, 1);
1214: }
1215:
1216: static char fsbuffer[100];
1217:
1218: static GtkWidget *make_file_selector (const char *title,
1219: GtkFileChooserAction action)
1220: {
1221: GtkWidget *p = gtk_file_chooser_dialog_new (title, GTK_WINDOW (gui_window), action,
1222: GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1223: action == GTK_FILE_CHOOSER_ACTION_SAVE ? GTK_STOCK_SAVE : GTK_STOCK_OPEN,
1224: GTK_RESPONSE_ACCEPT,
1225: NULL);
1226:
1227: return p;
1228: }
1229:
1230: static void filesel_set_path (GtkWidget *p, const char *path)
1231: {
1232: size_t len = strlen (path);
1233: if (len > 0 && ! access (path, R_OK)) {
1234: char *tmp = xmalloc (len + 2);
1235: strcpy (tmp, path);
1236: strcat (tmp, "/");
1237: gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (p), tmp);
1238: }
1239: }
1240:
1241: static void make_disk_selector (void)
1242: {
1243: if (disk_selector)
1244: return;
1245: disk_selector = make_file_selector ("Select a disk image file to mount",
1246: GTK_FILE_CHOOSER_ACTION_OPEN);
1247: filesel_set_path (disk_selector, currprefs.path_floppy);
1248: }
1249:
1250: static void did_insert (GtkWidget *w, gpointer data)
1251: {
1252: int n = GPOINTER_TO_INT (data);
1253:
1254: make_disk_selector ();
1255: sprintf (fsbuffer, "Select a disk image file for DF%d", n);
1256: gtk_window_set_title (GTK_WINDOW (disk_selector), fsbuffer);
1257:
1258: if (gtk_dialog_run (GTK_DIALOG (disk_selector)) == GTK_RESPONSE_ACCEPT) {
1259: char *filename;
1260:
1261: filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (disk_selector));
1262:
1263: uae_sem_wait (&gui_sem);
1264: if (new_disk_string[n] != 0)
1265: free (new_disk_string[n]);
1266: new_disk_string[n] = strdup (filename);
1267: uae_sem_post (&gui_sem);
1268: write_comm_pipe_int (&from_gui_pipe, 1, 0);
1269: write_comm_pipe_int (&from_gui_pipe, n, 1);
1270: gtk_label_set_text (GTK_LABEL (disk_text_widget[n]), filename);
1271:
1272: g_free (filename);
1273: }
1274: gtk_widget_hide (disk_selector);
1275: }
1276:
1277: static gint driveled_event (GtkWidget *thing, GdkEvent *event)
1278: {
1279: int lednr = nr_for_led (thing);
1280:
1281: switch (event->type) {
1282: case GDK_MAP:
1283: draw_led (lednr);
1284: break;
1285: case GDK_EXPOSE:
1286: draw_led (lednr);
1287: break;
1288: default:
1289: break;
1290: }
1291:
1292: return 0;
1293: }
1294:
1295: static GtkWidget *snap_selector;
1296:
1297: static void did_loadstate (void)
1298: {
1299: GtkWidget *dialog;
1300:
1301: dialog = make_file_selector ("Select a state file to restore", GTK_FILE_CHOOSER_ACTION_OPEN);
1302:
1303: if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
1304: char *filename;
1305:
1306: filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1307:
1308: uae_sem_wait (&gui_sem);
1309: gui_snapname = strdup (filename);
1310: uae_sem_post (&gui_sem);
1311: write_comm_pipe_int (&from_gui_pipe, 7, 0);
1312: write_comm_pipe_int (&from_gui_pipe, STATE_DORESTORE, 1);
1313:
1314: g_free (filename);
1315: }
1316:
1317: gtk_widget_destroy (dialog);
1318: }
1319:
1320: static void did_savestate (void)
1321: {
1322: GtkWidget *dialog;
1323:
1324: dialog = make_file_selector ("Select a filename for the state file",
1325: GTK_FILE_CHOOSER_ACTION_SAVE);
1326:
1327: if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
1328: char *filename;
1329:
1330: filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1331:
1332: uae_sem_wait (&gui_sem);
1333: gui_snapname = strdup (filename);
1334: uae_sem_post (&gui_sem);
1335: write_comm_pipe_int (&from_gui_pipe, 7, 0);
1336: write_comm_pipe_int (&from_gui_pipe, STATE_DOSAVE, 1);
1337:
1338: g_free (filename);
1339: }
1340:
1341: gtk_widget_destroy (dialog);
1342: }
1343:
1344: static void did_rompathchange (GtkWidget *w, gpointer data)
1345: {
1346: GtkWidget *pathsel;
1347: pathsel = make_file_selector ("Select a ROM path",
1348: GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
1349: filesel_set_path (pathsel, currprefs.path_rom);
1350: if (gtk_dialog_run (GTK_DIALOG (pathsel)) == GTK_RESPONSE_ACCEPT) {
1351: char *filename;
1352:
1353: filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (pathsel));
1354:
1355: uae_sem_wait (&gui_sem);
1356: gui_romname = strdup (filename);
1357: uae_sem_post (&gui_sem);
1358: write_comm_pipe_int (&from_gui_pipe, 10, 0);
1359: gtk_label_set_text (GTK_LABEL (rom_path_widget), gui_romname);
1360:
1361: g_free (filename);
1362: }
1363:
1364: gtk_widget_destroy (pathsel);
1365: }
1366:
1367: static void did_romchange (GtkWidget *w, gpointer data)
1368: {
1369: GtkWidget *romsel;
1370:
1371: romsel = make_file_selector ("Select a ROM file",
1372: GTK_FILE_CHOOSER_ACTION_OPEN);
1373: filesel_set_path (romsel, currprefs.path_rom);
1374: if (gtk_dialog_run (GTK_DIALOG (romsel)) == GTK_RESPONSE_ACCEPT) {
1375: char *filename;
1376:
1377: filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (romsel));
1378: rom_req = 0;
1379: rom_requirements_change ();
1380:
1381: uae_sem_wait (&gui_sem);
1382: gui_romname = strdup (filename);
1383: uae_sem_post (&gui_sem);
1384: write_comm_pipe_int (&from_gui_pipe, 8, 0);
1385: gtk_label_set_text (GTK_LABEL (rom_text_widget), gui_romname);
1386:
1387: g_free (filename);
1388: }
1389:
1390: gtk_widget_destroy (romsel);
1391: }
1392:
1393: static void did_keychange (GtkWidget *w, gpointer data)
1394: {
1395: GtkWidget *keysel;
1396:
1397: keysel = make_file_selector ("Select a Kickstart key file",
1398: GTK_FILE_CHOOSER_ACTION_OPEN);
1399: filesel_set_path (keysel, currprefs.path_rom);
1400:
1401: if (gtk_dialog_run (GTK_DIALOG (keysel)) == GTK_RESPONSE_ACCEPT) {
1402: char *filename;
1403:
1404: filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (keysel));
1405: uae_sem_wait (&gui_sem);
1406: gui_keyname = strdup (filename);
1407: uae_sem_post (&gui_sem);
1408: write_comm_pipe_int (&from_gui_pipe, 9, 0);
1409: gtk_label_set_text (GTK_LABEL (key_text_widget), gui_keyname);
1410:
1411: g_free (filename);
1412: }
1413:
1414: gtk_widget_destroy (keysel);
1415: }
1416:
1417: static void add_empty_vbox (GtkWidget *tobox)
1418: {
1419: GtkWidget *thing = gtk_vbox_new (FALSE, 0);
1420: gtk_widget_show (thing);
1421: gtk_box_pack_start (GTK_BOX (tobox), thing, TRUE, TRUE, 0);
1422: }
1423:
1424: static void add_centered_to_vbox (GtkWidget *vbox, GtkWidget *w, int vexpand)
1425: {
1426: GtkWidget *hbox = gtk_hbox_new (TRUE, 0);
1427: gtk_widget_show (hbox);
1428: gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, FALSE, 0);
1429: gtk_box_pack_start (GTK_BOX (vbox), hbox, vexpand, vexpand, 0);
1430: }
1431:
1432: static GtkWidget *make_labelled_widget (const char *str, GtkWidget *thing, int expand)
1433: {
1434: GtkWidget *label = gtk_label_new (str);
1435: GtkWidget *hbox2 = gtk_hbox_new (FALSE, 4);
1436:
1437: gtk_widget_show (label);
1438: gtk_widget_show (thing);
1439:
1440: gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
1441: gtk_box_pack_start (GTK_BOX (hbox2), thing, expand, TRUE, 0);
1442:
1443: return hbox2;
1444: }
1445:
1446: static GtkWidget *add_labelled_widget_centered (const char *str, GtkWidget *thing, GtkWidget *vbox)
1447: {
1448: GtkWidget *w = make_labelled_widget (str, thing, FALSE);
1449: gtk_widget_show (w);
1450: add_centered_to_vbox (vbox, w, 0);
1451: return w;
1452: }
1453:
1454: static int make_radio_group (const char **labels, GtkWidget *tobox,
1455: GtkWidget **saveptr, gint t1, gint t2,
1456: void (*sigfunc) (void), int count, GSList *group)
1457: {
1458: int t = 0;
1459:
1460: while (*labels && (count == -1 || count-- > 0)) {
1461: GtkWidget *thing = gtk_radio_button_new_with_label (group, *labels++);
1462: group = gtk_radio_button_group (GTK_RADIO_BUTTON (thing));
1463:
1464: *saveptr++ = thing;
1465: gtk_widget_show (thing);
1466: gtk_box_pack_start (GTK_BOX (tobox), thing, t1, t2, 0);
1467: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
1468: t++;
1469: }
1470: return t;
1471: }
1472:
1473: static GtkWidget *make_radio_group_box (const char *title, const char **labels,
1474: GtkWidget **saveptr, int horiz,
1475: void (*sigfunc) (void), GtkWidget **boxp)
1476: {
1477: GtkWidget *frame, *newbox;
1478:
1479: frame = gtk_frame_new (title);
1480: newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (FALSE, 4);
1481: gtk_widget_show (newbox);
1482: gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1483: gtk_container_add (GTK_CONTAINER (frame), newbox);
1484: make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc, -1, NULL);
1485: if (boxp)
1486: *boxp = newbox;
1487: return frame;
1488: }
1489:
1490: static GtkWidget *make_radio_group_box_1 (const char *title, const char **labels,
1491: GtkWidget **saveptr, int horiz,
1492: void (*sigfunc) (void), int elts_per_column)
1493: {
1494: GtkWidget *frame, *newbox;
1495: GtkWidget *column;
1496: GSList *group = 0;
1497:
1498: frame = gtk_frame_new (title);
1499: column = (horiz ? gtk_vbox_new : gtk_hbox_new) (FALSE, 4);
1500: gtk_container_add (GTK_CONTAINER (frame), column);
1501: gtk_widget_show (column);
1502:
1503: while (*labels) {
1504: int count;
1505: newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (FALSE, 4);
1506: gtk_widget_show (newbox);
1507: gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1508: gtk_container_add (GTK_CONTAINER (column), newbox);
1509: count = make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc, elts_per_column, group);
1510: labels += count;
1511: saveptr += count;
1512: group = gtk_radio_button_group (GTK_RADIO_BUTTON (saveptr[-1]));
1513: }
1514: return frame;
1515: }
1516:
1517: static GtkWidget *make_led (int nr)
1518: {
1519: GtkWidget *subframe, *the_led, *thing;
1520: GdkColormap *colormap;
1521:
1522: the_led = gtk_vbox_new (FALSE, 0);
1523: gtk_widget_show (the_led);
1524:
1525: thing = gtk_preview_new (GTK_PREVIEW_COLOR);
1526: gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
1527: gtk_widget_show (thing);
1528:
1529: subframe = gtk_frame_new (NULL);
1530: gtk_box_pack_start (GTK_BOX (the_led), subframe, TRUE, TRUE, 0);
1531: gtk_widget_show (subframe);
1532:
1533: thing = gtk_drawing_area_new ();
1534: gtk_drawing_area_size (GTK_DRAWING_AREA (thing), 20, 5);
1535: gtk_widget_set_events (thing, GDK_EXPOSURE_MASK);
1536: gtk_container_add (GTK_CONTAINER (subframe), thing);
1537: colormap = gtk_widget_get_colormap (thing);
1538: led_on[nr].red = nr == 0 ? 0xEEEE : 0xCCCC;
1539: led_on[nr].green = nr == 0 ? 0: 0xFFFF;
1540: led_on[nr].blue = 0;
1541: led_on[nr].pixel = 0;
1542: led_off[nr].red = 0;
1543: led_off[nr].green = 0;
1544: led_off[nr].blue = 0;
1545: led_off[nr].pixel = 0;
1546: gdk_color_alloc (colormap, led_on + nr);
1547: gdk_color_alloc (colormap, led_off + nr);
1548: led_widgets[nr] = thing;
1549: gtk_signal_connect (GTK_OBJECT (thing), "event",
1550: (GtkSignalFunc) driveled_event, (gpointer) thing);
1551: gtk_widget_show (thing);
1552:
1553: thing = gtk_preview_new (GTK_PREVIEW_COLOR);
1554: gtk_box_pack_start (GTK_BOX (the_led), thing, TRUE, TRUE, 0);
1555: gtk_widget_show (thing);
1556:
1557: return the_led;
1558: }
1559:
1560: static GtkWidget *make_file_container (const char *title, GtkWidget *vbox, int vertical)
1561: {
1562: GtkWidget *thing = gtk_frame_new (title);
1563: GtkWidget *file_vbox = vertical ? gtk_vbox_new (FALSE, 4) : gtk_hbox_new (FALSE, 4);
1564:
1565: gtk_container_set_border_width (GTK_CONTAINER (file_vbox), 4);
1566: gtk_container_add (GTK_CONTAINER (thing), file_vbox);
1567: gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
1568: gtk_widget_show (file_vbox);
1569: gtk_widget_show (thing);
1570:
1571: return file_vbox;
1572: }
1573:
1574: static GtkWidget *make_file_widget (GtkWidget *buttonbox)
1575: {
1576: GtkWidget *thing, *subthing;
1577: GtkWidget *subframe = gtk_frame_new (NULL);
1578:
1579: gtk_frame_set_shadow_type (GTK_FRAME (subframe), GTK_SHADOW_ETCHED_OUT);
1580: gtk_box_pack_start (GTK_BOX (buttonbox), subframe, TRUE, TRUE, 0);
1581: gtk_widget_show (subframe);
1582: subthing = gtk_vbox_new (FALSE, 0);
1583: gtk_widget_show (subthing);
1584: gtk_container_add (GTK_CONTAINER (subframe), subthing);
1585: thing = gtk_label_new ("");
1586: gtk_widget_show (thing);
1587: gtk_box_pack_start (GTK_BOX (subthing), thing, TRUE, TRUE, 0);
1588:
1589: return thing;
1590: }
1591:
1592: static void make_floppy_disks (GtkWidget *vbox)
1593: {
1594: GtkWidget *thing, *subthing, *subframe, *buttonbox, *file_vbox;
1595: char buf[5];
1596: int i;
1597:
1598: add_empty_vbox (vbox);
1599:
1600: for (i = 0; i < 4; i++) {
1601: /* Frame with an hbox and the "DFx:" title */
1602: sprintf (buf, "DF%d:", i);
1603: file_vbox = make_file_container (buf, vbox, 1);
1604:
1605: buttonbox = gtk_hbox_new (FALSE, 4);
1606: gtk_box_pack_start (GTK_BOX (file_vbox), buttonbox, FALSE, TRUE, 0);
1607: gtk_widget_show (buttonbox);
1608:
1609: /* LED */
1610: subthing = make_led (i + 1);
1611: gtk_box_pack_start (GTK_BOX (buttonbox), subthing, FALSE, TRUE, 0);
1612:
1613: /* Current file display */
1614: disk_text_widget[i] = make_file_widget (buttonbox);
1615:
1616: /* Now, the buttons. */
1617: thing = gtk_button_new_with_label ("Eject");
1618: gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
1619: gtk_widget_show (thing);
1620: disk_eject_widget[i] = thing;
1621: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_eject,
1622: GINT_TO_POINTER (i));
1623:
1624: thing = gtk_button_new_with_label ("Insert");
1625: gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
1626: gtk_widget_show (thing);
1627: disk_insert_widget[i] = thing;
1628: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_insert,
1629: GINT_TO_POINTER (i));
1630:
1631: buttonbox = gtk_hbox_new (FALSE, 4);
1632: gtk_box_pack_start (GTK_BOX (file_vbox), buttonbox, FALSE, FALSE, 0);
1633: gtk_widget_show (buttonbox);
1634:
1635: if (i == 0)
1636: thing = make_chooser (2, "3.5 DD", "3.5 HD");
1637: else
1638: thing = make_chooser (3, "Disabled", "3.5 DD", "3.5 HD");
1639: gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) dftype_changed,
1640: GINT_TO_POINTER (i));
1641: dftype_widget[i] = thing;
1642:
1643: thing = make_labelled_widget ("Type:", thing, 0);
1644: gtk_box_pack_end (GTK_BOX (buttonbox), thing, FALSE, FALSE, 0);
1645: gtk_widget_show (thing);
1646: }
1647:
1648: add_empty_vbox (vbox);
1649: }
1650:
1651: static GtkWidget *make_cpu_speed_sel (void)
1652: {
1653: int t;
1654: static const char *labels[] = {
1655: "Optimize for host CPU speed", "Approximate 68000/7MHz speed", "Adjustable",
1656: NULL
1657: };
1658: GtkWidget *frame, *newbox;
1659:
1660: frame = gtk_frame_new ("CPU speed");
1661: newbox = gtk_vbox_new (FALSE, 4);
1662: gtk_widget_show (newbox);
1663: gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1664: gtk_container_add (GTK_CONTAINER (frame), newbox);
1665: make_radio_group (labels, newbox, cpuspeed_widgets, 0, 1, cpuspeed_changed, -1, NULL);
1666:
1667: t = currprefs.m68k_speed > 0 ? currprefs.m68k_speed : 4 * CYCLE_UNIT;
1668: cpuspeed_adj = GTK_ADJUSTMENT (gtk_adjustment_new (t, 1.0, 5120.0, 1.0, 1.0, 1.0));
1669: gtk_signal_connect (GTK_OBJECT (cpuspeed_adj), "value_changed",
1670: GTK_SIGNAL_FUNC (cpuspeed_changed), NULL);
1671:
1672: cpuspeed_scale = gtk_hscale_new (cpuspeed_adj);
1673: gtk_range_set_update_policy (GTK_RANGE (cpuspeed_scale), GTK_UPDATE_DELAYED);
1674: gtk_scale_set_digits (GTK_SCALE (cpuspeed_scale), 0);
1675: gtk_scale_set_value_pos (GTK_SCALE (cpuspeed_scale), GTK_POS_RIGHT);
1676: cpuspeed_scale = make_labelled_widget ("Cycles/insn:", cpuspeed_scale, TRUE);
1677: gtk_widget_show (cpuspeed_scale);
1678: gtk_box_pack_start (GTK_BOX (newbox), cpuspeed_scale, FALSE, FALSE, 0);
1679:
1680: return frame;
1681: }
1682:
1683: static void make_cpu_widgets (GtkWidget *vbox)
1684: {
1685: int i;
1686: GtkWidget *newbox, *hbox, *frame;
1687: GtkWidget *thing, *label;
1688: static const char *cpulabels[] = {
1689: "68000", "68010", "68EC020", "68020", "68030", "68040", "68060",
1690: NULL
1691: };
1692: static const char *fpulabels[] = {
1693: "None", "68881", "68882", "68040", "68060",
1694: NULL
1695: };
1696:
1697: add_empty_vbox (vbox);
1698:
1699: hbox = gtk_hbox_new (FALSE, 0);
1700: add_empty_vbox (hbox);
1701:
1702: newbox = make_radio_group_box ("CPU type", cpulabels, cpu_widget, 0, cputype_changed, NULL);
1703: gtk_widget_show (newbox);
1704: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
1705:
1706: newbox = make_radio_group_box ("FPU type", fpulabels, fpu_widget, 0, cputype_changed, NULL);
1707: gtk_widget_show (newbox);
1708: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
1709:
1710: newbox = make_cpu_speed_sel ();
1711: gtk_widget_show (newbox);
1712: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
1713:
1714: add_empty_vbox (hbox);
1715: gtk_widget_show (hbox);
1716: gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1717:
1718: req68ec020 = gtk_label_new ("The selected ROM requires at least a 68ec020.");
1719: add_centered_to_vbox (vbox, req68ec020, 0);
1720:
1721: req68020 = gtk_label_new ("The selected ROM requires at least a 68020.");
1722: add_centered_to_vbox (vbox, req68020, 0);
1723:
1724: req68030 = gtk_label_new ("The selected ROM requires at least a 68030.");
1725: add_centered_to_vbox (vbox, req68030, 0);
1726:
1727: add_empty_vbox (vbox);
1728:
1729: label = gtk_label_new ("CPU type settings take effect after the next reset.");
1730: gtk_widget_show (label);
1731: add_centered_to_vbox (vbox, label, 0);
1732: }
1733:
1734: static GtkWidget *make_screenmode_box (const char *title, struct scrmode_widgets *mw,
1735: struct uae_rect *modes, int n_modes)
1736: {
1737: GtkWidget *vbox;
1738: int i;
1739:
1740: mw->frame = gtk_frame_new (title);
1741: gtk_widget_show (mw->frame);
1742:
1743: vbox = gtk_vbox_new (FALSE, 10);
1744: gtk_widget_show (vbox);
1745: gtk_container_add (GTK_CONTAINER (mw->frame), vbox);
1746: gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
1747:
1748: mw->modelist = gtk_combo_box_new_text ();
1749: gtk_widget_show (mw->modelist);
1750: gtk_box_pack_start (GTK_BOX (vbox), mw->modelist, FALSE, TRUE, 0);
1751:
1752: for (i = 0; i < n_modes; i++) {
1753: char t[200];
1754: sprintf (t, "%dx%d", modes[i].w, modes[i].h);
1755: gtk_combo_box_append_text (GTK_COMBO_BOX (mw->modelist), t);
1756: }
1757: if (n_modes == 0)
1758: gtk_widget_set_sensitive (mw->frame, FALSE);
1759:
1760: mw->hcenter = make_chooser (3, "Off", "Simple", "Smart");
1761: mw->hc_label = make_labelled_widget ("Horizontal bounds detect:", mw->hcenter, TRUE);
1762: gtk_widget_show (mw->hc_label);
1763: gtk_box_pack_start (GTK_BOX (vbox), mw->hc_label, FALSE, TRUE, 0);
1764:
1765: mw->vcenter = make_chooser (3, "Off", "Simple", "Smart");
1766: mw->vc_label = make_labelled_widget ("Vertical bounds detect:", mw->vcenter, TRUE);
1767: gtk_widget_show (mw->vc_label);
1768: gtk_box_pack_start (GTK_BOX (vbox), mw->vc_label, FALSE, TRUE, 0);
1769:
1770: mw->linedbl = make_chooser (2, "Double", "Scanlines");
1771: mw->ld_label = make_labelled_widget ("Line doubling:", mw->linedbl, TRUE);
1772: gtk_widget_show (mw->ld_label);
1773: gtk_box_pack_start (GTK_BOX (vbox), mw->ld_label, FALSE, TRUE, 0);
1774:
1775: mw->aspect = gtk_check_button_new_with_label ("Correct aspect ratio");
1776: gtk_widget_show (mw->aspect);
1777: gtk_box_pack_start (GTK_BOX (vbox), mw->aspect, FALSE, TRUE, 0);
1778:
1779: mw->leds = gtk_check_button_new_with_label ("Show LEDs on screen");
1780: gtk_widget_show (mw->leds);
1781: gtk_box_pack_start (GTK_BOX (vbox), mw->leds, FALSE, TRUE, 0);
1782:
1783: gtk_signal_connect (GTK_OBJECT (mw->leds), "clicked",
1784: (GtkSignalFunc) leds_changed, NULL);
1785: gtk_signal_connect (GTK_OBJECT (mw->aspect), "clicked",
1786: (GtkSignalFunc) aspect_changed, NULL);
1787: gtk_signal_connect (GTK_OBJECT (mw->linedbl), "changed",
1788: (GtkSignalFunc) aspect_changed, NULL);
1789: gtk_signal_connect (GTK_OBJECT (mw->hcenter), "changed",
1790: (GtkSignalFunc) aspect_changed, NULL);
1791: gtk_signal_connect (GTK_OBJECT (mw->vcenter), "changed",
1792: (GtkSignalFunc) aspect_changed, NULL);
1793: gtk_signal_connect (GTK_OBJECT (mw->modelist), "changed",
1794: (GtkSignalFunc) screenmode_changed, NULL);
1795:
1796: return mw->frame;
1797: }
1798:
1799: static void make_gfx_widgets (GtkWidget *vbox)
1800: {
1801: GtkWidget *thing, *frame, *newbox, *hbox;
1802:
1803: add_empty_vbox (vbox);
1804:
1805: hbox = gtk_hbox_new (FALSE, 10);
1806: gtk_widget_show (hbox);
1807: add_centered_to_vbox (vbox, hbox, 0);
1808:
1809: thing = make_screenmode_box ("Fullscreen mode", &gw_fullscreen, gfx_fullscreen_modes, n_fullscreen_modes);
1810: gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, FALSE, 0);
1811: thing = make_screenmode_box ("Windowed mode", &gw_windowed, gfx_windowed_modes, n_windowed_modes);
1812: gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, FALSE, 0);
1813:
1814: hbox = gtk_hbox_new (FALSE, 10);
1815: gtk_widget_show (hbox);
1816: add_centered_to_vbox (vbox, hbox, 0);
1817:
1818: frame = gtk_frame_new ("Miscellaneous");
1819: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
1820:
1821: gtk_widget_show (frame);
1822: newbox = gtk_vbox_new (FALSE, 4);
1823: gtk_widget_show (newbox);
1824: gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1825: gtk_container_add (GTK_CONTAINER (frame), newbox);
1826:
1827: framerate_adj = GTK_ADJUSTMENT (gtk_adjustment_new (currprefs.gfx_framerate, 1, 21, 1, 1, 1));
1828: gtk_signal_connect (GTK_OBJECT (framerate_adj), "value_changed",
1829: GTK_SIGNAL_FUNC (custom_changed), NULL);
1830:
1831: thing = gtk_hscale_new (framerate_adj);
1832: gtk_range_set_update_policy (GTK_RANGE (thing), GTK_UPDATE_DELAYED);
1833: gtk_scale_set_digits (GTK_SCALE (thing), 0);
1834: gtk_scale_set_value_pos (GTK_SCALE (thing), GTK_POS_RIGHT);
1835: thing = make_labelled_widget ("Framerate:", thing, TRUE);
1836: gtk_widget_show (thing);
1837: gtk_box_pack_start (GTK_BOX (newbox), thing, FALSE, FALSE, 0);
1838:
1839: b32_widget = gtk_check_button_new_with_label ("32 bit blitter");
1840: add_centered_to_vbox (newbox, b32_widget, 0);
1841: #if 0
1842: gtk_widget_show (b32_widget);
1843: #endif
1844: bimm_widget = gtk_check_button_new_with_label ("Immediate blits");
1845: gtk_box_pack_start (GTK_BOX (newbox), bimm_widget, FALSE, FALSE, 0);
1846: gtk_widget_show (bimm_widget);
1847:
1848: afscr_widget = gtk_check_button_new_with_label ("Amiga modes fullscreen");
1849: gtk_box_pack_start (GTK_BOX (newbox), afscr_widget, FALSE, FALSE, 0);
1850: gtk_widget_show (afscr_widget);
1851: pfscr_widget = gtk_check_button_new_with_label ("Picasso modes fullscreen");
1852: gtk_box_pack_start (GTK_BOX (newbox), pfscr_widget, FALSE, FALSE, 0);
1853: gtk_widget_show (pfscr_widget);
1854: add_empty_vbox (vbox);
1855:
1856: gtk_signal_connect (GTK_OBJECT (bimm_widget), "clicked",
1857: (GtkSignalFunc) custom_changed, NULL);
1858: gtk_signal_connect (GTK_OBJECT (afscr_widget), "clicked",
1859: (GtkSignalFunc) custom_changed, NULL);
1860: gtk_signal_connect (GTK_OBJECT (pfscr_widget), "clicked",
1861: (GtkSignalFunc) custom_changed, NULL);
1862: #if 0
1863: gtk_signal_connect (GTK_OBJECT (b32_widget), "clicked",
1864: (GtkSignalFunc) custom_changed, NULL);
1865: #endif
1866: }
1867:
1868: static void make_chipset_widgets (GtkWidget *vbox)
1869: {
1870: GtkWidget *newbox, *hbox, *thing, *tmpbox;
1871: static const char *colllabels[] = {
1872: "None (fastest)", "Sprites only", "Sprites & playfields", "Full (very slow)",
1873: NULL
1874: };
1875: static const char *cslevellabels[] = {
1876: "OCS", "ECS Agnus", "Full ECS", "AGA", NULL
1877: };
1878: static const char *ntsclabels[] = {
1879: "PAL (European)", "NTSC (American)", NULL
1880: };
1881:
1882: add_empty_vbox (vbox);
1883:
1884: mbtype_widget = make_chooser (7, "Generic", "A1000", "A500/A2000", "A600", "A1200", "A3000", "A4000");
1885: gtk_widget_show (mbtype_widget);
1886: gtk_signal_connect (GTK_OBJECT (mbtype_widget), "changed", (GtkSignalFunc) mbtype_changed,
1887: NULL);
1888: mbtype_labelled = make_labelled_widget ("Motherboard type:", mbtype_widget, TRUE);
1889: gtk_widget_show (mbtype_labelled);
1890: add_centered_to_vbox (vbox, mbtype_labelled, 0);
1891:
1892: hbox = gtk_hbox_new (FALSE, 10);
1893: gtk_widget_show (hbox);
1894: add_centered_to_vbox (vbox, hbox, 0);
1895:
1896: newbox = make_radio_group_box ("Sprite collisions", colllabels, coll_widget, 0, coll_changed, NULL);
1897: gtk_widget_show (newbox);
1898: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
1899:
1900: newbox = make_radio_group_box ("Chipset", cslevellabels, cslevel_widget, 0, cslevel_changed, NULL);
1901: gtk_widget_show (newbox);
1902: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
1903:
1904: newbox = make_radio_group_box ("Chipset video output", ntsclabels, ntsc_widget, 0, ntsc_changed, NULL);
1905: gtk_widget_show (newbox);
1906: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
1907:
1908: reqa4000 = gtk_label_new ("The selected ROM requires at least an A4000.");
1909: add_centered_to_vbox (vbox, reqa4000, 0);
1910:
1911: reqa1000 = gtk_label_new ("The selected ROM requires an A1000 motherboard.");
1912: add_centered_to_vbox (vbox, reqa1000, 0);
1913:
1914: add_empty_vbox (vbox);
1915:
1916: thing = gtk_label_new ("Chipset type settings take effect after the next reset.");
1917: gtk_widget_show (thing);
1918: add_centered_to_vbox (vbox, thing, 0);
1919: }
1920:
1921: static void make_sound_widgets (GtkWidget *vbox)
1922: {
1923: GtkWidget *frame, *newbox;
1924: int t;
1925: GtkWidget *hbox, *inner_vbox, *outer_hbox;
1926: static const char *soundlabels1[] = {
1927: "None", "No output", "Normal", "Accurate",
1928: NULL
1929: }, *soundlabels2[] = {
1930: "None", "RH", "BS", "Sinc", "Anti",
1931: NULL
1932: }, *soundlabels3[] = {
1933: "Mono", "Stereo",
1934: NULL
1935: }, *soundlabels4[] = {
1936: "Off", "A500 (power LED)", "A500 (always on)",
1937: "A1200 (power LED)", "A1200 (always on)",
1938: NULL
1939: };
1940:
1941: add_empty_vbox (vbox);
1942:
1943: outer_hbox = gtk_hbox_new (FALSE, 0);
1944: gtk_widget_show (outer_hbox);
1945: add_centered_to_vbox (vbox, outer_hbox, 0);
1946:
1947: inner_vbox = gtk_vbox_new (FALSE, 0);
1948: gtk_widget_show (inner_vbox);
1949: gtk_box_pack_start (GTK_BOX (outer_hbox), inner_vbox, FALSE, TRUE, 0);
1950:
1951: hbox = gtk_hbox_new (FALSE, 0);
1952: add_empty_vbox (hbox);
1953:
1954: newbox = make_radio_group_box ("Mode", soundlabels1, sound_widget, 0, sound_changed, NULL);
1955: gtk_widget_show (newbox);
1956: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, FALSE, 0);
1957:
1958: frame = gtk_frame_new ("Channels");
1959: gtk_widget_show (frame);
1960: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
1961: newbox = gtk_vbox_new (FALSE, 4);
1962: gtk_widget_show (newbox);
1963: gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1964: gtk_container_add (GTK_CONTAINER (frame), newbox);
1965: make_radio_group (soundlabels3, newbox, sound_ch_widget, 0, 1, sound_changed, -1, NULL);
1966:
1967: newbox = make_radio_group_box ("Interpolation", soundlabels2, sound_interpol_widget, 0, sound_changed, NULL);
1968: gtk_widget_show (newbox);
1969: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
1970:
1971: newbox = make_radio_group_box ("Filter", soundlabels4, sound_filter_widget, 0, sound_changed, NULL);
1972: gtk_widget_show (newbox);
1973: gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
1974:
1975: add_empty_vbox (hbox);
1976: gtk_widget_show (hbox);
1977: gtk_box_pack_start (GTK_BOX (inner_vbox), hbox, FALSE, FALSE, 0);
1978:
1979: t = currprefs.sound_stereo_separation;
1980: if (t == 0)
1981: t = MIXED_STEREO_MAX;
1982: stereo_sep_adj = GTK_ADJUSTMENT (gtk_adjustment_new (t, 1, MIXED_STEREO_MAX, 1, 1, 0));
1983: gtk_signal_connect (GTK_OBJECT (stereo_sep_adj), "value_changed",
1984: GTK_SIGNAL_FUNC (sound_changed), NULL);
1985:
1986: stereo_sep_scale = gtk_hscale_new (stereo_sep_adj);
1987: gtk_range_set_update_policy (GTK_RANGE (stereo_sep_scale), GTK_UPDATE_DELAYED);
1988: gtk_scale_set_digits (GTK_SCALE (stereo_sep_scale), 0);
1989: gtk_scale_set_value_pos (GTK_SCALE (stereo_sep_scale), GTK_POS_RIGHT);
1990: stereo_sep_scale = make_labelled_widget ("Stereo separation:", stereo_sep_scale, TRUE);
1991: gtk_widget_show (stereo_sep_scale);
1992: gtk_box_pack_start (GTK_BOX (inner_vbox), stereo_sep_scale, FALSE, FALSE, 0);
1993:
1994: t = currprefs.sound_mixed_stereo_delay;
1995: stereo_delay_adj = GTK_ADJUSTMENT (gtk_adjustment_new (t, 0, SOUND_MAX_LOG_DELAY, 1, 1, 1));
1996: gtk_signal_connect (GTK_OBJECT (stereo_delay_adj), "value_changed",
1997: GTK_SIGNAL_FUNC (sound_changed), NULL);
1998:
1999: stereo_delay_scale = gtk_hscale_new (stereo_delay_adj);
2000: gtk_range_set_update_policy (GTK_RANGE (stereo_delay_scale), GTK_UPDATE_DELAYED);
2001: gtk_scale_set_digits (GTK_SCALE (stereo_delay_scale), 0);
2002: gtk_scale_set_value_pos (GTK_SCALE (stereo_delay_scale), GTK_POS_RIGHT);
2003: stereo_delay_scale = make_labelled_widget ("Stereo mixing delay:", stereo_delay_scale, TRUE);
2004: gtk_widget_show (stereo_delay_scale);
2005: gtk_box_pack_start (GTK_BOX (inner_vbox), stereo_delay_scale, FALSE, FALSE, 0);
2006:
2007: add_empty_vbox (vbox);
2008: }
2009:
2010: static void make_rom_widgets (GtkWidget *dvbox)
2011: {
2012: GtkWidget *hbox = gtk_hbox_new (FALSE, 10);
2013: GtkWidget *label, *frame;
2014:
2015: rom_req = 0;
2016:
2017: add_empty_vbox (dvbox);
2018:
2019: {
2020: GtkWidget *buttonbox = make_file_container ("ROM search path:", dvbox, 0);
2021: GtkWidget *thing = gtk_button_new_with_label ("Change");
2022:
2023: /* Current file display */
2024: rom_path_widget = make_file_widget (buttonbox);
2025:
2026: gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
2027: gtk_widget_show (thing);
2028: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_rompathchange, 0);
2029: }
2030:
2031: {
2032: GtkWidget *buttonbox = make_file_container ("Kickstart ROM file:", dvbox, 1);
2033: GtkWidget *hbox, *thing;
2034:
2035: romlist_widget = gtk_combo_box_new_text ();
2036: gtk_widget_show (romlist_widget);
2037: gtk_box_pack_start (GTK_BOX (buttonbox), romlist_widget, FALSE, TRUE, 0);
2038: gtk_combo_box_append_text (GTK_COMBO_BOX (romlist_widget),
2039: "Manually select a ROM file");
2040: romlist_nr_entries = 1;
2041: gtk_signal_connect (GTK_OBJECT (romlist_widget), "changed", (GtkSignalFunc) rom_combo_changed, 0);
2042:
2043: hbox = gtk_hbox_new (FALSE, 0);
2044: gtk_box_pack_start (GTK_BOX (buttonbox), hbox, FALSE, TRUE, 0);
2045: gtk_widget_show (hbox);
2046:
2047: /* Current file display */
2048: rom_text_widget = make_file_widget (hbox);
2049:
2050: romsel_button = gtk_button_new_with_label ("Change");
2051: gtk_box_pack_start (GTK_BOX (hbox), romsel_button, FALSE, TRUE, 0);
2052: gtk_widget_show (romsel_button);
2053: gtk_signal_connect (GTK_OBJECT (romsel_button), "clicked", (GtkSignalFunc) did_romchange, 0);
2054: }
2055:
2056: {
2057: GtkWidget *buttonbox = make_file_container ("ROM key file for Cloanto Amiga Forever:", dvbox, 0);
2058: GtkWidget *thing = gtk_button_new_with_label ("Change");
2059:
2060: /* Current file display */
2061: key_text_widget = make_file_widget (buttonbox);
2062:
2063: gtk_box_pack_start (GTK_BOX (buttonbox), thing, FALSE, TRUE, 0);
2064: gtk_widget_show (thing);
2065: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_keychange, 0);
2066: }
2067:
2068: label = gtk_label_new ("These settings take effect after the next reset.");
2069: gtk_widget_show (label);
2070: add_centered_to_vbox (dvbox, label, 0);
2071:
2072: add_empty_vbox (dvbox);
2073: }
2074:
2075: static void make_ram_widgets (GtkWidget *dvbox)
2076: {
2077: GtkWidget *hbox = gtk_hbox_new (FALSE, 10);
2078: GtkWidget *label, *frame;
2079:
2080: static const char *chiplabels[] = {
2081: "512 KB", "1 MB", "2 MB", "4 MB", "8 MB", NULL
2082: };
2083: static const char *bogolabels[] = {
2084: "None", "512 KB", "1 MB", "1.8 MB", NULL
2085: };
2086: static const char *fastlabels[] = {
2087: "None", "1 MB", "2 MB", "4 MB", "8 MB", NULL
2088: };
2089: static const char *z3labels[] = {
2090: "None", "1 MB", "2 MB", "4 MB", "8 MB",
2091: "16 MB", "32 MB", "64 MB", "128 MB", "256 MB",
2092: NULL
2093: };
2094: static const char *p96labels[] = {
2095: "None", "1 MB", "2 MB", "4 MB", "8 MB", "16 MB", "32 MB", NULL
2096: };
2097:
2098: add_empty_vbox (dvbox);
2099:
2100: gtk_widget_show (hbox);
2101: add_centered_to_vbox (dvbox, hbox, 0);
2102:
2103: add_empty_vbox (dvbox);
2104:
2105: label = gtk_label_new ("These settings take effect after the next reset.");
2106: gtk_widget_show (label);
2107: add_centered_to_vbox (dvbox, label, 0);
2108:
2109: frame = make_radio_group_box ("Chip Mem", chiplabels, chipsize_widget, 0, chipsize_changed, NULL);
2110: gtk_widget_show (frame);
2111: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
2112:
2113: frame = make_radio_group_box ("Slow Mem", bogolabels, bogosize_widget, 0, bogosize_changed, NULL);
2114: gtk_widget_show (frame);
2115: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
2116:
2117: frame = make_radio_group_box ("Fast Mem", fastlabels, fastsize_widget, 0, fastsize_changed, NULL);
2118: gtk_widget_show (frame);
2119: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
2120:
2121: frame = make_radio_group_box_1 ("Z3 Mem", z3labels, z3size_widget, 0, z3size_changed, 5);
2122: gtk_widget_show (frame);
2123: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
2124:
2125: frame = make_radio_group_box_1 ("P96 RAM", p96labels, p96size_widget, 0, p96size_changed, 4);
2126: gtk_widget_show (frame);
2127: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
2128: }
2129:
2130: static void make_joy_widgets (GtkWidget *dvbox)
2131: {
2132: int i;
2133: GtkWidget *hbox = gtk_hbox_new (FALSE, 10);
2134: GtkWidget *thing;
2135: static const char *joylabels[] = {
2136: "Joystick 0", "Joystick 1", "Mouse", "Numeric pad",
2137: "Cursor keys/Right Ctrl", "T/F/H/B/Left Alt",
2138: NULL
2139: };
2140:
2141: add_empty_vbox (dvbox);
2142: gtk_widget_show (hbox);
2143: add_centered_to_vbox (dvbox, hbox, 0);
2144:
2145: legacy_widget = gtk_check_button_new_with_label ("Use legacy configuration");
2146: add_centered_to_vbox (dvbox, legacy_widget, 0);
2147: gtk_widget_show (legacy_widget);
2148: gtk_signal_connect (GTK_OBJECT (legacy_widget), "clicked",
2149: (GtkSignalFunc) joy_changed, NULL);
2150:
2151: for (i = 0; i < 2; i++) {
2152: GtkWidget *vbox, *frame;
2153: char buffer[20];
2154: int j;
2155:
2156: sprintf (buffer, "Port %d", i);
2157: frame = make_radio_group_box (buffer, joylabels, joy_widget[i], 0, joy_changed, NULL);
2158: gtk_widget_show (frame);
2159: gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
2160: }
2161:
2162: thing = make_chooser (7, "English (QWERTY)", "Danish", "Deutsch (QWERTZ)", "Swedish",
2163: "Francais (AZERTY)", "Italian", "Spanish");
2164: gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) kbdlang_changed,
2165: GINT_TO_POINTER (i));
2166: kbdlang_widget = thing;
2167: thing = add_labelled_widget_centered ("Keyboard language:", thing, dvbox);
2168:
2169: add_empty_vbox (dvbox);
2170: }
2171:
2172: static GtkWidget *leftalign (GtkWidget *thing)
2173: {
2174: GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
2175: gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, FALSE, 0);
2176: return hbox;
2177: }
2178:
2179: static GtkWidget *create_dirdlg (const char *title, int row)
2180: {
2181: GtkWidget *vbox, *pathsel, *dirdlg;
2182: GtkWidget *path_entry, *volname_entry, *pri_entry;
2183:
2184: dirdlg = gtk_dialog_new_with_buttons (title, GTK_WINDOW (gui_window),
2185: GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
2186: GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
2187: GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
2188: NULL);
2189:
2190: gtk_window_set_position (GTK_WINDOW (dirdlg), GTK_WIN_POS_MOUSE);
2191:
2192: vbox = GTK_DIALOG (dirdlg)->vbox;
2193:
2194: pathsel = make_file_selector ("Select a path to mount",
2195: GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
2196:
2197: gtkutil_add_table (GTK_WIDGET (vbox),
2198: leftalign (gtk_label_new ("Path:")), 1, 1, GTK_FILL,
2199: leftalign (path_entry = gtk_file_chooser_button_new_with_dialog (pathsel)), 2, 1, GTK_FILL,
2200: GTKUTIL_ROW_END,
2201: leftalign (gtk_label_new ("Volume name:")), 1, 1, GTK_FILL,
2202: leftalign (volname_entry = gtk_entry_new_with_max_length (32)), 2, 1, GTK_FILL,
2203: GTKUTIL_ROW_END,
2204: leftalign (gtk_label_new ("Boot priority:")), 1, 1, GTK_FILL,
2205: leftalign (pri_entry = gtk_entry_new_with_max_length (2)), 2, 1, GTK_FILL,
2206: GTKUTIL_TABLE_END);
2207:
2208: if (row != -1) {
2209: char *failure;
2210: char t[20];
2211: int secspertrack, surfaces, reserved, blocksize, size;
2212: int cylinders, readonly, pri;
2213: char *volname, *rootdir, *devname;
2214:
2215: failure = get_filesys_unit (currprefs.mountinfo, row,
2216: &devname, &volname, &rootdir, &readonly,
2217: &secspertrack, &surfaces, &reserved,
2218: &cylinders, &size, &blocksize, &pri);
2219: if (failure) {
2220: mkmsgbox ("Error", failure);
2221: goto out;
2222: }
2223: gtk_entry_set_text (GTK_ENTRY (volname_entry), volname);
2224: gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (path_entry), rootdir);
2225: sprintf (t, "%d", pri);
2226: gtk_entry_set_text (GTK_ENTRY (pri_entry), t);
2227: if (volname)
2228: free (volname);
2229: if (devname)
2230: free (devname);
2231: if (rootdir)
2232: free (rootdir);
2233: }
2234:
2235: retry:
2236: if (gtk_dialog_run (GTK_DIALOG (dirdlg)) == GTK_RESPONSE_ACCEPT) {
2237: const char *failure;
2238: const char *pathname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (path_entry));
2239: const char *volname = gtk_entry_get_text (GTK_ENTRY (volname_entry));
2240: const char *bprstr = gtk_entry_get_text (GTK_ENTRY (pri_entry));
2241: char fixed_volname[256];
2242: int n, bpr;
2243:
2244: if (pathname == NULL || strlen (pathname) == 0 || access (pathname, R_OK) != 0) {
2245: mkmsgbox ("Error", "You must select a valid path.");
2246: goto retry;
2247: }
2248: n = volname == NULL ? 0 : strlen (volname);
2249: if (n > 255) {
2250: mkmsgbox ("Error", "Volume name too long.");
2251: goto retry;
2252: }
2253: /* Strip colons from the end. */
2254: if (n > 0) {
2255: strcpy (fixed_volname, volname);
2256: if (fixed_volname[n - 1] == ':') {
2257: fixed_volname[n - 1] = '\0';
2258: n--;
2259: }
2260: }
2261:
2262: if (n == 0) {
2263: mkmsgbox ("Error", "You must enter a volume name.");
2264: goto retry;
2265: }
2266:
2267: if (strlen (bprstr) == 0) {
2268: mkmsgbox ("Error", "You must enter a valid number of surfaces.");
2269: goto retry;
2270: }
2271: bpr = atoi (bprstr);
2272:
2273: if (row == -1) {
2274: failure = add_filesys_unit (currprefs.mountinfo, NULL, fixed_volname, pathname,
2275: 0, 0, 0, 0, 0, bpr);
2276: } else {
2277: failure = set_filesys_unit (currprefs.mountinfo, row, NULL, fixed_volname, pathname,
2278: 0, 0, 0, 0, 0, bpr);
2279: }
2280: if (failure) {
2281: mkmsgbox ("Error", failure);
2282: goto retry;
2283: }
2284: set_hd_state ();
2285: }
2286:
2287: out:
2288: gtk_widget_destroy (dirdlg);
2289: return 0;
2290: }
2291:
2292: static void create_hdfdlg (const char *title, int row)
2293: {
2294: GtkWidget *vbox, *pathsel;
2295: GtkWidget *hdfdlg;
2296: static GtkWidget *bpt_entry, *surfaces_entry, *pri_entry;
2297: static GtkWidget *blocksize_entry, *reserved_entry, *path_entry;
2298:
2299: int readonly = 0;
2300:
2301: hdfdlg = gtk_dialog_new_with_buttons (title, GTK_WINDOW (gui_window),
2302: GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
2303: GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
2304: GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
2305: NULL);
2306:
2307: gtk_window_set_position (GTK_WINDOW (hdfdlg), GTK_WIN_POS_MOUSE);
2308:
2309: pathsel = make_file_selector ("Select a path to mount",
2310: GTK_FILE_CHOOSER_ACTION_OPEN);
2311:
2312: vbox = GTK_DIALOG (hdfdlg)->vbox;
2313:
2314: gtkutil_add_table (GTK_WIDGET (vbox),
2315: leftalign (gtk_label_new ("File:")), 1, 1, GTK_FILL,
2316: leftalign (path_entry = gtk_file_chooser_button_new_with_dialog (pathsel)), 2, 1, GTK_FILL,
2317: GTKUTIL_ROW_END,
2318: leftalign (gtk_label_new ("Reserved blocks:")), 1, 1, GTK_FILL,
2319: leftalign (reserved_entry = gtk_entry_new_with_max_length (6)), 2, 1, GTK_FILL,
2320: GTKUTIL_ROW_END,
2321: leftalign (gtk_label_new ("Surfaces:")), 1, 1, GTK_FILL,
2322: leftalign (surfaces_entry = gtk_entry_new_with_max_length (2)), 2, 1, GTK_FILL,
2323: GTKUTIL_ROW_END,
2324: leftalign (gtk_label_new ("Blocksize:")), 1, 1, GTK_FILL,
2325: leftalign (blocksize_entry = gtk_entry_new_with_max_length (6)), 2, 1, GTK_FILL,
2326: GTKUTIL_ROW_END,
2327: leftalign (gtk_label_new ("Blocks per track:")), 1, 1, GTK_FILL,
2328: leftalign (bpt_entry = gtk_entry_new_with_max_length (6)), 2, 1, GTK_FILL,
2329: GTKUTIL_ROW_END,
2330: leftalign (gtk_label_new ("Boot priority:")), 1, 1, GTK_FILL,
2331: leftalign (pri_entry = gtk_entry_new_with_max_length (2)), 2, 1, GTK_FILL,
2332:
2333: GTKUTIL_TABLE_END);
2334:
2335: gtk_file_chooser_button_set_width_chars (GTK_FILE_CHOOSER_BUTTON (path_entry), 40);
2336:
2337: if (row != -1) {
2338: char *failure;
2339: char *devname, *volname, *rootdir;
2340: int secspertrack, surfaces, reserved, blocksize, size;
2341: int cylinders, pri;
2342: char t[20];
2343:
2344: failure = get_filesys_unit (currprefs.mountinfo, row,
2345: &devname, &volname, &rootdir, &readonly,
2346: &secspertrack, &surfaces, &reserved,
2347: &cylinders, &size, &blocksize, &pri);
2348: if (failure) {
2349: mkmsgbox ("Error", failure);
2350: goto out;
2351: }
2352: gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (path_entry), rootdir);
2353: sprintf (t, "%d", blocksize);
2354: gtk_entry_set_text (GTK_ENTRY (blocksize_entry), t);
2355: sprintf (t, "%d", secspertrack);
2356: gtk_entry_set_text (GTK_ENTRY (bpt_entry), t);
2357: sprintf (t, "%d", surfaces);
2358: gtk_entry_set_text (GTK_ENTRY (surfaces_entry), t);
2359: sprintf (t, "%d", reserved);
2360: gtk_entry_set_text (GTK_ENTRY (reserved_entry), t);
2361: sprintf (t, "%d", pri);
2362: gtk_entry_set_text (GTK_ENTRY (pri_entry), t);
2363: if (volname)
2364: free (volname);
2365: if (devname)
2366: free (devname);
2367: if (rootdir)
2368: free (rootdir);
2369: }
2370:
2371: retry:
2372: if (gtk_dialog_run (GTK_DIALOG (hdfdlg)) == GTK_RESPONSE_ACCEPT) {
2373: const char *failure;
2374: const char *new_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (path_entry));
2375: const char *bptstr = gtk_entry_get_text (GTK_ENTRY (bpt_entry));
2376: const char *sfstr = gtk_entry_get_text (GTK_ENTRY (surfaces_entry));
2377: const char *bsstr = gtk_entry_get_text (GTK_ENTRY (blocksize_entry));
2378: const char *rsrvstr = gtk_entry_get_text (GTK_ENTRY (reserved_entry));
2379: const char *bprstr = gtk_entry_get_text (GTK_ENTRY (pri_entry));
2380: int n, sf, bpt, bs, rsrv, bpr;
2381:
2382: if (new_filename == NULL || strlen (new_filename) == 0) {
2383: mkmsgbox ("Error", "You must enter a valid filename.");
2384: goto retry;
2385: }
2386:
2387: if (strlen (bptstr) == 0 || (bpt = atoi (bptstr)) == 0) {
2388: mkmsgbox ("Error", "You must enter a valid number of blocks per track.");
2389: goto retry;
2390: }
2391: if (strlen (rsrvstr) == 0) {
2392: mkmsgbox ("Error", "You must enter the number of reserved blocks.");
2393: goto retry;
2394: }
2395: rsrv = atoi (rsrvstr);
2396: if (strlen (sfstr) == 0 || (sf = atoi (sfstr)) == 0) {
2397: mkmsgbox ("Error", "You must enter a valid number of surfaces.");
2398: goto retry;
2399: }
2400: if (strlen (bsstr) == 0 || (bs = atoi (bsstr)) == 0) {
2401: mkmsgbox ("Error", "You must enter a valid number of surfaces.");
2402: goto retry;
2403: }
2404: if (strlen (bprstr) == 0) {
2405: mkmsgbox ("Error", "You must enter a valid number of surfaces.");
2406: goto retry;
2407: }
2408: bpr = atoi (bprstr);
2409:
2410: if (row == -1) {
2411: failure = add_filesys_unit (currprefs.mountinfo, NULL, NULL, new_filename,
2412: readonly, bpt, sf, rsrv, bs, bpr);
2413: } else {
2414: failure = set_filesys_unit (currprefs.mountinfo, row, NULL, NULL, new_filename,
2415: readonly, bpt, sf, rsrv, bs, bpr);
2416: }
2417: if (failure) {
2418: mkmsgbox ("Error", failure);
2419: goto retry;
2420: }
2421: set_hd_state ();
2422: }
2423: out:
2424: gtk_widget_destroy (hdfdlg);
2425: return;
2426: }
2427:
2428: static void did_newdir (void)
2429: {
2430: create_dirdlg ("Add a new mounted directory", -1);
2431: }
2432:
2433: static void did_newhdf (void)
2434: {
2435: create_hdfdlg ("Add a new hardfile", -1);
2436: }
2437:
2438: static void did_newadf (void)
2439: {
2440: make_disk_selector ();
2441:
2442: if (gtk_dialog_run (GTK_DIALOG (disk_selector)) == GTK_RESPONSE_ACCEPT) {
2443: char *filename;
2444: struct zfile *f;
2445: filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (disk_selector));
2446:
2447: f = zfile_open (filename, "rb");
2448: if (f) {
2449: const char *failure;
2450: char buf[512];
2451: long size;
2452: zfile_fread (buf, 1, 512, f);
2453: zfile_fseek (f, 0, SEEK_END);
2454: size = zfile_ftell (f);
2455: if (buf[0] != 'D' || buf[1] != 'O' || buf[2] != 'S'
2456: || (buf[3] != 0 && buf[3] != 1)
2457: || size != 901120)
2458: {
2459: mkmsgbox ("Error", "Not an ADF diskfile.");
2460: } else {
2461: failure = add_filesys_unit (currprefs.mountinfo, NULL, NULL, filename,
2462: 0, 11, 2, 2, 512, -2);
2463: if (failure)
2464: mkmsgbox ("Error", failure);
2465: else
2466: set_hd_state ();
2467: }
2468: zfile_fclose (f);
2469: }
2470:
2471: g_free (filename);
2472: }
2473:
2474: gtk_widget_hide (disk_selector);
2475: }
2476:
2477: static void did_hdchange (void)
2478: {
2479: GtkTreeIter iter;
2480: GtkTreeModel *model;
2481: int idx;
2482:
2483: if (gtk_tree_selection_get_selected (hd_selection, &model, &iter))
2484: gtk_tree_model_get (model, &iter, 0, &idx, -1);
2485: else
2486: return;
2487:
2488: if (is_hardfile (currprefs.mountinfo, idx)) {
2489: create_hdfdlg ("Change a hardfile", idx);
2490: } else {
2491: create_dirdlg ("Change a mounted directory", idx);
2492: }
2493: }
2494: static void did_hddel (void)
2495: {
2496: GtkTreeIter iter;
2497: GtkTreeModel *model;
2498: int idx;
2499:
2500: if (gtk_tree_selection_get_selected (hd_selection, &model, &iter))
2501: gtk_tree_model_get (model, &iter, 0, &idx, -1);
2502: else
2503: return;
2504:
2505: kill_filesys_unit (currprefs.mountinfo, idx);
2506: set_hd_state ();
2507: }
2508:
2509: static void hdsel_changed (GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,
2510: gpointer user_data)
2511: {
2512: GtkTreeIter iter;
2513: GtkTreeModel *model;
2514:
2515: if (gtk_tree_selection_get_selected (hd_selection, &model, &iter)) {
2516: gtk_widget_set_sensitive (hdchange_button, TRUE);
2517: gtk_widget_set_sensitive (hddel_button, TRUE);
2518: } else {
2519: gtk_widget_set_sensitive (hdchange_button, FALSE);
2520: gtk_widget_set_sensitive (hddel_button, FALSE);
2521: }
2522: }
2523:
2524: static void hdunselect (GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,
2525: gpointer user_data)
2526: {
2527: gtk_widget_set_sensitive (hdchange_button, FALSE);
2528: gtk_widget_set_sensitive (hddel_button, FALSE);
2529: }
2530:
2531: static void preset_changed (GtkTreeSelection *selection, gpointer data)
2532: {
2533: GtkTreeIter iter;
2534: GtkTreeModel *model;
2535:
2536: if (gtk_tree_selection_get_selected (selection, &model, &iter))
2537: gtk_widget_set_sensitive (preset_button, TRUE);
2538: else
2539: gtk_widget_set_sensitive (preset_button, FALSE);
2540: }
2541:
2542: static void did_set_preset (void)
2543: {
2544: GtkTreeIter iter;
2545: GtkTreeModel *model;
2546: gchar *filename;
2547:
2548: if (gtk_tree_selection_get_selected (preset_selection, &model, &iter)) {
2549: gtk_tree_model_get (model, &iter, 1, &filename, -1);
2550:
2551: if (filename) {
2552: cfgfile_load (&changed_prefs, filename);
2553: set_widgets_from_config ();
2554: }
2555: g_free (filename);
2556: }
2557: }
2558:
2559: static GtkWidget *make_buttons_1 (const char *label, GtkWidget *box, void (*sigfunc) (void),
2560: GtkWidget *(*create)(const char *label), int expand)
2561: {
2562: GtkWidget *thing = create (label);
2563: gtk_widget_show (thing);
2564: gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
2565: gtk_box_pack_start (GTK_BOX (box), thing, expand, expand, 0);
2566:
2567: return thing;
2568: }
2569: #define make_buttons(label, box, sigfunc, create) make_buttons_1(label, box, sigfunc, create, 1)
2570: #define make_button(label, box, sigfunc) make_buttons(label, box, sigfunc, gtk_button_new_with_label)
2571:
2572: static void new_text_cell_renderer (GtkWidget *treeview, const char *title, int colnr,
2573: int expand, int ellipsize)
2574: {
2575: GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
2576: GtkTreeViewColumn *column;
2577: column = gtk_tree_view_column_new_with_attributes (title, renderer,
2578: "text", colnr, NULL);
2579: gtk_tree_view_column_set_expand (column, expand);
2580: gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
2581: if (ellipsize)
2582: g_object_set (renderer,
2583: "ellipsize", PANGO_ELLIPSIZE_START,
2584: "ellipsize-set", TRUE,
2585: NULL);
2586: }
2587:
2588: static void make_hd_widgets (GtkWidget *dvbox)
2589: {
2590: GtkCellRenderer *renderer;
2591: GtkTreeViewColumn *column;
2592: GtkAdjustment *adj;
2593: GtkWidget *scrolled, *buttonbox, *vbox, *hbox;
2594: int i;
2595:
2596: hd_store = gtk_list_store_new (11,
2597: G_TYPE_INT,
2598: G_TYPE_STRING, G_TYPE_STRING,
2599: G_TYPE_BOOLEAN,
2600: G_TYPE_STRING, G_TYPE_STRING,
2601: G_TYPE_STRING, G_TYPE_STRING,
2602: G_TYPE_STRING, G_TYPE_STRING,
2603: G_TYPE_INT);
2604:
2605: #if 0
2606: add_empty_vbox (dvbox);
2607: #endif
2608:
2609: hbox = gtk_hbox_new (FALSE, 0);
2610: gtk_box_pack_start (GTK_BOX (dvbox), hbox, TRUE, TRUE, 20);
2611: gtk_widget_show (hbox);
2612:
2613: vbox = gtk_vbox_new (FALSE, 4);
2614: gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
2615: gtk_widget_show (vbox);
2616:
2617: hdlist_widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (hd_store));
2618:
2619: new_text_cell_renderer (hdlist_widget, "Volume", 1, 0, 0);
2620: new_text_cell_renderer (hdlist_widget, "Path/File", 2, 1, 1);
2621:
2622: renderer = gtk_cell_renderer_toggle_new ();
2623: column = gtk_tree_view_column_new_with_attributes ("R/O", renderer,
2624: "active", 3, NULL);
2625: gtk_tree_view_column_set_expand (column, 0);
2626: gtk_tree_view_append_column (GTK_TREE_VIEW (hdlist_widget), column);
2627:
2628: new_text_cell_renderer (hdlist_widget, "Heads", 4, 0, 0);
2629: new_text_cell_renderer (hdlist_widget, "Cyl.", 5, 0, 0);
2630: new_text_cell_renderer (hdlist_widget, "Sec.", 6, 0, 0);
2631: new_text_cell_renderer (hdlist_widget, "Rsrvd", 7, 0, 0);
2632: new_text_cell_renderer (hdlist_widget, "Size", 8, 0, 0);
2633: new_text_cell_renderer (hdlist_widget, "Blksize", 9, 0, 0);
2634: new_text_cell_renderer (hdlist_widget, "Pri", 10, 0, 0);
2635:
2636: gtk_widget_show (hdlist_widget);
2637:
2638: scrolled = gtk_scrolled_window_new (NULL, NULL);
2639: gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
2640: GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2641: gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
2642: gtk_widget_show (scrolled);
2643:
2644: gtk_container_add (GTK_CONTAINER (scrolled), hdlist_widget);
2645:
2646: hd_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (hdlist_widget));
2647: gtk_tree_selection_set_mode (hd_selection, GTK_SELECTION_SINGLE);
2648: g_signal_connect (G_OBJECT (hd_selection), "changed",
2649: G_CALLBACK (hdsel_changed), NULL);
2650:
2651: /* The buttons */
2652: buttonbox = gtk_hbox_new (FALSE, 4);
2653: gtk_widget_show (buttonbox);
2654: gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, FALSE, 0);
2655: make_button ("New filesystem...", buttonbox, did_newdir);
2656: make_button ("New hardfile...", buttonbox, did_newhdf);
2657: make_button ("Mount floppy as HD...", buttonbox, did_newadf);
2658:
2659: buttonbox = gtk_hbox_new (FALSE, 4);
2660: gtk_widget_show (buttonbox);
2661: gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, FALSE, 0);
2662: hdchange_button = make_button ("Change...", buttonbox, did_hdchange);
2663: hddel_button = make_button ("Delete", buttonbox, did_hddel);
2664:
2665: bootrom_widget = gtk_check_button_new_with_label ("Enable bootrom - needed for filesystem, Picasso96 and better mouse support;\ndisable only in case of (unlikely) compatibility issues");
2666: add_centered_to_vbox (dvbox, bootrom_widget, 0);
2667: gtk_widget_show (bootrom_widget);
2668: gtk_signal_connect (GTK_OBJECT (bootrom_widget), "clicked",
2669: (GtkSignalFunc) bootrom_changed, NULL);
2670: #if 0
2671: add_empty_vbox (dvbox);
2672: #endif
2673: }
2674:
2675: static void make_presets (GtkWidget *dvbox)
2676: {
2677: GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
2678: GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
2679: GtkTreeViewColumn *column;
2680: GtkWidget *scrolled, *buttonbox, *vbox, *hbox;
2681: int i;
2682:
2683: add_empty_vbox (dvbox);
2684:
2685: hbox = gtk_hbox_new (FALSE, 0);
2686: gtk_box_pack_start (GTK_BOX (dvbox), hbox, TRUE, TRUE, 0);
2687: gtk_widget_show (hbox);
2688:
2689: add_empty_vbox (hbox);
2690:
2691: vbox = gtk_vbox_new (FALSE, 4);
2692: gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
2693: gtk_widget_show (vbox);
2694:
2695: for (i = 0; i < n_predef_configs; i++) {
2696: GtkTreeIter iter;
2697: gtk_list_store_append (store, &iter);
2698:
2699: gtk_list_store_set (store, &iter,
2700: 0, predef_configs[i].description,
2701: 1, predef_configs[i].filename,
2702: -1);
2703: }
2704: preset_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
2705: gtk_widget_show (preset_list);
2706:
2707: new_text_cell_renderer (preset_list, "Hardware configuration presets", 0, 1, 0);
2708:
2709: scrolled = gtk_scrolled_window_new (NULL, NULL);
2710: gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
2711: GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2712: gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
2713: gtk_widget_show (scrolled);
2714:
2715: gtk_container_add (GTK_CONTAINER (scrolled), preset_list);
2716:
2717: preset_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (preset_list));
2718: gtk_tree_selection_set_mode (preset_selection, GTK_SELECTION_SINGLE);
2719: g_signal_connect (G_OBJECT (preset_selection), "changed",
2720: G_CALLBACK (preset_changed),
2721: NULL);
2722:
2723: /* The buttons */
2724: buttonbox = gtk_hbox_new (FALSE, 4);
2725: gtk_widget_show (buttonbox);
2726: gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, FALSE, 0);
2727: preset_button = make_buttons_1 ("Set configuration to chosen preset", buttonbox, did_set_preset,
2728: gtk_button_new_with_label, 0);
2729:
2730: add_empty_vbox (hbox);
2731:
2732: add_empty_vbox (dvbox);
2733: }
2734:
2735: static void make_about_widgets (GtkWidget *dvbox)
2736: {
2737: GtkWidget *lab_version;
2738: GtkStyle *style;
2739: GdkFont *font;
2740: char t[20];
2741:
2742: add_empty_vbox (dvbox);
2743:
2744: sprintf (t, "%s %s", PACKAGE_NAME, PACKAGE_VERSION);
2745: lab_version = gtk_label_new (t);
2746: lab_info = gtk_label_new ("Choose your settings, then deselect the Pause button to start!");
2747:
2748: style = gtk_style_copy (GTK_WIDGET (lab_version)->style);
2749: pango_font_description_free (style->font_desc);
2750: style->font_desc = pango_font_description_from_string ("Sans 24");
2751: gtk_widget_set_style (lab_version, style);
2752:
2753: add_centered_to_vbox (dvbox, lab_version, 0);
2754: add_centered_to_vbox (dvbox, lab_info, 0);
2755: gtk_widget_show (lab_version);
2756: if (currprefs.start_gui == 1)
2757: gtk_widget_show (lab_info);
2758:
2759: add_empty_vbox (dvbox);
2760: }
2761:
2762: static void create_guidlg (void)
2763: {
2764: GtkWidget *window;
2765: GtkWidget *buttonbox, *vbox, *hbox;
2766: GtkWidget *thing;
2767: unsigned int i;
2768: int argc = 1;
2769: char *a[] = {"UAE"};
2770: char **argv = a;
2771: static const struct _pages {
2772: const char *title;
2773: void (*createfunc)(GtkWidget *);
2774: } pages[] = {
2775: /* ??? If this isn't the first page, there are errors in draw_led. */
2776: { "Floppies", make_floppy_disks },
2777: { "ROM", make_rom_widgets },
2778: { "RAM", make_ram_widgets },
2779: { "CPU", make_cpu_widgets },
2780: { "Graphics", make_gfx_widgets },
2781: { "Chipset", make_chipset_widgets },
2782: { "Sound", make_sound_widgets },
2783: { "Input devices", make_joy_widgets },
2784: { "Harddisks", make_hd_widgets },
2785: { "Presets", make_presets },
2786: { "About", make_about_widgets }
2787: };
2788:
2789: gtk_init (&argc, &argv);
2790: gtk_rc_parse ("uaegtkrc");
2791:
2792: gui_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2793: gtk_window_set_title (GTK_WINDOW (gui_window), "UAE control");
2794:
2795: gtk_signal_connect (GTK_OBJECT (gui_window), "delete_event",
2796: GTK_SIGNAL_FUNC (gui_delete_event), NULL);
2797:
2798: vbox = gtk_vbox_new (FALSE, 4);
2799: gtk_container_add (GTK_CONTAINER (gui_window), vbox);
2800: gtk_container_set_border_width (GTK_CONTAINER (gui_window), 10);
2801:
2802: /* First line - buttons and power LED */
2803: hbox = gtk_hbox_new (FALSE, 10);
2804: gtk_widget_show (hbox);
2805: gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2806:
2807: /* The buttons */
2808: buttonbox = gtk_hbox_new (TRUE, 4);
2809: gtk_widget_show (buttonbox);
2810: gtk_box_pack_start (GTK_BOX (hbox), buttonbox, TRUE, TRUE, 0);
2811: make_button ("Reset", buttonbox, did_reset);
2812: make_button ("Debug", buttonbox, did_debug);
2813: make_button ("Quit", buttonbox, did_quit);
2814: make_button ("Save config", buttonbox, save_config);
2815: pause_uae_widget = make_buttons ("Pause", buttonbox, pause_uae, gtk_toggle_button_new_with_label);
2816:
2817: /* The LED */
2818: thing = make_led (0);
2819: thing = make_labelled_widget ("Power:", thing, FALSE);
2820: gtk_widget_show (thing);
2821: gtk_box_pack_start (GTK_BOX (hbox), thing, FALSE, TRUE, 0);
2822:
2823: /* More buttons */
2824: buttonbox = gtk_hbox_new (TRUE, 4);
2825: gtk_widget_show (buttonbox);
2826: gtk_box_pack_start (GTK_BOX (vbox), buttonbox, TRUE, TRUE, 0);
2827: snap_save_widget = make_button ("Save state", buttonbox, did_savestate);
2828: snap_load_widget = make_button ("Load state", buttonbox, did_loadstate);
2829:
2830: /* Place a separator below those buttons. */
2831: thing = gtk_hseparator_new ();
2832: gtk_box_pack_start (GTK_BOX (vbox), thing, FALSE, TRUE, 0);
2833: gtk_widget_show (thing);
2834:
2835: /* Now the notebook */
2836: notebook = gtk_notebook_new ();
2837: gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
2838: gtk_widget_show (notebook);
2839:
2840: for (i = 0; i < sizeof pages / sizeof (struct _pages); i++) {
2841: thing = gtk_vbox_new (FALSE, 4);
2842: gtk_widget_show (thing);
2843: gtk_container_set_border_width (GTK_CONTAINER (thing), 10);
2844: pages[i].createfunc (thing);
2845: gtk_notebook_append_page (GTK_NOTEBOOK (notebook), thing, gtk_label_new (pages[i].title));
2846: }
2847:
2848: /* Put "about" screen first. */
2849: gtk_notebook_set_page (GTK_NOTEBOOK (notebook), i - 1);
2850: enable_disk_buttons (1);
2851:
2852: gtk_widget_show (vbox);
2853:
2854: gtk_timeout_add (1000, (GtkFunction)my_idle, 0);
2855: }
2856:
2857: static void *gtk_gui_thread (void *dummy)
2858: {
2859: gui_available = 1;
2860: gtk_main ();
2861:
2862: gui_available = 0;
2863: uae_sem_post (&gui_quit_sem);
2864: return 0;
2865: }
2866:
2867: void gui_fps (int x)
2868: {
2869: }
2870:
2871: void gui_display (int shortcut)
2872: {
2873: if (shortcut == -1 && !gui_available) {
2874: gui_init (0);
2875: }
2876: }
2877:
2878: void gui_led (int num, int on)
2879: {
2880: if (no_gui)
2881: return;
2882:
2883: /* if (num == 0)
2884: return;
2885: printf("LED %d %d\n", num, on);
2886: write_comm_pipe_int (&to_gui_pipe, 1, 0);
2887: write_comm_pipe_int (&to_gui_pipe, num == 0 ? 4 : num - 1, 0);
2888: write_comm_pipe_int (&to_gui_pipe, on, 1);
2889: printf("#LED %d %d\n", num, on);*/
2890: }
2891:
2892: void gui_filename (int num, const char *name)
2893: {
2894: if (no_gui)
2895: return;
2896:
2897: write_comm_pipe_int (&to_gui_pipe, GUICMD_DISKCHANGE, 0);
2898: write_comm_pipe_int (&to_gui_pipe, num, 1);
2899:
2900: /* gui_update ();*/
2901: }
2902:
2903: void gui_handle_events (void)
2904: {
2905: int pause_uae = FALSE;
2906:
2907: if (no_gui)
2908: return;
2909:
2910: do {
2911: while (pause_uae || comm_pipe_has_data (&from_gui_pipe)) {
2912: int cmd = read_comm_pipe_int_blocking (&from_gui_pipe);
2913: int n;
2914: switch (cmd) {
2915: case 0:
2916: n = read_comm_pipe_int_blocking (&from_gui_pipe);
2917: changed_prefs.df[n][0] = '\0';
2918: break;
2919: case 1:
2920: n = read_comm_pipe_int_blocking (&from_gui_pipe);
2921: uae_sem_wait (&gui_sem);
2922: strncpy (changed_prefs.df[n], new_disk_string[n], 255);
2923: free (new_disk_string[n]);
2924: new_disk_string[n] = 0;
2925: changed_prefs.df[n][255] = '\0';
2926: uae_sem_post (&gui_sem);
2927: break;
2928: case 2:
2929: uae_reset (1);
2930: end_pause_uae ();
2931: break;
2932: case 3:
2933: activate_debugger ();
2934: end_pause_uae ();
2935: break;
2936: case 4:
2937: uae_quit ();
2938: end_pause_uae ();
2939: break;
2940: case 5:
2941: pause_uae = TRUE;
2942: break;
2943: case 6:
2944: pause_uae = FALSE;
2945: break;
2946: case 7:
2947: printf ("STATESAVE\n");
2948: savestate_state = read_comm_pipe_int_blocking (&from_gui_pipe);
2949: uae_sem_wait (&gui_sem);
2950: savestate_filename = gui_snapname;
2951: uae_sem_post (&gui_sem);
2952: break;
2953: case 8:
2954: uae_sem_wait (&gui_sem);
2955: strncpy (changed_prefs.romfile, gui_romname, 255);
2956: changed_prefs.romfile[255] = '\0';
2957: free (gui_romname);
2958: uae_sem_post (&gui_sem);
2959: break;
2960: case 9:
2961: uae_sem_wait (&gui_sem);
2962: strncpy (changed_prefs.keyfile, gui_keyname, 255);
2963: changed_prefs.keyfile[255] = '\0';
2964: free (gui_keyname);
2965: uae_sem_post (&gui_sem);
2966: break;
2967: case 10:
2968: uae_sem_wait (&gui_sem);
2969: strncpy (changed_prefs.path_rom, gui_romname, 255);
2970: changed_prefs.path_rom[255] = '\0';
2971: free (gui_romname);
2972: uae_sem_post (&gui_sem);
2973: break;
2974: case 11:
2975: uae_sem_wait (&gui_sem);
2976: changed_prefs.gfx_w = gfx_w;
2977: changed_prefs.gfx_f = gfx_f;
2978: uae_sem_post (&gui_sem);
2979: break;
2980: }
2981: }
2982: } while (pause_uae);
2983: }
2984:
2985: void gui_update_gfx (void)
2986: {
2987: if (no_gui)
2988: return;
2989:
2990: write_comm_pipe_int (&to_gui_pipe, GUICMD_FULLSCREEN, 1);
2991: }
2992:
2993: int gui_init (int at_start)
2994: {
2995: uae_thread_id tid;
2996:
2997: if (gui_available)
2998: return 0;
2999:
3000: if (at_start) {
3001: init_comm_pipe (&to_gui_pipe, 20, 1);
3002: init_comm_pipe (&from_gui_pipe, 20, 1);
3003: uae_sem_init (&gui_sem, 0, 1);
3004: uae_sem_init (&gui_init_sem, 0, 0);
3005: uae_sem_init (&gui_quit_sem, 0, 0);
3006: }
3007:
3008: create_guidlg ();
3009: if (at_start)
3010: uae_start_thread (gtk_gui_thread, NULL, &tid);
3011:
3012: gui_update ();
3013:
3014: if (at_start && currprefs.start_gui == 1) {
3015: write_comm_pipe_int (&to_gui_pipe, GUICMD_PAUSE, 1);
3016: write_comm_pipe_int (&from_gui_pipe, 5, 1);
3017: /* Handle events until Pause is unchecked. */
3018: gui_handle_events ();
3019: /* Quit requested? */
3020: if (quit_program == -1) {
3021: gui_exit ();
3022: return -2;
3023: }
3024: }
3025:
3026: return 1;
3027: }
3028:
3029: int gui_update (void)
3030: {
3031: if (!gui_available)
3032: return 0;
3033:
3034: write_comm_pipe_int (&to_gui_pipe, GUICMD_UPDATE, 1);
3035: uae_sem_wait (&gui_init_sem);
3036: return 0;
3037: }
3038:
3039: void gui_romlist_changed (void)
3040: {
3041: if (!gui_available)
3042: return;
3043:
3044: write_comm_pipe_int (&to_gui_pipe, GUICMD_NEW_ROMLIST, 1);
3045: return;
3046: }
3047:
3048: void gui_exit (void)
3049: {
3050: if (!gui_available)
3051: return;
3052:
3053: quit_gui = 1;
3054: uae_sem_wait (&gui_quit_sem);
3055: }
3056:
3057: void gui_lock (void)
3058: {
3059: if (!gui_available)
3060: return;
3061: uae_sem_wait (&gui_sem);
3062: }
3063:
3064: void gui_unlock (void)
3065: {
3066: if (!gui_available)
3067: return;
3068:
3069: uae_sem_post (&gui_sem);
3070: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.