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];
63 static GtkWidget *sound_widget[4], *sound_ch_widget[3], *sound_interpol_widget[3];
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
make_labelled_button(guchar * label,GtkAccelGroup * accel_group)143 static GtkWidget *make_labelled_button (guchar *label, GtkAccelGroup *accel_group)
144 {
145 return gtk_button_new_with_mnemonic (label);
146 }
147
find_current_toggle(GtkWidget ** widgets,int count)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
make_message_box(const char * title,const char * message,int modal)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
mkmsgbox(const char * title,const char * message)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 */
handle_message_box_request(smp_comm_pipe * msg_pipe)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 */
do_message_box(const guchar * title,const guchar * message,gboolean modal,gboolean wait)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
gui_message(const char * format,...)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
save_config(void)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
nr_for_led(GtkWidget * led)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
enable_disk_buttons(int enable)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
set_disk_state(void)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
set_romlist_state(void)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
set_cpu_state(void)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
set_cpu_widget(void)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. */
adjust_gfx_prefs(struct gfx_params * gp,struct scrmode_widgets * w)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
set_gfx_mode_state(struct gfx_params * gp,struct scrmode_widgets * w)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
set_fullscreen_state(void)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
set_gfx_state(void)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. */
discover_cstype(void)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
set_chipset_state(void)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
set_sound_state(void)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
set_mem_state(void)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
set_joy_state(void)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
set_hd_state(void)600 static void set_hd_state (void)
601 {
602 char texts[9][256];
603 int nr = nr_units (currprefs.mountinfo);
604 int i;
605
606 gtk_list_store_clear (hd_store);
607 for (i = 0; i < nr; i++) {
608 GtkTreeIter iter;
609 int secspertrack, surfaces, reserved, blocksize, size;
610 int cylinders, readonly, pri, type;
611 char *volname, *rootdir, *devname;
612 char *failure;
613
614 /* We always use currprefs.mountinfo for the GUI. The filesystem
615 code makes a private copy which is updated every reset. */
616 failure = get_filesys_unit (currprefs.mountinfo, i,
617 &devname, &volname, &rootdir, &readonly,
618 &secspertrack, &surfaces, &reserved,
619 &cylinders, &size, &blocksize, &pri);
620
621 type = hardfile_fs_type (currprefs.mountinfo, i);
622 if (type != FILESYS_VIRTUAL) {
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
rom_requirements_change(void)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
draw_led(int nr)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
set_widgets_from_config(void)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
my_idle(void)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;
761 case GUICMD_SHOW:
762 gtk_widget_show (gui_window);
763 uae_sem_post (&gui_init_sem);
764 break;
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
gui_delete_event(GtkWidget * widget,GdkEvent * event,gpointer data)811 static gint gui_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
812 {
813 gui_active = 0;
814 if (disk_selector)
815 gtk_widget_destroy (disk_selector);
816 disk_selector = 0;
817 gtk_widget_hide (gui_window);
818 return TRUE;
819 }
820
dftype_changed(GtkWidget * w,gpointer data)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
kbdlang_changed(GtkWidget * w,gpointer data)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
joy_changed(void)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
coll_changed(void)867 static void coll_changed (void)
868 {
869 changed_prefs.collision_level = find_current_toggle (coll_widget, 4);
870 }
871
cslevel_changed(void)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
custom_changed(void)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
leds_changed(void)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
aspect_changed(void)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
screenmode_changed(void)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
cpuspeed_changed(void)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
cputype_changed(void)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
chipsize_changed(void)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
bogosize_changed(void)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
fastsize_changed(void)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
z3size_changed(void)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
p96size_changed(void)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
rom_combo_changed(void)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
sound_changed(void)1085 static void sound_changed (void)
1086 {
1087 int n;
1088
1089 changed_prefs.produce_sound = find_current_toggle (sound_widget, 4);
1090 changed_prefs.sound_interpol = find_current_toggle (sound_interpol_widget, 3);
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
bootrom_changed(void)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
ntsc_changed(void)1108 static void ntsc_changed (void)
1109 {
1110 changed_prefs.ntscmode = find_current_toggle (ntsc_widget, 2);
1111 }
1112
mbtype_changed(void)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
did_reset(void)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
did_debug(void)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
did_quit(void)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
did_eject(GtkWidget * w,gpointer data_p)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
pause_uae(void)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
end_pause_uae(void)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
make_file_selector(const char * title,GtkFileChooserAction action)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
filesel_set_path(GtkWidget * p,const char * path)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
make_disk_selector(void)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
did_insert(GtkWidget * w,gpointer data)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
driveled_event(GtkWidget * thing,GdkEvent * event)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
did_loadstate(void)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
did_savestate(void)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
did_rompathchange(GtkWidget * w,gpointer data)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
did_romchange(GtkWidget * w,gpointer data)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
did_keychange(GtkWidget * w,gpointer data)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
add_empty_vbox(GtkWidget * tobox)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
add_centered_to_vbox(GtkWidget * vbox,GtkWidget * w,int vexpand)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
make_labelled_widget(const char * str,GtkWidget * thing,int expand)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
add_labelled_widget_centered(const char * str,GtkWidget * thing,GtkWidget * vbox)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
make_radio_group(const char ** labels,GtkWidget * tobox,GtkWidget ** saveptr,gint t1,gint t2,void (* sigfunc)(void),int count,GSList * group)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
make_radio_group_box(const char * title,const char ** labels,GtkWidget ** saveptr,int horiz,void (* sigfunc)(void),GtkWidget ** boxp)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
make_radio_group_box_1(const char * title,const char ** labels,GtkWidget ** saveptr,int horiz,void (* sigfunc)(void),int elts_per_column)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
make_led(int nr)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
make_file_container(const char * title,GtkWidget * vbox,int vertical)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
make_file_widget(GtkWidget * buttonbox)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
make_floppy_disks(GtkWidget * vbox)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
make_cpu_speed_sel(void)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
make_cpu_widgets(GtkWidget * vbox)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
make_screenmode_box(const char * title,struct scrmode_widgets * mw,struct uae_rect * modes,int n_modes)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
make_gfx_widgets(GtkWidget * vbox)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
make_chipset_widgets(GtkWidget * vbox)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
make_sound_widgets(GtkWidget * vbox)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[] = {
1914 "None", "Sinc", "Anti",
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
1939 newbox = make_radio_group_box ("Resampler", soundlabels2, sound_interpol_widget, 0, sound_changed, NULL);
1940 gtk_widget_show (newbox);
1941 gtk_box_pack_start (GTK_BOX (hbox), newbox, FALSE, TRUE, 0);
1942
1943 newbox = make_radio_group_box ("Filter", soundlabels3, sound_filter_widget, 0, sound_changed, NULL);
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
make_rom_widgets(GtkWidget * dvbox)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
make_ram_widgets(GtkWidget * dvbox)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
make_joy_widgets(GtkWidget * dvbox)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
leftalign(GtkWidget * thing)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
create_dirdlg(const char * title,int row)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
create_hdfdlg(const char * title,int row)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
did_newdir(void)2400 static void did_newdir (void)
2401 {
2402 create_dirdlg ("Add a new mounted directory", -1);
2403 }
2404
did_newhdf(void)2405 static void did_newhdf (void)
2406 {
2407 create_hdfdlg ("Add a new hardfile", -1);
2408 }
2409
did_newadf(void)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
did_hdchange(void)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
2460 if (hardfile_fs_type (currprefs.mountinfo, idx) != FILESYS_VIRTUAL) {
2461 create_hdfdlg ("Change a hardfile", idx);
2462 } else {
2463 create_dirdlg ("Change a mounted directory", idx);
2464 }
2465 }
did_hddel(void)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
hdsel_changed(GtkWidget * widget,gint row,gint column,GdkEventButton * bevent,gpointer user_data)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
hdunselect(GtkWidget * widget,gint row,gint column,GdkEventButton * bevent,gpointer user_data)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
preset_changed(GtkTreeSelection * selection,gpointer data)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
did_set_preset(void)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
make_buttons_1(const char * label,GtkWidget * box,void (* sigfunc)(void),GtkWidget * (* create)(const char * label),int expand)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
new_text_cell_renderer(GtkWidget * treeview,const char * title,int colnr,int expand,int ellipsize)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
make_hd_widgets(GtkWidget * dvbox)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
make_presets(GtkWidget * dvbox)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
make_about_widgets(GtkWidget * dvbox)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
create_guidlg(void)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
gtk_gui_thread(void * dummy)2829 static void *gtk_gui_thread (void *dummy)
2830 {
2831 create_guidlg ();
2832 gtk_main ();
2833
2834 gui_available = 0;
2835 uae_sem_post (&gui_quit_sem);
2836 return 0;
2837 }
2838
gui_fps(int x)2839 void gui_fps (int x)
2840 {
2841 }
2842
gui_display(int shortcut)2843 void gui_display (int shortcut)
2844 {
2845 if (shortcut == -1 && !gui_active) {
2846 gui_init (0);
2847 }
2848 }
2849
gui_led(int num,int on)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
gui_filename(int num,const char * name)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
gui_handle_events(void)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
gui_update_gfx(void)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
gui_update(void)2965 int gui_update (void)
2966 {
2967 if (!gui_available)
2968 return 0;
2969
2970 write_comm_pipe_int (&to_gui_pipe, GUICMD_UPDATE, 1);
2971 uae_sem_wait (&gui_init_sem);
2972 return 0;
2973 }
2974
gui_show(void)2975 static void gui_show (void)
2976 {
2977 if (!gui_available)
2978 return;
2979
2980 write_comm_pipe_int (&to_gui_pipe, GUICMD_SHOW, 1);
2981 uae_sem_wait (&gui_init_sem);
2982 return;
2983 }
2984
gui_romlist_changed(void)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
gui_exit(void)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
gui_lock(void)3003 void gui_lock (void)
3004 {
3005 if (!gui_available)
3006 return;
3007 uae_sem_wait (&gui_sem);
3008 }
3009
gui_unlock(void)3010 void gui_unlock (void)
3011 {
3012 if (!gui_available)
3013 return;
3014
3015 uae_sem_post (&gui_sem);
3016 }
3017
gui_init(int at_start)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 }
3051 quit_program = 0;
3052 }
3053
3054 return 1;
3055 }
3056