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