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