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  * Copyright 2003-2007 Richard Drummond
9  * Copyright 2009-2010 Mustafa TUFAN
10  *
11  * The Tk GUI doesn't work.
12  * The X Forms Library isn't available as source, and there aren't any
13  * binaries compiled against glibc
14  *
15  * So let's try this...
16  */
17 
18 #include "sysconfig.h"
19 #include "sysdeps.h"
20 
21 #include "autoconf.h"
22 #include "options.h"
23 #include "uae.h"
24 #include "memory_uae.h"
25 #include "custom.h"
26 #include "gui.h"
27 #include "newcpu.h"
28 #include "filesys.h"
29 #include "threaddep/thread.h"
30 #include "audio.h"
31 #include "savestate.h"
32 #include "debug.h"
33 #include "inputdevice.h"
34 #include "xwin.h"
35 #include "picasso96.h"
36 #include "gcc_warnings.h"
37 
38 GCC_DIAG_OFF(strict-prototypes)
39 #include <gtk/gtk.h>
40 #include <gdk/gdk.h>
41 #include <gdk/gdkkeysyms.h>
42 GCC_DIAG_ON(strict-prototypes)
43 
44 #include "gui-gtk/cputypepanel.h"
45 #include "gui-gtk/cpuspeedpanel.h"
46 #include "gui-gtk/floppyfileentry.h"
47 #include "gui-gtk/led.h"
48 #include "gui-gtk/chipsettypepanel.h"
49 #include "gui-gtk/chipsetspeedpanel.h"
50 #include "gui-gtk/util.h"
51 
52 //#define GUI_DEBUG
53 #ifdef  GUI_DEBUG
54 #define DEBUG_LOG write_log ( "%s: ", __func__); write_log
55 #else
56 #define DEBUG_LOG(...) { }
57 #endif
58 
59 /* internal types */
60 static int gui_active;
61 
62 static int gui_available;
63 unsigned int pause_uae = 0;
64 
65 static GtkWidget *gui_window;
66 
67 static GtkWidget *start_uae_widget;
68 static GtkWidget *stop_uae_widget;
69 static GtkWidget *pause_uae_widget;
70 static GtkWidget *reset_uae_widget;
71 static GtkWidget *debug_uae_widget;
72 
73 static GtkWidget *chipsize_widget[5];
74 static GtkWidget *bogosize_widget[4];
75 static GtkWidget *fastsize_widget[5];
76 static GtkWidget *z3size_widget[10];
77 #ifdef PICASSO96
78 static GtkWidget *p96size_widget[7];
79 #endif
80 static GtkWidget *rom_text_widget;
81 static GtkWidget *rom_change_widget;
82 static GtkWidget  *sstate_text_widget, *sstate_change_widget, *sstate_load_widget, *sstate_save_widget;
83 
84 static GtkWidget *floppy_widget[4];
85 static char *new_disk_string[4];
86 
87 static gpointer power_led;
88 
89 static GtkWidget *ctpanel;
90 static GtkWidget *ftpanel;
91 static GtkWidget *cspanel;
92 static GtkWidget *chipsettype_panel;
93 static GtkWidget *chipsetspeed_panel;
94 
95 static GtkWidget *hdpanel;
96 static GtkWidget *memorypanel;
97 
98 static GtkWidget *sound_widget[4], *sound_ch_widget[3], *sound_in_widget[3], *sound_fl_widget[5];
99 static GtkWidget *drvspeed_widget[5];
100 static GtkWidget *cpu_widget[6], *fpu_widget[4];
101 
102 #ifdef JIT
103 static GtkWidget *jit_page;
104 static GtkWidget *compbyte_widget[4], *compword_widget[4], *complong_widget[4];
105 static GtkWidget *compaddr_widget[4];
106 static GtkWidget *compnf_widget[2];
107 static GtkWidget *compfpu_widget[2], *comp_hardflush_widget[2];
108 static GtkWidget *comp_constjump_widget[2];
109 static GtkAdjustment *cachesize_adj;
110 #endif
111 
112 #ifdef XARCADE
113 # define JOY_WIDGET_COUNT 9
114 #else
115 # define JOY_WIDGET_COUNT 7
116 #endif
117 static GtkWidget *joy_widget[2][JOY_WIDGET_COUNT];
118 
119 static unsigned int prevledstate;
120 
121 static GtkWidget *hdlist_widget;
122 static int selected_hd_row;
123 static GtkWidget *hdchange_button, *hddel_button;
124 static GtkWidget *devname_entry, *volname_entry, *path_entry;
125 static GtkWidget *readonly_widget, *bootpri_widget;
126 static GtkWidget *leds_on_screen_widget;
127 static GtkWidget *dirdlg;
128 static GtkWidget *dirdlg_ok;
129 static char dirdlg_devname[256], dirdlg_volname[256], dirdlg_path[256], floppydlg_path[256];
130 
131 enum hdlist_cols {
132     HDLIST_DEVICE,
133     HDLIST_VOLUME,
134     HDLIST_PATH,
135     HDLIST_READONLY,
136     HDLIST_HEADS,
137     HDLIST_CYLS,
138     HDLIST_SECS,
139     HDLIST_RSRVD,
140     HDLIST_SIZE,
141     HDLIST_BLKSIZE,
142     HDLIST_BOOTPRI,
143 //    HDLIST_DONOTMOUNT,
144 //    HDLIST_AUTOBOOT,
145 //    HDLIST_FILESYSDIR,
146 //    HDLIST_HDC,
147 //    HDLIST_FLAGS,
148     HDLIST_MAX_COLS
149 };
150 
151 static const char *hdlist_col_titles[] = {
152      "Device",
153      "Volume",
154      "File/Directory",
155      "R/O",
156      "Heads",
157      "Cyl.",
158      "Sec.",
159      "Rsrvd",
160      "Size",
161      "Blksize",
162      "Boot Pri",
163 //     "Donotmount",
164 //     "Autoboot",
165 //    "Filesysdir?"
166 //    "HDC"
167 //    "Flags"
168      NULL
169 };
170 
171 
172 static smp_comm_pipe to_gui_pipe;   // For sending messages to the GUI from UAE
173 static smp_comm_pipe from_gui_pipe; // For sending messages from the GUI to UAE
174 
175 /*
176  * Messages sent to GUI from UAE via to_gui_pipe
177  */
178 enum gui_commands {
179     GUICMD_STATE_CHANGE,	// Tell GUI about change in emulator state.
180     GUICMD_SHOW,			// Show yourself
181     GUICMD_UPDATE,			// Refresh your state from changed preferences
182     GUICMD_DISKCHANGE,		// Hey! A disk has been changed. Do something!
183     GUICMD_MSGBOX,			// Display a message box for me, please
184     GUICMD_NEW_ROMLIST,		// The ROM list has been updated.
185     GUICMD_FLOPPYDLG,		// Open a floppy insert dialog
186     GUICMD_FULLSCREEN,		// Fullscreen mode was toggled; update checkboxes
187     GUICMD_PAUSE,			// We're now paused, in case you didn't notice
188     GUICMD_UNPAUSE			// We're now running.
189 };
190 
191 enum uae_commands {
192     UAECMD_START,
193     UAECMD_STOP,
194     UAECMD_QUIT,
195     UAECMD_RESET,
196     UAECMD_PAUSE,
197     UAECMD_RESUME,
198     UAECMD_DEBUG,
199     UAECMD_SAVE_CONFIG,
200     UAECMD_EJECTDISK,
201     UAECMD_INSERTDISK,
202     UAECMD_SELECT_ROM,
203 	UAECMD_SAVESTATE_LOAD,
204 	UAECMD_SAVESTATE_SAVE
205 };
206 
207 
208 static uae_sem_t gui_sem;			// For mutual exclusion on various prefs settings
209 static uae_sem_t gui_update_sem;	// For synchronization between gui_update() and the GUI thread
210 static uae_sem_t gui_init_sem;		// For the GUI thread to tell UAE that it's ready.
211 static uae_sem_t gui_quit_sem;		// For the GUI thread to tell UAE that it's quitting.
212 
213 static volatile int quit_gui = 0, quitted_gui = 0;
214 
215 
216 /* internal prototypes */
217 static void create_guidlg (void);
218 
219 static void do_message_box (const gchar *title, const gchar *message, gboolean modal, gboolean wait);
220 static void handle_message_box_request (smp_comm_pipe *msg_pipe);
221 static GtkWidget *make_message_box (const gchar *title, const gchar *message, int modal, uae_sem_t *sem);
222 void on_message_box_quit (GtkWidget *w, gpointer user_data);
223 void on_vstat_toggle(GtkWidget *widget, gpointer statusbar);
224 
225 /* external prototypes */
226 extern void clearallkeys (void);
227 
228 
229 
uae_pause(void)230 static void uae_pause (void)
231 {
232 	write_comm_pipe_int (&from_gui_pipe, GUICMD_PAUSE , 1);
233 }
234 
uae_resume(void)235 static void uae_resume (void)
236 {
237 	write_comm_pipe_int (&to_gui_pipe, GUICMD_UNPAUSE, 1);
238 }
239 
set_mem32_widgets_state(void)240 static void set_mem32_widgets_state (void)
241 {
242 	int enable = changed_prefs.cpu_model >= 68020 && ! changed_prefs.address_space_24;
243 
244 #ifdef AUTOCONFIG
245     unsigned int i;
246 
247 	for (i = 0; i < 10; i++)
248 		gtk_widget_set_sensitive (z3size_widget[i], enable);
249 
250 # ifdef PICASSO96
251 	for (i = 0; i < 7; i++)
252 		gtk_widget_set_sensitive (p96size_widget[i], enable);
253 #endif
254 #endif
255 #ifdef JIT
256 	gtk_widget_set_sensitive (jit_page, changed_prefs.cpu_model >= 68020);
257 #endif
258 }
259 
set_cpu_state(void)260 static void set_cpu_state (void)
261 {
262 /*
263 	int i;
264 	unsigned int lvl;
265 	lvl = (changed_prefs.cpu_model - 68000) / 10;
266 
267 	DEBUG_LOG ("set_cpu_state: %d %d %d\n", lvl,
268 	changed_prefs.address_space_24, changed_prefs.m68k_speed);
269 
270     cputypepanel_set_cpulevel      (CPUTYPEPANEL (ctpanel), lvl);
271     cputypepanel_set_addr24bit     (CPUTYPEPANEL (ctpanel), changed_prefs.address_space_24);
272 
273     cpuspeedpanel_set_cpuspeed     (CPUSPEEDPANEL (cspanel), changed_prefs.m68k_speed);
274     cpuspeedpanel_set_cpuidle      (CPUSPEEDPANEL (cspanel), changed_prefs.cpu_idle);
275     set_mem32_widgets_state ();
276 */
277 }
278 
set_fpu_state(void)279 static void set_fpu_state (void)
280 {
281 #ifdef FPU
282 
283 #endif
284 }
285 
set_chipset_state(void)286 static void set_chipset_state (void)
287 {
288 	chipsettypepanel_set_chipset_mask		(CHIPSETTYPEPANEL  (chipsettype_panel),  currprefs.chipset_mask);
289 	chipsettypepanel_set_ntscmode			(CHIPSETTYPEPANEL  (chipsettype_panel),  currprefs.ntscmode);
290 	chipsetspeedpanel_set_framerate			(CHIPSETSPEEDPANEL (chipsetspeed_panel), currprefs.gfx_framerate);
291 	chipsetspeedpanel_set_collision_level	(CHIPSETSPEEDPANEL (chipsetspeed_panel), currprefs.collision_level);
292 	chipsetspeedpanel_set_immediate_blits	(CHIPSETSPEEDPANEL (chipsetspeed_panel), currprefs.immediate_blits);
293 }
294 
set_sound_state(void)295 static void set_sound_state (void)
296 {
297 	int stereo = currprefs.sound_stereo + currprefs.sound_mixed_stereo_delay;
298 	unsigned int i;
299 
300 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_widget[currprefs.produce_sound]), 1);
301 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_ch_widget[stereo]), 1);
302 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_in_widget[currprefs.sound_interpol]), 1);
303 
304 	if (currprefs.sound_filter == FILTER_SOUND_OFF) {
305 		i = 0;
306 	} else {
307 		if (currprefs.sound_filter_type == FILTER_SOUND_TYPE_A500) i = 1;
308 		if (currprefs.sound_filter_type == FILTER_SOUND_TYPE_A1200) i = 3;
309 		if (currprefs.sound_filter == FILTER_SOUND_ON) i++;
310 	}
311 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_fl_widget[i]), 1);
312 }
313 
set_mem_state(void)314 static void set_mem_state (void)
315 {
316     int t, t2;
317 
318     t = 0;
319     t2 = currprefs.chipmem_size;
320     while (t < 4 && t2 > 0x80000)
321 	t++, t2 >>= 1;
322     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chipsize_widget[t]), 1);
323 
324     t = 0;
325     t2 = currprefs.bogomem_size;
326     while (t < 3 && t2 >= 0x80000)
327 	t++, t2 >>= 1;
328     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bogosize_widget[t]), 1);
329 
330     t = 0;
331     t2 = currprefs.fastmem_size;
332     while (t < 4 && t2 >= 0x100000)
333 	t++, t2 >>= 1;
334     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fastsize_widget[t]), 1);
335 
336     t = 0;
337     t2 = currprefs.z3fastmem_size;
338     while (t < 9 && t2 >= 0x100000)
339 	t++, t2 >>= 1;
340     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (z3size_widget[t]), 1);
341 
342 #ifdef PICASSO96
343     t = 0;
344     t2 = currprefs.rtgmem_size;
345     while (t < 6 && t2 >= 0x100000)
346 	t++, t2 >>= 1;
347     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (p96size_widget[t]), 1);
348 #endif
349 
350     gtk_label_set_text (GTK_LABEL (rom_text_widget), changed_prefs.romfile[0]!='\0' ?
351 					changed_prefs.romfile : currprefs.romfile);
352 }
353 
354 #ifdef JIT
set_comp_state(void)355 static void set_comp_state (void)
356 {
357     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compbyte_widget[currprefs.comptrustbyte]), 1);
358     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compword_widget[currprefs.comptrustword]), 1);
359     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (complong_widget[currprefs.comptrustlong]), 1);
360     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compaddr_widget[currprefs.comptrustnaddr]), 1);
361     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compnf_widget[currprefs.compnf]), 1);
362     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_hardflush_widget[currprefs.comp_hardflush]), 1);
363     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_constjump_widget[currprefs.comp_constjump]), 1);
364     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compfpu_widget[currprefs.compfpu]), 1);
365 }
366 #endif
367 
set_misc_state(void)368 static void set_misc_state (void)
369 {
370     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (leds_on_screen_widget), currprefs.leds_on_screen);
371 }
372 
373 /*
374  * Temporary hacks for joystick widgets
375  */
376 
377 /*
378  * widget 0 = none
379  *        1 = joy 0
380  *        2 = joy 1
381  *        3 = mouse
382  *        4 = numpad
383  *        5 = cursor
384  *        6 = other
385  *        7 = xarcade1
386  *        8 = xarcade2
387  */
map_jsem_to_widget(int jsem)388 static int map_jsem_to_widget (int jsem)
389 {
390     int widget = 0;
391 
392     if (jsem == JSEM_END)
393 		widget = 0;
394     else if (jsem == JSEM_MICE)
395 		widget = 3;
396     else if (jsem == JSEM_JOYS || jsem == JSEM_JOYS + 1 )
397 		widget = jsem - JSEM_JOYS + 1;
398     else if (jsem >= JSEM_KBDLAYOUT)
399 		widget = jsem - JSEM_KBDLAYOUT + 4;
400 
401     return widget;
402 }
403 
map_widget_to_jsem(int widget)404 static int map_widget_to_jsem (int widget)
405 {
406    int jsem;
407 
408    switch (widget) {
409 	default:
410 	case 0: jsem = JSEM_END;           break;
411 	case 1: jsem = JSEM_JOYS;          break;
412 	case 2: jsem = JSEM_JOYS + 1;      break;
413 	case 3: jsem = JSEM_MICE;          break;
414 	case 4: jsem = JSEM_KBDLAYOUT;     break;
415 	case 5: jsem = JSEM_KBDLAYOUT + 1; break;
416 	case 6: jsem = JSEM_KBDLAYOUT + 2; break;
417 	case 7: jsem = JSEM_KBDLAYOUT + 3; break;
418 	case 8: jsem = JSEM_KBDLAYOUT + 4; break;
419    }
420 
421    return jsem;
422 }
423 
set_joy_state(void)424 static void set_joy_state (void)
425 {
426 	int j0t = map_jsem_to_widget (changed_prefs.jports[0].id);
427 	int j1t = map_jsem_to_widget (changed_prefs.jports[1].id);
428 
429 	int joy_count = inputdevice_get_device_total (IDTYPE_JOYSTICK);
430 	int i;
431 
432 	if (j0t != 0 && j0t == j1t) {
433 		/* Can't happen */
434 		j0t++;
435 		j0t %= 7;
436 	}
437 
438 	for (i = 0; i < JOY_WIDGET_COUNT; i++) {
439 		if (i == 1 && joy_count == 0) continue;
440 		if (i == 2 && joy_count <= 1) continue;
441 
442 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[0][i]), j0t == i);
443 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (joy_widget[1][i]), j1t == i);
444 		gtk_widget_set_sensitive (joy_widget[0][i], i == 0 || j1t != i);
445 		gtk_widget_set_sensitive (joy_widget[1][i], i == 0 || j0t != i);
446 	}
447 }
448 
449 #ifdef FILESYS
set_hd_state(void)450 static void set_hd_state (void)
451 {
452 	char  texts[HDLIST_MAX_COLS][256];
453 	char *tptrs[HDLIST_MAX_COLS];
454 	int nr = nr_units ();
455 	int i;
456 //	UnitInfo *ui;
457 
458 	DEBUG_LOG ("set_hd_state\n");
459 	for (i=0; i<HDLIST_MAX_COLS; i++)
460 		tptrs[i] = texts[i];
461 
462 		gtk_clist_freeze (GTK_CLIST (hdlist_widget));
463 		gtk_clist_clear (GTK_CLIST (hdlist_widget));
464 
465 		for (i = 0; i < nr; i++) {
466 			int     secspertrack=0, surfaces=0, reserved=0, blocksize=0, bootpri=0;
467 			uae_u64 size = 0;
468 			int     cylinders=0, readonly=0, flags=0;
469 			char   	*devname=NULL, *volname=NULL, *rootdir=NULL, *filesysdir=NULL;
470 			int	ret = 0;
471 
472 			/* We always use currprefs.mountinfo for the GUI.  The filesystem
473 			   code makes a private copy which is updated every reset.  */
474 			struct mountedinfo mi;
475 			ret = get_filesys_unitconfig (&currprefs, i, &mi);
476 /*		failure = get_filesys_unit (i,
477 				    &devname, &volname, &rootdir, &readonly,
478 				    &secspertrack, &surfaces, &reserved,
479 				    &cylinders, &size, &blocksize, &bootpri,
480 				    &filesysdir, &flags); */
481 
482 		if (ret == FILESYS_HARDDRIVE)
483 		    write_log ("Get Filesys Unit: HDD\n");
484 		if (ret == FILESYS_HARDFILE_RDB)
485 		    write_log ("Get Filesys Unit: HF RDB\n");
486 		if (ret == FILESYS_VIRTUAL)
487 		    write_log ("Get Filesys Unit: VIRT\n");
488 
489 	//	ui = &mountinfo.ui[i]
490           if (secspertrack == 0)
491                strcpy (texts[HDLIST_DEVICE], "N/A" );
492            else
493                 strncpy (texts[HDLIST_DEVICE], devname, 255);
494 		if (volname)
495 		    strncpy (texts[HDLIST_VOLUME], volname, 255);
496 
497 	    sprintf (texts[HDLIST_HEADS],   "%d", surfaces);
498 	    sprintf (texts[HDLIST_CYLS],    "%d", cylinders);
499 	    sprintf (texts[HDLIST_SECS],    "%d", secspertrack);
500 	    sprintf (texts[HDLIST_RSRVD],   "%d", reserved);
501 	    sprintf (texts[HDLIST_SIZE],    "%lu", size);
502 	    sprintf (texts[HDLIST_BLKSIZE], "%d", blocksize);
503 
504 		if (rootdir)
505 			strcpy  (texts[HDLIST_PATH],     rootdir);
506 		strcpy  (texts[HDLIST_READONLY], readonly ? "Y" : "N");
507 		sprintf (texts[HDLIST_BOOTPRI], "%d", bootpri);
508 
509 		gtk_clist_append (GTK_CLIST (hdlist_widget), tptrs);
510     }
511     gtk_clist_thaw (GTK_CLIST (hdlist_widget));
512     gtk_widget_set_sensitive (hdchange_button, false);
513     gtk_widget_set_sensitive (hddel_button, false);
514     DEBUG_LOG ("set_hd_state done\n");
515 }
516 #endif
517 
set_floppy_state(void)518 static void set_floppy_state( void )
519 {
520     unsigned int i;
521     switch (currprefs.floppy_speed) {
522 	case 0:   i = 0;
523         case 100: i = 1;
524         case 200: i = 2;
525         case 400: i = 3;
526         case 800: i = 4;
527         default:  i = 1;
528     }
529     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (drvspeed_widget[i]), 1);
530 
531     floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[0]), currprefs.floppyslots[0].df);
532     floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[1]), currprefs.floppyslots[1].df);
533     floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[2]), currprefs.floppyslots[2].df);
534     floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[3]), currprefs.floppyslots[3].df);
535 }
536 
update_state(void)537 static void update_state (void)
538 {
539     set_cpu_state ();
540 #ifdef FPU
541     set_fpu_state ();
542 #endif
543     set_joy_state ();
544     set_sound_state ();
545 #ifdef JIT
546     set_comp_state ();
547 #endif
548     set_mem_state ();
549     set_floppy_state ();
550 #ifdef FILESYS
551     set_hd_state ();
552 #endif
553     set_chipset_state ();
554     set_misc_state ();
555 }
556 
update_buttons(void)557 static void update_buttons (void)
558 {
559     if (gui_window) {
560 		int running = pause_uae ? 0 : 1;
561 		int paused  = pause_uae ? 1 : 0;
562 
563 		gtk_widget_set_sensitive (start_uae_widget, !running && !paused);
564 		gtk_widget_set_sensitive (stop_uae_widget,  running || paused);
565 		gtk_widget_set_sensitive (pause_uae_widget, running || paused);
566 		gtk_widget_set_sensitive (reset_uae_widget, running);
567 
568 		gtk_widget_set_sensitive (hdpanel,     !running && !paused);
569 		gtk_widget_set_sensitive (memorypanel, !running && !paused);
570 		gtk_widget_set_sensitive (rom_change_widget, !running && !paused);
571 //		gtk_widget_set_sensitive (sstate_change_widget, !running && !paused);
572 
573 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pause_uae_widget), paused);
574     }
575 }
576 
577 
578 #define MY_IDLE_PERIOD        250
579 #define LEDS_CALLBACK_PERIOD  1000
580 /*
581  * my_idle()
582  *
583  * This function is added as a callback to the GTK+ mainloop
584  * and is run every 250ms. It handles messages sent from UAE.
585  */
my_idle(void)586 static int my_idle (void)
587 {
588     if (quit_gui) {
589 		gtk_main_quit ();
590 		return 0;
591     }
592 
593     while (comm_pipe_has_data (&to_gui_pipe)) {
594 	int cmd = read_comm_pipe_int_blocking (&to_gui_pipe);
595 	int n;
596 	DEBUG_LOG ("GUI got command:%d\n", cmd);
597 	switch (cmd) {
598 	 case GUICMD_STATE_CHANGE: {
599 	     int state = read_comm_pipe_int_blocking (&to_gui_pipe);
600 	     update_buttons ();
601 	     break;
602 	 }
603 	 case GUICMD_SHOW:
604 	 case GUICMD_FLOPPYDLG:
605 	    if (!gui_window) {
606 			create_guidlg ();
607 			update_state ();
608 			update_buttons (); //FIXME
609 	    }
610 	    if (cmd == GUICMD_SHOW) {
611 			gtk_widget_show (gui_window);
612 #if GTK_MAJOR_VERSION >= 2
613 			gtk_window_present (GTK_WINDOW (gui_window));
614 			gui_active = 1;
615 #endif
616 	    } else {
617 			n = read_comm_pipe_int_blocking (&to_gui_pipe);
618 			floppyfileentry_do_dialog (FLOPPYFILEENTRY (floppy_widget[n]));
619 	    }
620 	    break;
621 	 case GUICMD_DISKCHANGE:
622 	    n = read_comm_pipe_int_blocking (&to_gui_pipe);
623 	    if (floppy_widget[n])
624 			floppyfileentry_set_filename (FLOPPYFILEENTRY (floppy_widget[n]), currprefs.floppyslots[n].df);
625 	    break;
626 	 case GUICMD_UPDATE:
627 	    update_state ();
628 	    uae_sem_post (&gui_update_sem);
629 	    gui_active = 1;
630 	    DEBUG_LOG ("GUICMD_UPDATE done\n");
631 	    break;
632 	 case GUICMD_MSGBOX:
633 	    handle_message_box_request(&to_gui_pipe);
634 	    break;
635 #if 0
636 	 case GUICMD_FLOPPYDLG:
637 	    n = read_comm_pipe_int_blocking (&to_gui_pipe);
638 	    floppyfileentry_do_dialog (FLOPPYFILEENTRY (floppy_widget[n]));
639 	    break;
640 #endif
641 	}
642     }
643     gui_handle_events();
644     return 1;
645 }
646 
leds_callback(void)647 static int leds_callback (void)
648 {
649     unsigned int leds = 0; //= gui_ledstate;
650     unsigned int i = 0;
651 
652     if (!quit_gui) {
653 	for ( ; i < 5; i++) {
654 	    GtkWidget *widget = i ? floppy_widget[i-1] : power_led;
655 	    unsigned int mask = 1 << i;
656 	    unsigned int on = leds & mask;
657 
658 	    if (!widget)
659 		continue;
660 
661 	   if (on == (prevledstate & mask))
662 		continue;
663 
664 	    if (i > 0)
665 		floppyfileentry_set_led (FLOPPYFILEENTRY (widget), on);
666 	    else {
667 		static GdkColor red   = {0, 0xffff, 0x0000, 0x0000};
668 		static GdkColor black = {0, 0x0000, 0x0000, 0x0000};
669 		led_set_color (LED (widget), on ? red : black);
670 	    }
671 	}
672 	prevledstate = leds;
673     }
674     return 1;
675 }
676 
find_current_toggle(GtkWidget ** widgets,int count)677 static int find_current_toggle (GtkWidget **widgets, int count)
678 {
679     int i;
680     for (i = 0; i < count; i++)
681 	if (GTK_TOGGLE_BUTTON (*widgets++)->active)
682 	    return i;
683     DEBUG_LOG ("GTKUI: Can't happen!\n");
684     return -1;
685 }
686 
joy_changed(void)687 static void joy_changed (void)
688 {
689 	if (! gui_active)
690 		return;
691 	changed_prefs.jports[0].id = map_widget_to_jsem (find_current_toggle (joy_widget[0], JOY_WIDGET_COUNT));
692 	changed_prefs.jports[1].id = map_widget_to_jsem (find_current_toggle (joy_widget[1], JOY_WIDGET_COUNT));
693 
694 //	write_log("Joystick Port 0: %d\n", changed_prefs.jports[0].id);
695 //	write_log("Joystick Port 1: %d\n", changed_prefs.jports[1].id);
696 
697 	if (changed_prefs.jports[0].id != currprefs.jports[0].id || changed_prefs.jports[1].id != currprefs.jports[1].id)
698 		inputdevice_config_change();
699 
700 	set_joy_state ();
701 }
702 
chipsize_changed(void)703 static void chipsize_changed (void)
704 {
705     int t = find_current_toggle (chipsize_widget, 5);
706     changed_prefs.chipmem_size = 0x80000 << t;
707     for (t = 0; t < 5; t++)
708 	gtk_widget_set_sensitive (fastsize_widget[t], changed_prefs.chipmem_size <= 0x200000);
709     if (changed_prefs.chipmem_size > 0x200000) {
710 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fastsize_widget[0]), 1);
711 		changed_prefs.fastmem_size = 0;
712     }
713 }
714 
bogosize_changed(void)715 static void bogosize_changed (void)
716 {
717     int t = find_current_toggle (bogosize_widget, 4);
718     switch (t) {
719 	case 0: changed_prefs.bogomem_size = 0;        break;
720 	case 1: changed_prefs.bogomem_size = 0x080000; break;
721 	case 2: changed_prefs.bogomem_size = 0x100000; break;
722 	case 3: changed_prefs.bogomem_size = 0x1C0000; break;
723     }
724 }
725 
fastsize_changed(void)726 static void fastsize_changed (void)
727 {
728     int t = find_current_toggle (fastsize_widget, 5);
729     changed_prefs.fastmem_size = (0x80000 << t) & ~0x80000;
730 }
731 
z3size_changed(void)732 static void z3size_changed (void)
733 {
734     int t = find_current_toggle (z3size_widget, 10);
735     changed_prefs.z3fastmem_size = (0x80000 << t) & ~0x80000;
736 }
737 
738 #ifdef PICASSO96
p96size_changed(void)739 static void p96size_changed (void)
740 {
741     int t = find_current_toggle (p96size_widget, 7);
742     changed_prefs.rtgmem_size = (0x80000 << t) & ~0x80000;
743 }
744 #endif
745 
drvspeed_changed(void)746 static void drvspeed_changed (void)
747 {
748 	switch (find_current_toggle (sound_widget, 5)) {
749 		case 0: changed_prefs.floppy_speed = 0;
750 		case 1: changed_prefs.floppy_speed = 100;
751 		case 2: changed_prefs.floppy_speed = 200;
752 		case 3: changed_prefs.floppy_speed = 400;
753 		case 4: changed_prefs.floppy_speed = 800;
754 	}
755 }
756 
sound_changed(void)757 static void sound_changed (void)
758 {
759     changed_prefs.produce_sound = find_current_toggle (sound_widget, 4);
760     changed_prefs.sound_stereo = find_current_toggle (sound_ch_widget, 3);
761     changed_prefs.sound_mixed_stereo_delay = 0;
762     if (changed_prefs.sound_stereo == 2)
763 		changed_prefs.sound_mixed_stereo_delay = changed_prefs.sound_stereo = 1;
764     	changed_prefs.sound_interpol = find_current_toggle (sound_in_widget, 3);
765     	int t = find_current_toggle (sound_fl_widget, 5);
766 
767     if (t == 0)
768 		changed_prefs.sound_filter = FILTER_SOUND_OFF;
769     else {
770 		changed_prefs.sound_filter = (t & 1) ? FILTER_SOUND_EMUL : FILTER_SOUND_ON;
771 		changed_prefs.sound_filter_type = (t > 2 ? FILTER_SOUND_TYPE_A1200 : FILTER_SOUND_TYPE_A500);
772     }
773 }
774 
775 #ifdef JIT
comp_changed(void)776 static void comp_changed (void)
777 {
778     changed_prefs.cachesize=cachesize_adj->value;
779     changed_prefs.comptrustbyte = find_current_toggle (compbyte_widget, 4);
780     changed_prefs.comptrustword = find_current_toggle (compword_widget, 4);
781     changed_prefs.comptrustlong = find_current_toggle (complong_widget, 4);
782     changed_prefs.comptrustnaddr = find_current_toggle (compaddr_widget, 4);
783     changed_prefs.compnf = find_current_toggle (compnf_widget, 2);
784     changed_prefs.comp_hardflush = find_current_toggle (comp_hardflush_widget, 2);
785     changed_prefs.comp_constjump = find_current_toggle (comp_constjump_widget, 2);
786     changed_prefs.compfpu= find_current_toggle (compfpu_widget, 2);
787 }
788 #endif
789 
cpu_changed(void)790 static void cpu_changed (void)
791 {
792 }
793 
fpu_changed(void)794 static void fpu_changed (void)
795 {
796 }
797 
on_start_clicked(void)798 static void on_start_clicked (void)
799 {
800     DEBUG_LOG ("Start button clicked.\n");
801 
802     write_comm_pipe_int (&from_gui_pipe, UAECMD_START, 1);
803 }
804 
on_stop_clicked(void)805 static void on_stop_clicked (void)
806 {
807     DEBUG_LOG ("Stop button clicked.\n");
808 
809     write_comm_pipe_int (&from_gui_pipe, UAECMD_STOP, 1);
810 }
811 
on_reset_clicked(void)812 static void on_reset_clicked (void)
813 {
814     DEBUG_LOG ("Reset button clicked.\n");
815 
816     if (!quit_gui)
817 	write_comm_pipe_int (&from_gui_pipe, UAECMD_RESET, 1);
818 }
819 
820 #ifdef DEBUGGER
on_debug_clicked(void)821 static void on_debug_clicked (void)
822 {
823     DEBUG_LOG ("Called\n");
824 
825     if (!quit_gui)
826 	write_comm_pipe_int (&from_gui_pipe, UAECMD_DEBUG, 1);
827 }
828 #endif
829 
on_quit_clicked(void)830 static void on_quit_clicked (void)
831 {
832     DEBUG_LOG ("Quit button clicked.\n");
833 
834     if (!quit_gui)
835 	write_comm_pipe_int (&from_gui_pipe, UAECMD_QUIT, 1);
836 }
837 
on_pause_clicked(GtkWidget * widget,gpointer data)838 static void on_pause_clicked (GtkWidget *widget, gpointer data)
839 {
840     DEBUG_LOG ("Called with %d\n", GTK_TOGGLE_BUTTON (widget)->active == true );
841 
842     if (!quit_gui) {
843 		write_comm_pipe_int (&from_gui_pipe, GTK_TOGGLE_BUTTON (widget)->active ? UAECMD_PAUSE : UAECMD_RESUME, 1);
844     }
845 }
846 
847 
848 static char *gui_romname;
849 static char *gui_sstate_name;
850 
disc_changed(FloppyFileEntry * ffe,gpointer p)851 static void disc_changed (FloppyFileEntry *ffe, gpointer p)
852 {
853     int num = GPOINTER_TO_INT(p);
854     char *s = floppyfileentry_get_filename(ffe);
855     int len;
856 
857     if (quit_gui)
858 	return;
859 
860     if(s == NULL || strlen(s) == 0) {
861 	write_comm_pipe_int (&from_gui_pipe, UAECMD_EJECTDISK, 0);
862 	write_comm_pipe_int (&from_gui_pipe, GPOINTER_TO_INT(p), 1);
863     } else {
864 	/* Get the pathname, not including the filename
865 	 * Set floppydlg_path to this, so that when the requester
866 	 * dialog pops up again, we don't have to navigate to the same place. */
867 	len = strrchr(s, '/') - s;
868 	if (len > 254) len = 254;
869 	strncpy(floppydlg_path, s, len);
870 	floppydlg_path[len] = '\0';
871 
872 	uae_sem_wait (&gui_sem);
873 	if (new_disk_string[num] != 0)
874 	    xfree (new_disk_string[num]);
875 	new_disk_string[num] = strdup (s);
876 	uae_sem_post (&gui_sem);
877 	write_comm_pipe_int (&from_gui_pipe, UAECMD_INSERTDISK, 0);
878 	write_comm_pipe_int (&from_gui_pipe, num, 1);
879     }
880 }
881 
882 static char fsbuffer[100];
883 
make_file_selector(const char * title,void (* insertfunc)(GtkObject *),void (* closefunc)(gpointer))884 static GtkWidget *make_file_selector (const char *title,
885 				      void (*insertfunc)(GtkObject *),
886 				      void (*closefunc)(gpointer))
887 {
888     GtkWidget *p = gtk_file_selection_new (title);
889     gtk_signal_connect (GTK_OBJECT (p), "destroy", (GtkSignalFunc) closefunc, p);
890 
891     gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (p)->ok_button),
892 			       "clicked", (GtkSignalFunc) insertfunc,
893 			       GTK_OBJECT (p));
894     gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (p)->cancel_button),
895 			       "clicked", (GtkSignalFunc) gtk_widget_destroy,
896 			       GTK_OBJECT (p));
897 
898 #if 0
899     gtk_window_set_title (GTK_WINDOW (p), title);
900 #endif
901 
902     gtk_widget_show (p);
903     return p;
904 }
905 
filesel_set_path(GtkWidget * p,const char * path)906 static void filesel_set_path (GtkWidget *p, const char *path)
907 {
908     size_t len = strlen (path);
909     if (len > 0 && ! access (path, R_OK)) {
910 	char *tmp = xmalloc (char, len + 2);
911 	strcpy (tmp, path);
912 	strcat (tmp, "/");
913 	gtk_file_selection_set_filename (GTK_FILE_SELECTION (p),
914 					 tmp);
915     }
916 }
917 
918 static GtkWidget *rom_selector;
919 
did_close_rom(gpointer gdata)920 static void did_close_rom (gpointer gdata)
921 {
922     gtk_widget_set_sensitive (rom_change_widget, 1);
923 }
924 
did_rom_select(GtkObject * o)925 static void did_rom_select (GtkObject *o)
926 {
927     const char *s = gtk_file_selection_get_filename (GTK_FILE_SELECTION (rom_selector));
928 
929     if (quit_gui)
930 		return;
931 
932     gtk_widget_set_sensitive (rom_change_widget, 1);
933 
934     uae_sem_wait (&gui_sem);
935     gui_romname = strdup (s);
936     uae_sem_post (&gui_sem);
937     gtk_label_set_text (GTK_LABEL (rom_text_widget), gui_romname);
938     write_comm_pipe_int (&from_gui_pipe, UAECMD_SELECT_ROM, 0);
939     gtk_widget_destroy (rom_selector);
940 }
941 
did_romchange(GtkWidget * w,gpointer data)942 static void did_romchange (GtkWidget *w, gpointer data)
943 {
944     gtk_widget_set_sensitive (rom_change_widget, 0);
945 
946     rom_selector = make_file_selector ("Select a ROM file", did_rom_select, did_close_rom);
947     filesel_set_path (rom_selector, currprefs.path_rom.path[0]);
948 }
949 
add_empty_vbox(GtkWidget * tobox)950 static void add_empty_vbox (GtkWidget *tobox)
951 {
952     GtkWidget *thing = gtk_vbox_new (false, 0);
953     gtk_widget_show (thing);
954     gtk_box_pack_start (GTK_BOX (tobox), thing, true, true, 0);
955 }
956 
add_empty_hbox(GtkWidget * tobox)957 static void add_empty_hbox (GtkWidget *tobox)
958 {
959     GtkWidget *thing = gtk_hbox_new (false, 0);
960     gtk_widget_show (thing);
961     gtk_box_pack_start (GTK_BOX (tobox), thing, true, true, 0);
962 }
963 
add_centered_to_vbox(GtkWidget * vbox,GtkWidget * w)964 static void add_centered_to_vbox (GtkWidget *vbox, GtkWidget *w)
965 {
966     GtkWidget *hbox = gtk_hbox_new (true, 0);
967     gtk_widget_show (hbox);
968     gtk_box_pack_start (GTK_BOX (hbox), w, true, false, 0);
969     gtk_box_pack_start (GTK_BOX (vbox), hbox, false, true, 0);
970 }
971 
make_labelled_widget(const char * str,GtkWidget * thing)972 static GtkWidget *make_labelled_widget (const char *str, GtkWidget *thing)
973 {
974     GtkWidget *label = gtk_label_new (str);
975     GtkWidget *hbox2 = gtk_hbox_new (false, 4);
976 
977     gtk_widget_show (label);
978     gtk_widget_show (thing);
979 
980     gtk_box_pack_start (GTK_BOX (hbox2), label, false, true, 0);
981     gtk_box_pack_start (GTK_BOX (hbox2), thing, false, true, 0);
982 
983     return hbox2;
984 }
985 
add_labelled_widget_centered(const char * str,GtkWidget * thing,GtkWidget * vbox)986 static GtkWidget *add_labelled_widget_centered (const char *str, GtkWidget *thing, GtkWidget *vbox)
987 {
988     GtkWidget *w = make_labelled_widget (str, thing);
989     gtk_widget_show (w);
990     add_centered_to_vbox (vbox, w);
991     return w;
992 }
993 
make_radio_group(const char ** labels,GtkWidget * tobox,GtkWidget ** saveptr,gint t1,gint t2,void (* sigfunc)(void),int count,GSList * group)994 static int make_radio_group (const char **labels, GtkWidget *tobox,
995 			      GtkWidget **saveptr, gint t1, gint t2,
996 			      void (*sigfunc) (void), int count, GSList *group)
997 {
998     int t = 0;
999 
1000     while (*labels && (count == -1 || count-- > 0)) {
1001 	GtkWidget *thing = gtk_radio_button_new_with_label (group, *labels++);
1002 	group = gtk_radio_button_group (GTK_RADIO_BUTTON (thing));
1003 
1004 	*saveptr++ = thing;
1005 	gtk_widget_show (thing);
1006 	gtk_box_pack_start (GTK_BOX (tobox), thing, t1, t2, 0);
1007 	gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
1008 	t++;
1009     }
1010     return t;
1011 }
1012 
make_radio_group_box(const char * title,const char ** labels,GtkWidget ** saveptr,int horiz,void (* sigfunc)(void))1013 static GtkWidget *make_radio_group_box (const char *title, const char **labels,
1014 					GtkWidget **saveptr, int horiz,
1015 					void (*sigfunc) (void))
1016 {
1017     GtkWidget *frame, *newbox;
1018 
1019     frame = gtk_frame_new (title);
1020     newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (false, 4);
1021     gtk_widget_show (newbox);
1022     gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1023     gtk_container_add (GTK_CONTAINER (frame), newbox);
1024     make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc, -1, NULL);
1025     return frame;
1026 }
1027 
make_radio_group_box_1(const char * title,const char ** labels,GtkWidget ** saveptr,int horiz,void (* sigfunc)(void),int elts_per_column)1028 static GtkWidget *make_radio_group_box_1 (const char *title, const char **labels,
1029 					  GtkWidget **saveptr, int horiz,
1030 					  void (*sigfunc) (void), int elts_per_column)
1031 {
1032     GtkWidget *frame, *newbox;
1033     GtkWidget *column;
1034     GSList *group = 0;
1035 
1036     frame = gtk_frame_new (title);
1037     column = (horiz ? gtk_vbox_new : gtk_hbox_new) (false, 4);
1038     gtk_container_add (GTK_CONTAINER (frame), column);
1039     gtk_widget_show (column);
1040 
1041     while (*labels) {
1042 	int count;
1043 	newbox = (horiz ? gtk_hbox_new : gtk_vbox_new) (false, 4);
1044 	gtk_widget_show (newbox);
1045 	gtk_container_set_border_width (GTK_CONTAINER (newbox), 4);
1046 	gtk_container_add (GTK_CONTAINER (column), newbox);
1047 	count = make_radio_group (labels, newbox, saveptr, horiz, !horiz, sigfunc, elts_per_column, group);
1048 	labels += count;
1049 	saveptr += count;
1050 	group = gtk_radio_button_group (GTK_RADIO_BUTTON (saveptr[-1]));
1051     }
1052     return frame;
1053 }
1054 
1055 
make_file_container(const char * title,GtkWidget * vbox)1056 static GtkWidget *make_file_container (const char *title, GtkWidget *vbox)
1057 {
1058     GtkWidget *thing = gtk_frame_new (title);
1059     GtkWidget *buttonbox = gtk_hbox_new (false, 4);
1060 
1061     gtk_container_set_border_width (GTK_CONTAINER (buttonbox), 4);
1062     gtk_container_add (GTK_CONTAINER (thing), buttonbox);
1063     gtk_box_pack_start (GTK_BOX (vbox), thing, false, true, 0);
1064     gtk_widget_show (buttonbox);
1065     gtk_widget_show (thing);
1066 
1067     return buttonbox;
1068 }
1069 
make_file_widget(GtkWidget * buttonbox)1070 static GtkWidget *make_file_widget (GtkWidget *buttonbox)
1071 {
1072     GtkWidget *thing, *subthing;
1073     GtkWidget *subframe = gtk_frame_new (NULL);
1074 
1075     gtk_frame_set_shadow_type (GTK_FRAME (subframe), GTK_SHADOW_ETCHED_OUT);
1076     gtk_box_pack_start (GTK_BOX (buttonbox), subframe, true, true, 0);
1077     gtk_widget_show (subframe);
1078     subthing = gtk_vbox_new (false, 0);
1079     gtk_widget_show (subthing);
1080     gtk_container_add (GTK_CONTAINER (subframe), subthing);
1081     thing = gtk_label_new ("");
1082     gtk_widget_show (thing);
1083     gtk_box_pack_start (GTK_BOX (subthing), thing, true, true, 0);
1084 
1085     return thing;
1086 }
1087 
make_floppy_disks(GtkWidget * vbox)1088 static void make_floppy_disks (GtkWidget *vbox)
1089 {
1090     char buf[5];
1091     unsigned int i;
1092     static const char *drv_speed_labels[] = { "Turbo", "100% (Compatible)", "200%", "400%", "800%", NULL };
1093 
1094     add_empty_vbox (vbox);
1095     GtkWidget *frame = make_radio_group_box ("Floppy Drive Speed", drv_speed_labels, drvspeed_widget, 1, drvspeed_changed);
1096     gtk_widget_show (frame);
1097     gtk_box_pack_start (GTK_BOX (vbox), frame, false, true, 0);
1098 
1099     add_empty_vbox (vbox);
1100     for (i = 0; i < 4; i++) {
1101 	sprintf (buf, "DF%d:", i);
1102 
1103 	floppy_widget[i] = floppyfileentry_new ();
1104 	if (currprefs.floppyslots[i].dfxtype == -1)
1105 	    gtk_widget_set_sensitive(floppy_widget[i], 0);
1106 	floppyfileentry_set_drivename (FLOPPYFILEENTRY (floppy_widget[i]), buf);
1107 	floppyfileentry_set_label (FLOPPYFILEENTRY (floppy_widget[i]), buf);
1108 	floppyfileentry_set_currentdir (FLOPPYFILEENTRY (floppy_widget[i]), currprefs.path_floppy.path[i]);
1109 	gtk_box_pack_start (GTK_BOX (vbox), floppy_widget[i], false, true, 0);
1110 	gtk_widget_show (floppy_widget[i]);
1111 	gtk_signal_connect (GTK_OBJECT (floppy_widget[i]), "disc-changed", (GtkSignalFunc) disc_changed, GINT_TO_POINTER (i));
1112     }
1113 
1114     add_empty_vbox (vbox);
1115 }
1116 
1117 static GtkWidget *sstate_selector;
1118 
did_close_sstate(gpointer gdata)1119 static void did_close_sstate (gpointer gdata)
1120 {
1121     gtk_widget_set_sensitive (sstate_change_widget, 1);
1122 }
1123 
did_sstate_select(GtkObject * o)1124 static void did_sstate_select (GtkObject *o)
1125 {
1126     const char *s = gtk_file_selection_get_filename (GTK_FILE_SELECTION (sstate_selector));
1127 
1128     if (quit_gui)
1129 		return;
1130 
1131     gtk_widget_set_sensitive (sstate_change_widget, 1);
1132 
1133     uae_sem_wait (&gui_sem);
1134     gui_sstate_name = strdup (s);
1135     uae_sem_post (&gui_sem);
1136     gtk_label_set_text (GTK_LABEL (sstate_text_widget), gui_sstate_name);
1137     gtk_widget_destroy (sstate_selector);
1138 }
1139 
did_sstate_change(GtkWidget * w,gpointer data)1140 static void did_sstate_change (GtkWidget *w, gpointer data)
1141 {
1142     gtk_widget_set_sensitive (sstate_change_widget, 0);
1143 
1144     sstate_selector = make_file_selector ("Select a Savestate file", did_sstate_select, did_close_sstate);
1145 //    filesel_set_path (sstate_selector, currprefs.path_savestate);
1146 }
1147 
did_sstate_load(GtkWidget * w,gpointer data)1148 static void did_sstate_load (GtkWidget *w, gpointer data)
1149 {
1150 	if ((int)strlen(gui_sstate_name) == 0) {
1151 	;//	writelog ("SaveState Load: Select a Savestate first\n");
1152 	} else {
1153 	    write_comm_pipe_int (&from_gui_pipe, UAECMD_SAVESTATE_LOAD, 0);
1154 	}
1155 }
1156 
did_sstate_save(GtkWidget * w,gpointer data)1157 static void did_sstate_save (GtkWidget *w, gpointer data)
1158 {
1159 	if ((int)strlen(gui_sstate_name) == 0) {
1160 	;//	writelog ("SaveState Save: Select a Savestate first\n");
1161 	} else {
1162 	    write_comm_pipe_int (&from_gui_pipe, UAECMD_SAVESTATE_SAVE, 0);
1163 	}
1164 }
1165 
make_ss_widgets(GtkWidget * vbox)1166 static void make_ss_widgets (GtkWidget *vbox)
1167 {
1168 	GtkWidget *hbox = gtk_hbox_new (false, 10);
1169 
1170 	add_empty_vbox (vbox);
1171 
1172 	GtkWidget *buttonbox = make_file_container ("Savestate file:", vbox);
1173 	GtkWidget *thing = gtk_button_new_with_label ("Select");
1174 	GtkWidget *thing_load = gtk_button_new_with_label ("Load");
1175 	GtkWidget *thing_save = gtk_button_new_with_label ("Save");
1176 
1177 	/* Current file display */
1178 	sstate_text_widget = make_file_widget (buttonbox);
1179 
1180 	gtk_box_pack_start (GTK_BOX (buttonbox), thing, false, true, 0);
1181 	gtk_widget_show (thing);
1182 	gtk_box_pack_start (GTK_BOX (buttonbox), thing_load, false, true, 0);
1183 	gtk_widget_show (thing_load);
1184 	gtk_box_pack_start (GTK_BOX (buttonbox), thing_save, false, true, 0);
1185 	gtk_widget_show (thing_save);
1186 
1187 	sstate_change_widget = thing;
1188 	sstate_load_widget = thing_load;
1189 	sstate_save_widget = thing_save;
1190 	gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_sstate_change, 0);
1191 	gtk_signal_connect (GTK_OBJECT (thing_load), "clicked", (GtkSignalFunc) did_sstate_load, 0);
1192 	gtk_signal_connect (GTK_OBJECT (thing_save), "clicked", (GtkSignalFunc) did_sstate_save, 0);
1193 
1194     gtk_widget_show (hbox);
1195     add_centered_to_vbox (vbox, hbox);
1196 }
1197 
leds_on_screen_changed(void)1198 static void leds_on_screen_changed (void)
1199 {
1200     currprefs.leds_on_screen = GTK_TOGGLE_BUTTON(leds_on_screen_widget)->active;
1201     DEBUG_LOG("leds_on_screen = %d\n", currprefs.leds_on_screen);
1202 }
1203 
make_misc_widgets(GtkWidget * vbox)1204 static void make_misc_widgets (GtkWidget *vbox)
1205 {
1206 	GtkWidget *hbox = gtk_hbox_new (false, 10);
1207 
1208 	add_empty_vbox (vbox);
1209 
1210 	leds_on_screen_widget = gtk_check_button_new_with_label ("Status Line");
1211 	gtk_signal_connect (GTK_OBJECT (leds_on_screen_widget), "clicked", (GtkSignalFunc) leds_on_screen_changed, 0);
1212 	gtk_widget_show (leds_on_screen_widget);
1213 	gtk_box_pack_start (GTK_BOX (hbox), leds_on_screen_widget, false, true, 0);
1214 
1215     gtk_widget_show (hbox);
1216     add_centered_to_vbox (vbox, hbox);
1217 }
1218 /*
1219  * CPU configuration page
1220  */
on_cputype_changed(void)1221 static void on_cputype_changed (void)
1222 {
1223     int i;
1224 	unsigned int mdl;
1225 
1226 	mdl = cputypepanel_get_cpulevel (CPUTYPEPANEL (ctpanel));
1227     mdl = (mdl * 10) + 68000;
1228 
1229     DEBUG_LOG ("called\n");
1230 
1231     changed_prefs.cpu_model       = mdl;
1232     changed_prefs.cpu_cycle_exact = CPUTYPEPANEL (ctpanel)->cycleexact;
1233 
1234     set_mem32_widgets_state ();
1235 
1236     DEBUG_LOG ("cpu_model=%d address_space24=%d cpu_compatible=%d cpu_cycle_exact=%d\n",
1237 	changed_prefs.cpu_model, changed_prefs.address_space_24,
1238 	changed_prefs.cpu_compatible, changed_prefs.cpu_cycle_exact);
1239 }
1240 
on_addr24bit_changed(void)1241 static void on_addr24bit_changed (void)
1242 {
1243 	int i;
1244 
1245 	DEBUG_LOG ("called\n");
1246 
1247 	changed_prefs.address_space_24 = (cputypepanel_get_addr24bit (CPUTYPEPANEL (ctpanel)) != 0);
1248 	set_mem32_widgets_state ();
1249 
1250 	DEBUG_LOG ("address_space_24=%d\n", changed_prefs.address_space_24);
1251 }
1252 
on_cpuspeed_changed(void)1253 static void on_cpuspeed_changed (void)
1254 {
1255 	DEBUG_LOG ("called\n");
1256 
1257 	changed_prefs.m68k_speed = CPUSPEEDPANEL (cspanel)->cpuspeed;
1258 
1259 	DEBUG_LOG ("m68k_speed=%d\n", changed_prefs.m68k_speed);
1260 }
1261 
on_cpuidle_changed(void)1262 static void on_cpuidle_changed (void)
1263 {
1264 	DEBUG_LOG ("called\n");
1265 
1266 	changed_prefs.cpu_idle       = CPUSPEEDPANEL (cspanel)->cpuidle;
1267 
1268 	DEBUG_LOG ("cpu_idle=%d\n", changed_prefs.cpu_idle);
1269 }
1270 
make_cpu_widgets(GtkWidget * vbox)1271 static void make_cpu_widgets (GtkWidget *vbox)
1272 {
1273     GtkWidget *table;
1274 
1275     table = make_xtable (5, 7);
1276     add_table_padding (table, 0, 0);
1277     add_table_padding (table, 4, 4);
1278     add_table_padding (table, 1, 2);
1279     gtk_box_pack_start (GTK_BOX (vbox), table, true, true, 0);
1280 
1281     ctpanel = cputypepanel_new();
1282     gtk_table_attach (GTK_TABLE (table), ctpanel, 1, 4, 1, 2,
1283 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1284 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1285     gtk_widget_show (ctpanel);
1286 
1287     ftpanel = fputypepanel_new();
1288     gtk_table_attach (GTK_TABLE (table), ftpanel, 1, 4, 3, 4,
1289 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1290 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1291     gtk_widget_show (ftpanel);
1292 
1293     cspanel = cpuspeedpanel_new();
1294     gtk_table_attach (GTK_TABLE (table), cspanel, 1, 4, 5, 6,
1295 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1296 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1297     gtk_widget_show (cspanel);
1298 
1299     gtk_signal_connect (GTK_OBJECT (ctpanel), "cputype-changed",
1300 			GTK_SIGNAL_FUNC (on_cputype_changed),
1301 			NULL);
1302     gtk_signal_connect (GTK_OBJECT (ctpanel), "addr24bit-changed",
1303 			GTK_SIGNAL_FUNC (on_addr24bit_changed),
1304 			NULL);
1305     gtk_signal_connect (GTK_OBJECT (cspanel), "cpuspeed-changed",
1306 			GTK_SIGNAL_FUNC (on_cpuspeed_changed),
1307 			NULL);
1308     gtk_signal_connect (GTK_OBJECT (cspanel), "cpuidle-changed",
1309 			GTK_SIGNAL_FUNC (on_cpuidle_changed),
1310 			NULL);
1311 }
1312 
on_chipset_changed(void)1313 static void on_chipset_changed (void)
1314 {
1315     changed_prefs.chipset_mask = CHIPSETTYPEPANEL (chipsettype_panel)->chipset_mask;
1316     changed_prefs.ntscmode     = CHIPSETTYPEPANEL (chipsettype_panel)->ntscmode;
1317 }
1318 
on_framerate_changed(void)1319 static void on_framerate_changed (void)
1320 {
1321     changed_prefs.gfx_framerate = CHIPSETSPEEDPANEL (chipsetspeed_panel)->framerate;
1322     DEBUG_LOG("gfx_framerate = %d\n", changed_prefs.gfx_framerate);
1323 }
1324 
on_collision_level_changed(void)1325 static void on_collision_level_changed (void)
1326 {
1327     changed_prefs.collision_level = CHIPSETSPEEDPANEL (chipsetspeed_panel)->collision_level;
1328     DEBUG_LOG("collision_level = %d\n", changed_prefs.collision_level);
1329 }
1330 
on_immediate_blits_changed(void)1331 static void on_immediate_blits_changed (void)
1332 {
1333     changed_prefs.immediate_blits = CHIPSETSPEEDPANEL (chipsetspeed_panel)->immediate_blits;
1334     DEBUG_LOG("immediate_blits = %d\n", changed_prefs.immediate_blits);
1335 }
1336 
make_chipset_widgets(GtkWidget * vbox)1337 static void make_chipset_widgets (GtkWidget *vbox)
1338 {
1339     GtkWidget *table;
1340 
1341     table = make_xtable (5, 7);
1342     add_table_padding (table, 0, 0);
1343     add_table_padding (table, 4, 4);
1344     add_table_padding (table, 1, 2);
1345     gtk_box_pack_start (GTK_BOX (vbox), table, true, true, 0);
1346 
1347     chipsettype_panel = chipsettypepanel_new ();
1348     gtk_table_attach (GTK_TABLE (table), chipsettype_panel, 1, 4, 1, 2,
1349 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1350 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1351     gtk_widget_show (chipsettype_panel);
1352 
1353     chipsetspeed_panel = chipsetspeedpanel_new ();
1354     gtk_table_attach (GTK_TABLE (table), chipsetspeed_panel, 1, 4, 3, 4,
1355 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1356 		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1357     gtk_widget_show (chipsetspeed_panel);
1358 
1359 
1360     gtk_signal_connect (GTK_OBJECT (chipsettype_panel), "chipset-changed", GTK_SIGNAL_FUNC (on_chipset_changed), NULL);
1361     gtk_signal_connect (GTK_OBJECT (chipsetspeed_panel), "framerate-changed", GTK_SIGNAL_FUNC (on_framerate_changed), NULL);
1362     gtk_signal_connect (GTK_OBJECT (chipsetspeed_panel), "sprite-collisions-changed", GTK_SIGNAL_FUNC (on_collision_level_changed), NULL);
1363     gtk_signal_connect (GTK_OBJECT (chipsetspeed_panel), "immediate-blits-changed", GTK_SIGNAL_FUNC (on_immediate_blits_changed), NULL);
1364 }
1365 
make_cpu_widgets2(GtkWidget * vbox)1366 static void make_cpu_widgets2 (GtkWidget *vbox)
1367 {
1368 	static const char *cpu_labels[] = {
1369 		"68000", "68010", "68020", "68030", "68040", "68060", NULL
1370 	}, *fpu_labels[] = {
1371 		"None", "68881", "68882", "CPU Internal", NULL
1372 	};
1373 
1374 	GtkWidget *hbox = gtk_hbox_new (false, 10);
1375 	GtkWidget *frame, *newbox, *newbox2;
1376 	add_empty_vbox (vbox);
1377 
1378 	gtk_widget_show (hbox);
1379 	add_centered_to_vbox (vbox, hbox);
1380 	add_empty_vbox (vbox);
1381 
1382 	//cpu emulation
1383 	newbox = make_radio_group_box ("CPU", cpu_labels, cpu_widget, 0, cpu_changed);
1384 	gtk_widget_show (newbox);
1385 	gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1386 
1387 	newbox2 = gtk_check_button_new_with_label ("24-bit addressing");
1388 	gtk_widget_show (newbox2);
1389 	gtk_box_pack_start (GTK_BOX (newbox), newbox2, false, true, 0);
1390 
1391 	newbox2 = gtk_check_button_new_with_label ("More compatible");
1392 	gtk_widget_show (newbox2);
1393 	gtk_box_pack_start (GTK_BOX (newbox), newbox2, false, true, 0);
1394 
1395 	newbox = gtk_check_button_new_with_label ("JIT");
1396 	gtk_widget_show (newbox);
1397 	gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1398 
1399 	newbox = gtk_check_button_new_with_label ("68040 MMU");
1400 	gtk_widget_show (newbox);
1401 	gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1402 
1403 	//fpu mode
1404 	newbox = make_radio_group_box ("FPU", fpu_labels, fpu_widget, 0, fpu_changed);
1405 	gtk_widget_show (newbox);
1406 	gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1407 
1408 	newbox = gtk_check_button_new_with_label ("More compatible");
1409 	gtk_widget_show (newbox);
1410 	gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1411 }
1412 
make_sound_widgets(GtkWidget * vbox)1413 static void make_sound_widgets (GtkWidget *vbox)
1414 {
1415 	static const char *snd_em_labels[] = {
1416 	"Disabled", "Disabled, but Emulated", "Enabled", "Enabled, 100% Accurate", NULL
1417 	}, *snd_in_labels[] = {
1418 	"Disabled", "None", "Sinc", "RH", "Anti", NULL
1419 	}, *snd_fl_labels[] = {
1420 	"Disabled", "A500 (Power Led)", "A500 (Always on)", "A1200 (Power Led)", "A1200 (Always on)", NULL
1421 	}, *snd_ch_labels[] = {
1422 	"Mono", "Stereo", "Mixed", NULL
1423 	};
1424 
1425 	GtkWidget *hbox = gtk_hbox_new (false, 10);
1426 	GtkWidget *frame, *newbox;
1427 	add_empty_vbox (vbox);
1428 
1429 	gtk_widget_show (hbox);
1430 	add_centered_to_vbox (vbox, hbox);
1431 	add_empty_vbox (vbox);
1432 
1433 	//sound emulation
1434 	newbox = make_radio_group_box ("Sound Emulation", snd_em_labels, sound_widget, 0, sound_changed);
1435 	gtk_widget_set_sensitive (sound_widget[2], sound_available);
1436 	gtk_widget_set_sensitive (sound_widget[3], sound_available);
1437 	gtk_widget_show (newbox);
1438 	gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1439 
1440 	//channel mode
1441     newbox = make_radio_group_box ("Channels", snd_ch_labels, sound_ch_widget, 0, sound_changed);
1442     gtk_widget_set_sensitive (newbox, sound_available);
1443     gtk_widget_show (newbox);
1444     gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1445 
1446 	//interpolation
1447     newbox = make_radio_group_box ("Interpolation", snd_in_labels, sound_in_widget, 0, sound_changed);
1448     gtk_widget_set_sensitive (newbox, sound_available);
1449     gtk_widget_show (newbox);
1450     gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1451 
1452 	//audio filter
1453     newbox = make_radio_group_box ("Audio Filter", snd_fl_labels, sound_fl_widget, 0, sound_changed);
1454     gtk_widget_set_sensitive (newbox, sound_available);
1455     gtk_widget_show (newbox);
1456     gtk_box_pack_start (GTK_BOX (hbox), newbox, false, true, 0);
1457 }
1458 
make_mem_widgets(GtkWidget * vbox)1459 static void make_mem_widgets (GtkWidget *vbox)
1460 {
1461     GtkWidget *hbox = gtk_hbox_new (false, 10);
1462     GtkWidget *label, *frame;
1463 
1464     static const char *chiplabels[] = {
1465 	"512 KB", "1 MB", "2 MB", "4 MB", "8 MB", NULL
1466     };
1467     static const char *bogolabels[] = {
1468 	"None", "512 KB", "1 MB", "1.8 MB", NULL
1469     };
1470     static const char *fastlabels[] = {
1471 	"None", "1 MB", "2 MB", "4 MB", "8 MB", NULL
1472     };
1473     static const char *z3labels[] = {
1474 	"None", "1 MB", "2 MB", "4 MB", "8 MB",
1475 	"16 MB", "32 MB", "64 MB", "128 MB", "256 MB",
1476 	NULL
1477     };
1478     static const char *p96labels[] = {
1479 	"None", "1 MB", "2 MB", "4 MB", "8 MB", "16 MB", "32 MB", NULL
1480     };
1481 
1482     add_empty_vbox (vbox);
1483 
1484     {
1485 	GtkWidget *buttonbox = make_file_container ("Kickstart ROM file:", vbox);
1486 	GtkWidget *thing = gtk_button_new_with_label ("Change");
1487 
1488 	/* Current file display */
1489 	rom_text_widget = make_file_widget (buttonbox);
1490 
1491 	gtk_box_pack_start (GTK_BOX (buttonbox), thing, false, true, 0);
1492 	gtk_widget_show (thing);
1493 	rom_change_widget = thing;
1494 	gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) did_romchange, 0);
1495     }
1496 
1497     gtk_widget_show (hbox);
1498     add_centered_to_vbox (vbox, hbox);
1499 
1500     add_empty_vbox (vbox);
1501 
1502     frame = make_radio_group_box ("Chip Mem", chiplabels, chipsize_widget, 0, chipsize_changed);
1503     gtk_widget_show (frame);
1504     gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1505 
1506     frame = make_radio_group_box ("Slow Mem", bogolabels, bogosize_widget, 0, bogosize_changed);
1507     gtk_widget_show (frame);
1508     gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1509 
1510     frame = make_radio_group_box ("Fast Mem", fastlabels, fastsize_widget, 0, fastsize_changed);
1511     gtk_widget_show (frame);
1512     gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1513 
1514     frame = make_radio_group_box_1 ("Z3 Mem", z3labels, z3size_widget, 0, z3size_changed, 5);
1515     gtk_widget_show (frame);
1516     gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1517 
1518 #ifdef PICASSO96
1519     frame = make_radio_group_box_1 ("P96 RAM", p96labels, p96size_widget, 0, p96size_changed, 4);
1520     gtk_widget_show (frame);
1521     gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1522 #endif
1523 
1524     memorypanel = hbox;
1525 }
1526 
1527 #ifdef JIT
make_comp_widgets(GtkWidget * vbox)1528 static void make_comp_widgets (GtkWidget *vbox)
1529 {
1530     GtkWidget *newbox;
1531     static const char *complabels1[] = {
1532 	"Direct", "Indirect", "Indirect for KS", "Direct after Picasso",
1533 	NULL
1534     },*complabels2[] = {
1535 	"Direct", "Indirect", "Indirect for KS", "Direct after Picasso",
1536 	NULL
1537     },*complabels3[] = {
1538 	"Direct", "Indirect", "Indirect for KS", "Direct after Picasso",
1539 	NULL
1540     },*complabels3a[] = {
1541 	"Direct", "Indirect", "Indirect for KS", "Direct after Picasso",
1542 	NULL
1543     }, *complabels4[] = {
1544       "Always generate", "Only generate when needed",
1545 	NULL
1546     }, *complabels5[] = {
1547       "Disable", "Enable",
1548 	NULL
1549     }, *complabels6[] = {
1550       "Disable", "Enable",
1551 	NULL
1552     }, *complabels7[] = {
1553       "Disable", "Enable",
1554 	NULL
1555     }, *complabels8[] = {
1556       "Soft", "Hard",
1557 	NULL
1558     }, *complabels9[] = {
1559       "Disable", "Enable",
1560 	NULL
1561     };
1562     GtkWidget *thing;
1563 
1564     add_empty_vbox (vbox);
1565 
1566     newbox = make_radio_group_box ("Byte access", complabels1, compbyte_widget, 1, comp_changed);
1567     gtk_widget_show (newbox);
1568     add_centered_to_vbox (vbox, newbox);
1569     newbox = make_radio_group_box ("Word access", complabels2, compword_widget, 1, comp_changed);
1570     gtk_widget_show (newbox);
1571     add_centered_to_vbox (vbox, newbox);
1572     newbox = make_radio_group_box ("Long access", complabels3, complong_widget, 1, comp_changed);
1573     gtk_widget_show (newbox);
1574     add_centered_to_vbox (vbox, newbox);
1575     newbox = make_radio_group_box ("Address lookup", complabels3a, compaddr_widget, 1, comp_changed);
1576     gtk_widget_show (newbox);
1577     add_centered_to_vbox (vbox, newbox);
1578 
1579     newbox = make_radio_group_box ("Flags", complabels4, compnf_widget, 1, comp_changed);
1580     gtk_widget_show (newbox);
1581     add_centered_to_vbox (vbox, newbox);
1582 
1583     newbox = make_radio_group_box ("Icache flushes", complabels8, comp_hardflush_widget, 1, comp_changed);
1584     gtk_widget_show (newbox);
1585     add_centered_to_vbox (vbox, newbox);
1586 
1587     newbox = make_radio_group_box ("Compile through uncond branch", complabels9, comp_constjump_widget, 1, comp_changed);
1588     gtk_widget_show (newbox);
1589     add_centered_to_vbox (vbox, newbox);
1590 
1591     newbox = make_radio_group_box ("JIT FPU compiler", complabels7, compfpu_widget, 1, comp_changed);
1592     gtk_widget_show (newbox);
1593     add_centered_to_vbox (vbox, newbox);
1594 
1595     cachesize_adj = GTK_ADJUSTMENT (gtk_adjustment_new (currprefs.cachesize, 0.0, 16385.0, 1.0, 1.0, 1.0));
1596     gtk_signal_connect (GTK_OBJECT (cachesize_adj), "value_changed",
1597 			GTK_SIGNAL_FUNC (comp_changed), NULL);
1598 
1599     thing = gtk_hscale_new (cachesize_adj);
1600     gtk_range_set_update_policy (GTK_RANGE (thing), GTK_UPDATE_DELAYED);
1601     gtk_scale_set_digits (GTK_SCALE (thing), 0);
1602     gtk_scale_set_value_pos (GTK_SCALE (thing), GTK_POS_RIGHT);
1603     gtk_widget_set_usize (thing, 180, -1); // Hack!
1604     add_labelled_widget_centered ("Translation buffer(kB):", thing, vbox);
1605 
1606     add_empty_vbox (vbox);
1607 
1608     /* Kludge - remember pointer to JIT page, so that we can easily disable it */
1609     jit_page = vbox;
1610 }
1611 #endif
1612 
make_joy_widgets(GtkWidget * dvbox)1613 static void make_joy_widgets (GtkWidget *dvbox)
1614 {
1615     int i;
1616     int joy_count = inputdevice_get_device_total (IDTYPE_JOYSTICK);
1617     GtkWidget *hbox = gtk_hbox_new (false, 12);
1618 
1619     static const char *joylabels[] = {
1620 		"None",
1621 		"Joystick 0",
1622 		"Joystick 1",
1623 		"Mouse",
1624 		"Keyboard Layout A (NumPad, 0 & 5 = Fire)",
1625 		"Keyboard Layout B (Cursor, RCtrl & Alt = Fire)",
1626 		"Keyboard Layout C (WASD, LAlt = Fire)",
1627 #ifdef XARCADE
1628 		"X-Arcade (Left)",
1629 		"X-Arcade (Right)",
1630 #endif
1631 		NULL
1632     };
1633 
1634     add_empty_vbox (dvbox);
1635     gtk_widget_show (hbox);
1636     add_centered_to_vbox (dvbox, hbox);
1637 
1638     for (i = 0; i < 2; i++) {
1639 		GtkWidget *frame;
1640 		char buffer[20];
1641 
1642 		sprintf (buffer, "Port %d", i);
1643 		frame = make_radio_group_box (buffer, joylabels, joy_widget[i], 0, joy_changed);
1644 		gtk_widget_show (frame);
1645 		gtk_box_pack_start (GTK_BOX (hbox), frame, false, true, 0);
1646 
1647 		if (joy_count < 2)
1648 		    gtk_widget_set_sensitive (joy_widget[i][2], 0);
1649 		if (joy_count == 0)
1650 		    gtk_widget_set_sensitive (joy_widget[i][1], 0);
1651     }
1652 
1653     add_empty_vbox (dvbox);
1654 }
1655 
1656 #ifdef FILESYS
1657 static int hd_change_mode;
1658 
newdir_ok(void)1659 static void newdir_ok (void)
1660 {
1661     int n;
1662     int readonly = GTK_TOGGLE_BUTTON (readonly_widget)->active;
1663     int bootpri  = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (bootpri_widget));
1664     strcpy (dirdlg_devname, gtk_entry_get_text (GTK_ENTRY (devname_entry)));
1665     strcpy (dirdlg_volname, gtk_entry_get_text (GTK_ENTRY (volname_entry)));
1666     strcpy (dirdlg_path, gtk_entry_get_text (GTK_ENTRY (path_entry)));
1667 
1668 	unsigned int secspertrack = 0;
1669 	unsigned int surfaces = 0;
1670 	unsigned int reserved = 0;
1671 	unsigned int blocksize = 0;
1672 	unsigned int flags = 0;
1673 	unsigned int donotmount = 0;
1674 	unsigned int autoboot = 129;
1675 	unsigned int hdc = 0;
1676 
1677     n = strlen (dirdlg_volname);
1678     /* Strip colons from the end.  */
1679     if (n > 0) {
1680 		if (dirdlg_volname[n - 1] == ':')
1681 		    dirdlg_volname[n - 1] = '\0';
1682     }
1683     /* Do device name too */
1684     n = strlen (dirdlg_devname);
1685     if (n > 0) {
1686 		if (dirdlg_devname[n - 1] == ':')
1687 		    dirdlg_devname[n - 1] = '\0';
1688     }
1689     if (strlen (dirdlg_volname) == 0 || strlen (dirdlg_path) == 0) {
1690 		/* Uh, no messageboxes in gtk?  */
1691 /// FIXME: set_filesys_unit() needs uaedev_config_info* !
1692 #if 0
1693     } else if (hd_change_mode) {
1694 		set_filesys_unit (selected_hd_row, dirdlg_devname, dirdlg_volname, dirdlg_path,
1695 				readonly, 0, secspertrack, surfaces, reserved, blocksize, bootpri,
1696 				donotmount, autoboot, (TCHAR*)NULL, hdc, flags);
1697 		set_hd_state ();
1698 #endif // 0
1699 /// FIXME: add_filesys_unit() needs uaedev_config_info* !
1700 #if 0
1701     } else {
1702 		add_filesys_unit (dirdlg_devname, dirdlg_volname, dirdlg_path, readonly,
1703 				0, secspertrack, surfaces, reserved, blocksize, bootpri,
1704 				donotmount, autoboot, (TCHAR*)NULL, hdc, flags);
1705 		set_hd_state ();
1706 #endif // 0
1707     }
1708     gtk_widget_destroy (dirdlg);
1709 }
1710 
1711 
1712 GtkWidget *path_selector;
1713 
did_dirdlg_done_select(GtkObject * o,gpointer entry)1714 static void did_dirdlg_done_select (GtkObject *o, gpointer entry )
1715 {
1716     assert (GTK_IS_ENTRY (entry));
1717 
1718     gtk_entry_set_text (GTK_ENTRY (entry), gtk_file_selection_get_filename (GTK_FILE_SELECTION (path_selector)));
1719 }
1720 
did_dirdlg_select(GtkObject * o,gpointer entry)1721 static void did_dirdlg_select (GtkObject *o, gpointer entry )
1722 {
1723     assert( GTK_IS_ENTRY(entry) );
1724     path_selector = gtk_file_selection_new ("Select a folder to mount");
1725     gtk_file_selection_set_filename (GTK_FILE_SELECTION (path_selector), gtk_entry_get_text (GTK_ENTRY (entry)));
1726     gtk_window_set_modal (GTK_WINDOW (path_selector), true);
1727 
1728     gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(path_selector)->ok_button),
1729 					  "clicked", GTK_SIGNAL_FUNC (did_dirdlg_done_select),
1730 					  (gpointer) entry);
1731     gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(path_selector)->ok_button),
1732 					  "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
1733 					  (gpointer) path_selector);
1734     gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(path_selector)->cancel_button),
1735 					  "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
1736 					  (gpointer) path_selector);
1737 
1738     /* Gtk1.2 doesn't have a directory chooser widget, so we fake one from the
1739      * file dialog by hiding the widgets related to file selection */
1740     gtk_widget_hide ((GTK_FILE_SELECTION(path_selector)->file_list)->parent);
1741     gtk_widget_hide (GTK_FILE_SELECTION(path_selector)->fileop_del_file);
1742     gtk_widget_hide (GTK_FILE_SELECTION(path_selector)->fileop_ren_file);
1743     gtk_widget_hide (GTK_FILE_SELECTION(path_selector)->selection_entry);
1744     gtk_entry_set_text (GTK_ENTRY (GTK_FILE_SELECTION(path_selector)->selection_entry), "" );
1745 
1746     gtk_widget_show (path_selector);
1747 }
1748 
dirdlg_on_change(GtkObject * o,gpointer data)1749 static void dirdlg_on_change (GtkObject *o, gpointer data)
1750 {
1751   int can_complete = (strlen (gtk_entry_get_text (GTK_ENTRY(path_entry))) !=0)
1752 		  && (strlen (gtk_entry_get_text (GTK_ENTRY(volname_entry))) != 0)
1753 		  && (strlen (gtk_entry_get_text (GTK_ENTRY(devname_entry))) != 0);
1754 
1755   gtk_widget_set_sensitive (dirdlg_ok, can_complete);
1756 }
1757 
create_dirdlg(const char * title)1758 static void create_dirdlg (const char *title)
1759 {
1760     GtkWidget *dialog_vbox, *dialog_hbox, *vbox, *frame, *table, *hbox, *thing, *label, *button;
1761 
1762     dirdlg = gtk_dialog_new ();
1763 
1764     gtk_window_set_title (GTK_WINDOW (dirdlg), title);
1765     gtk_window_set_position (GTK_WINDOW (dirdlg), GTK_WIN_POS_MOUSE);
1766     gtk_window_set_modal (GTK_WINDOW (dirdlg), true);
1767     gtk_widget_show (dirdlg);
1768 
1769     dialog_vbox = GTK_DIALOG (dirdlg)->vbox;
1770     gtk_widget_show (dialog_vbox);
1771 
1772     vbox = gtk_vbox_new (false, 0);
1773     gtk_widget_show (vbox);
1774     gtk_box_pack_start (GTK_BOX (dialog_vbox), vbox, true, false, 0);
1775 
1776     frame = gtk_frame_new ("Mount host folder");
1777     gtk_widget_show (frame);
1778     gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
1779     gtk_container_set_border_width (GTK_CONTAINER (frame), 8);
1780 
1781     hbox = gtk_hbox_new (false, 4);
1782     gtk_widget_show (hbox);
1783     gtk_container_add (GTK_CONTAINER (frame), hbox);
1784     gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
1785 
1786     label  = gtk_label_new ("Path");
1787     gtk_box_pack_start (GTK_BOX (hbox), label, false, false, 0);
1788     gtk_widget_show (label);
1789 
1790     thing = gtk_entry_new_with_max_length (255);
1791     gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) dirdlg_on_change, (gpointer) NULL);
1792     gtk_box_pack_start (GTK_BOX (hbox), thing, true, true, 0);
1793     gtk_widget_show (thing);
1794     path_entry = thing;
1795 
1796     button = gtk_button_new_with_label ("Select...");
1797     gtk_signal_connect (GTK_OBJECT (button), "clicked", (GtkSignalFunc) did_dirdlg_select, (gpointer) path_entry);
1798     gtk_box_pack_start (GTK_BOX (hbox), button, false, false, 0);
1799     gtk_widget_show (button);
1800 
1801     frame = gtk_frame_new ("As Amiga disk");
1802     gtk_widget_show (frame);
1803     gtk_box_pack_start (GTK_BOX (vbox), frame, false, false, 0);
1804     gtk_container_set_border_width (GTK_CONTAINER (frame), 8);
1805 
1806     table = gtk_table_new (3, 4, false);
1807     gtk_widget_show (table);
1808     gtk_container_add (GTK_CONTAINER (frame), table);
1809     gtk_container_set_border_width (GTK_CONTAINER (table), 8);
1810     gtk_table_set_row_spacings (GTK_TABLE (table), 4);
1811     gtk_table_set_col_spacings (GTK_TABLE (table), 4);
1812 
1813 	label = gtk_label_new ("Device name");
1814 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1815 	gtk_widget_show (label);
1816 	thing = gtk_entry_new_with_max_length (255);
1817 	gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) dirdlg_on_change, (gpointer) NULL);
1818 	gtk_widget_show (thing);
1819 	gtk_table_attach (GTK_TABLE (table), thing, 1, 2, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1820 	gtk_widget_set_usize (thing, 200, -1);
1821 	devname_entry = thing;
1822 
1823 	label = gtk_label_new ("Volume name");
1824 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1825 	gtk_widget_show (label);
1826 	thing = gtk_entry_new_with_max_length (255);
1827 	gtk_signal_connect (GTK_OBJECT (thing), "changed", (GtkSignalFunc) dirdlg_on_change, (gpointer) NULL);
1828 	gtk_table_attach (GTK_TABLE (table), thing, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1829 	gtk_widget_show (thing);
1830 	gtk_widget_set_usize (thing, 200, -1);
1831 	volname_entry = thing;
1832 
1833 	label = gtk_label_new ("Boot priority");
1834 	gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1835 	gtk_widget_show (label);
1836 	thing = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -128, 127, 1, 5, 5)), 1, 0);
1837 	gtk_table_attach (GTK_TABLE (table), thing, 3, 4, 0, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1838 	gtk_widget_show (thing);
1839 	bootpri_widget = thing;
1840 
1841 	readonly_widget = gtk_check_button_new_with_label ("Read only");
1842 	gtk_table_attach (GTK_TABLE (table), readonly_widget, 0, 4, 2, 3, (GtkAttachOptions) (GTK_EXPAND), (GtkAttachOptions) (0), 0, 0);
1843 	gtk_widget_show (readonly_widget);
1844 
1845     dialog_hbox = GTK_DIALOG (dirdlg)->action_area;
1846 
1847     hbox = gtk_hbutton_box_new();
1848     gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
1849     gtk_box_pack_start (GTK_BOX (dialog_hbox), hbox, true, true, 0);
1850     gtk_widget_show (hbox);
1851 
1852     button = gtk_button_new_with_label ("OK");
1853     gtk_widget_set_sensitive (GTK_WIDGET (button), false);
1854     gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC(newdir_ok), NULL);
1855     gtk_box_pack_start (GTK_BOX (hbox), button, true, true, 0);
1856     gtk_widget_show (button);
1857     dirdlg_ok = button;
1858 
1859     button = gtk_button_new_with_label ("Cancel");
1860     gtk_signal_connect_object (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (dirdlg));
1861     GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1862     gtk_box_pack_start (GTK_BOX (hbox), button, true, true, 0);
1863     gtk_widget_grab_default (button);
1864     gtk_widget_show (button);
1865 }
1866 
did_newdir(void)1867 static void did_newdir (void)
1868 {
1869     hd_change_mode = 0;
1870     create_dirdlg ("Add a hard disk");
1871 }
did_newhdf(void)1872 static void did_newhdf (void)
1873 {
1874     hd_change_mode = 0;
1875 }
1876 
did_hdchange(void)1877 static void did_hdchange (void)
1878 {
1879     int secspertrack=0, surfaces=0, reserved=0, blocksize=0, bootpri=0;
1880     uae_u64 size=0;
1881     int cylinders=0, readonly=0, flags=0;
1882     char *devname=NULL, *volname=NULL, *rootdir=NULL, *filesysdir=NULL;
1883     const char *failure;
1884 
1885 /*    failure = get_filesys_unit (selected_hd_row,
1886 				&devname, &volname, &rootdir, &readonly,
1887 				&secspertrack, &surfaces, &reserved,
1888 				&cylinders, &size, &blocksize, &bootpri,
1889 				&filesysdir, &flags);
1890 */
1891     hd_change_mode = 1;
1892     if (is_hardfile (selected_hd_row)) {
1893     } else {
1894 		create_dirdlg ("Hard disk properties");
1895 		gtk_entry_set_text (GTK_ENTRY (devname_entry), devname);
1896 		gtk_entry_set_text (GTK_ENTRY (volname_entry), volname);
1897 		gtk_entry_set_text (GTK_ENTRY (path_entry), rootdir);
1898 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (readonly_widget), readonly);
1899 		gtk_spin_button_set_value (GTK_SPIN_BUTTON (bootpri_widget), bootpri);
1900    }
1901 }
did_hddel(void)1902 static void did_hddel (void)
1903 {
1904     kill_filesys_unitconfig (&currprefs, selected_hd_row);
1905     set_hd_state ();
1906 }
1907 
hdselect(GtkWidget * widget,gint row,gint column,GdkEventButton * bevent,gpointer user_data)1908 static void hdselect (GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,
1909 		      gpointer user_data)
1910 {
1911     selected_hd_row = row;
1912     gtk_widget_set_sensitive (hdchange_button, true);
1913     gtk_widget_set_sensitive (hddel_button, true);
1914 }
1915 
hdunselect(GtkWidget * widget,gint row,gint column,GdkEventButton * bevent,gpointer user_data)1916 static void hdunselect (GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,
1917 			gpointer user_data)
1918 {
1919     gtk_widget_set_sensitive (hdchange_button, false);
1920     gtk_widget_set_sensitive (hddel_button, false);
1921 }
1922 #endif // FILESYS
1923 
make_buttons(const char * label,GtkWidget * box,void (* sigfunc)(void),GtkWidget * (* create)(const char * label))1924 static GtkWidget *make_buttons (const char *label, GtkWidget *box, void (*sigfunc) (void), GtkWidget *(*create)(const char *label))
1925 {
1926     GtkWidget *thing = create (label);
1927     gtk_widget_show (thing);
1928     gtk_signal_connect (GTK_OBJECT (thing), "clicked", (GtkSignalFunc) sigfunc, NULL);
1929     gtk_box_pack_start (GTK_BOX (box), thing, true, true, 0);
1930 
1931     return thing;
1932 }
1933 #define make_button(label, box, sigfunc) make_buttons(label, box, sigfunc, gtk_button_new_with_label)
1934 
1935 #ifdef FILESYS
make_hd_widgets(GtkWidget * dvbox)1936 static void make_hd_widgets (GtkWidget *dvbox)
1937 {
1938     GtkWidget *frame, *vbox, *scrollbox, *thing, *buttonbox, *hbox;
1939 //    char *titles [] = {
1940 //	"Volume", "File/Directory", "R/O", "Heads", "Cyl.", "Sec.", "Rsrvd", "Size", "Blksize"
1941 //    };
1942 
1943 
1944     frame = gtk_frame_new (NULL);
1945     gtk_widget_show (frame);
1946     gtk_box_pack_start (GTK_BOX (dvbox), frame, true, true, 0);
1947     gtk_container_set_border_width (GTK_CONTAINER (frame), 8);
1948 
1949     vbox = gtk_vbox_new (false, 0);
1950     gtk_widget_show (vbox);
1951     gtk_container_add (GTK_CONTAINER (frame), vbox);
1952 
1953     scrollbox = gtk_scrolled_window_new (NULL, NULL);
1954     gtk_widget_show (scrollbox);
1955     gtk_box_pack_start (GTK_BOX (vbox), scrollbox, true, true, 0);
1956     gtk_container_set_border_width (GTK_CONTAINER (scrollbox), 8);
1957     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbox), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1958 
1959     thing = gtk_clist_new_with_titles (HDLIST_MAX_COLS, (gchar **)hdlist_col_titles );
1960     gtk_clist_set_selection_mode (GTK_CLIST (thing), GTK_SELECTION_SINGLE);
1961     gtk_signal_connect (GTK_OBJECT (thing), "select_row", (GtkSignalFunc) hdselect, NULL);
1962     gtk_signal_connect (GTK_OBJECT (thing), "unselect_row", (GtkSignalFunc) hdunselect, NULL);
1963     hdlist_widget = thing;
1964     gtk_widget_set_usize (thing, -1, 200);
1965     gtk_widget_show (thing);
1966     gtk_container_add (GTK_CONTAINER (scrollbox), thing);
1967 
1968     /* The buttons */
1969     buttonbox = gtk_hbutton_box_new ();
1970     gtk_widget_show (buttonbox);
1971     gtk_box_pack_start (GTK_BOX (vbox), buttonbox, false, false, 0);
1972     gtk_container_set_border_width (GTK_CONTAINER (buttonbox), 8);
1973     gtk_button_box_set_layout (GTK_BUTTON_BOX (buttonbox), GTK_BUTTONBOX_SPREAD);
1974 
1975     make_button ("Add...", buttonbox, did_newdir);
1976 #if 0 /* later... */
1977     make_button ("New hardfile...", buttonbox, did_newhdf);
1978 #endif
1979     hdchange_button = make_button ("Properties...", buttonbox, did_hdchange);
1980     hddel_button = make_button ("Remove", buttonbox, did_hddel);
1981 
1982     hdpanel = frame;
1983 }
1984 #endif
1985 
make_about_widgets(GtkWidget * dvbox)1986 static void make_about_widgets (GtkWidget *dvbox)
1987 {
1988     GtkWidget *thing;
1989 //fixme
1990 #if GTK_MAJOR_VERSION >= 2
1991     const char title[] = "<span font_desc=\"Sans 24\">2.5.0</span>";
1992 #else
1993     const char title[] = "2.5.0";
1994 #endif
1995 
1996     add_empty_vbox (dvbox);
1997 
1998 #if GTK_MAJOR_VERSION >= 2
1999     thing = gtk_label_new (NULL);
2000     gtk_label_set_markup (GTK_LABEL (thing), title);
2001 #else
2002     thing = gtk_label_new (title);
2003     {
2004 	GdkFont *font = gdk_font_load ("-*-helvetica-medium-r-normal--*-240-*-*-*-*-*-*");
2005 	if (font) {
2006 	    GtkStyle *style = gtk_style_copy (GTK_WIDGET (thing)->style);
2007 	    gdk_font_unref (style->font);
2008 	    gdk_font_ref (font);
2009 	    style->font = font;
2010 	    gtk_widget_set_style (thing, style);
2011 	}
2012     }
2013 #endif
2014     gtk_widget_show (thing);
2015     add_centered_to_vbox (dvbox, thing);
2016 
2017 #ifdef PACKAGE_VERSION
2018     thing = gtk_label_new ("Version " PACKAGE_VERSION );
2019     gtk_widget_show (thing);
2020     add_centered_to_vbox (dvbox, thing);
2021 #endif
2022 
2023     add_empty_vbox (dvbox);
2024 }
2025 
did_guidlg_delete(GtkWidget * window,GdkEventAny * e,gpointer data)2026 static gint did_guidlg_delete (GtkWidget* window, GdkEventAny* e, gpointer data)
2027 {
2028     if (!quit_gui)
2029 	write_comm_pipe_int (&from_gui_pipe, UAECMD_QUIT, 1);
2030     gui_window = 0;
2031     return false;
2032 }
2033 
on_menu_saveconfig(void)2034 static void on_menu_saveconfig (void)
2035 {
2036     DEBUG_LOG ("Save config...\n");
2037     if (!quit_gui)
2038 	write_comm_pipe_int (&from_gui_pipe, UAECMD_SAVE_CONFIG, 1);
2039 }
2040 
on_vstat_toggle(GtkWidget * widget,gpointer statusbar)2041 void on_vstat_toggle(GtkWidget *widget, gpointer statusbar)
2042 {
2043   if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
2044     gtk_widget_show(statusbar);
2045   } else {
2046     gtk_widget_hide(statusbar);
2047   }
2048 }
2049 
create_guidlg(void)2050 static void create_guidlg (void)
2051 {
2052     GtkWidget *window, *notebook;
2053     GtkWidget *buttonbox, *vbox, *hbox;
2054     GtkWidget *thing;
2055     GtkWidget *menubar, *menuitem, *menuitem_menu;
2056     GtkWidget *statusbar, *vstatusbar;
2057 
2058     unsigned int i;
2059     static const struct _pages {
2060 	const char *title;
2061 	void (*createfunc)(GtkWidget *);
2062     } pages[] = {
2063 	{ "Floppy disks", make_floppy_disks },
2064 	{ "Memory",       make_mem_widgets },
2065 	{ "CPU",          make_cpu_widgets2 },
2066 	{ "Chipset",      make_chipset_widgets },
2067 	{ "Sound",        make_sound_widgets },
2068 #ifdef JIT
2069 	{ "JIT",          make_comp_widgets },
2070 #endif
2071 	{ "Game ports",   make_joy_widgets },
2072 #ifdef FILESYS
2073 	{ "Hard disks",   make_hd_widgets },
2074 #endif
2075 #ifdef SAVESTATE
2076 	{ "Savestate",    make_ss_widgets },
2077 #endif
2078 	{ "Misc",    	  make_misc_widgets },
2079 	{ "About",        make_about_widgets }
2080     };
2081 
2082     DEBUG_LOG ("Entered\n");
2083 
2084     gui_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2085     gtk_window_set_title (GTK_WINDOW (gui_window), PACKAGE_NAME " control");
2086     gtk_signal_connect (GTK_OBJECT(gui_window), "delete_event", GTK_SIGNAL_FUNC(did_guidlg_delete), NULL);
2087 
2088     vbox = gtk_vbox_new (false, 5);
2089     gtk_container_add (GTK_CONTAINER (gui_window), vbox);
2090     gtk_container_set_border_width (GTK_CONTAINER (gui_window), 10);
2091 
2092     /* Quick and dirty menu bar */
2093     menubar = gtk_menu_bar_new();
2094     gtk_widget_show (menubar);
2095     gtk_box_pack_start (GTK_BOX (vbox), menubar, false, false, 0);
2096 
2097     menuitem = gtk_menu_item_new_with_mnemonic ("_File");
2098     gtk_widget_show (menuitem);
2099     gtk_container_add (GTK_CONTAINER (menubar), menuitem);
2100 
2101     menuitem_menu = gtk_menu_new ();
2102     gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menuitem_menu);
2103 
2104     thing = gtk_menu_item_new_with_mnemonic ("Save config");
2105     gtk_widget_show (thing);
2106     gtk_container_add (GTK_CONTAINER (menuitem_menu), thing);
2107     gtk_signal_connect (GTK_OBJECT(thing), "activate", GTK_SIGNAL_FUNC(on_menu_saveconfig), NULL);
2108 
2109     vstatusbar = gtk_check_menu_item_new_with_label("View Statusbar");
2110     gtk_widget_show (vstatusbar);
2111     gtk_container_add (GTK_CONTAINER (menuitem_menu), vstatusbar);
2112     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vstatusbar), true);
2113 
2114     thing = gtk_separator_menu_item_new ();
2115     gtk_widget_show (thing);
2116     gtk_container_add (GTK_CONTAINER (menuitem_menu), thing);
2117 
2118     thing = gtk_menu_item_new_with_mnemonic ("Quit");
2119     gtk_widget_show (thing);
2120     gtk_container_add (GTK_CONTAINER (menuitem_menu), thing);
2121     gtk_signal_connect (GTK_OBJECT(thing), "activate", GTK_SIGNAL_FUNC(on_quit_clicked), NULL);
2122 
2123     /* First line - buttons and power LED */
2124     hbox = gtk_hbox_new (false, 10);
2125     gtk_widget_show (hbox);
2126     gtk_box_pack_start (GTK_BOX (vbox), hbox, false, true, 0);
2127 
2128     /* The buttons */
2129     buttonbox = gtk_hbox_new (true, 6);
2130     gtk_widget_show (buttonbox);
2131     gtk_box_pack_start (GTK_BOX (hbox), buttonbox, true, true, 0);
2132     start_uae_widget = make_button  ("Start", buttonbox, on_start_clicked);
2133     stop_uae_widget  = make_button  ("Stop",  buttonbox, on_stop_clicked);
2134     pause_uae_widget = make_buttons ("Pause", buttonbox, (void (*) (void))on_pause_clicked, gtk_toggle_button_new_with_label);
2135 #ifdef DEBUGGER
2136 //FIXME    debug_uae_widget = make_button  ("Debug", buttonbox, on_debug_clicked);
2137 #endif
2138     reset_uae_widget = make_button  ("Reset", buttonbox, on_reset_clicked);
2139     make_button ("Quit", buttonbox, on_quit_clicked);
2140 
2141     /* The LED */
2142     power_led = led_new();
2143     gtk_widget_show(power_led);
2144     thing = gtk_vbox_new(false, 4);
2145     add_empty_hbox(thing);
2146     gtk_container_add(GTK_CONTAINER(thing), power_led);
2147     add_empty_hbox(thing);
2148     thing = make_labelled_widget ("Power:", thing);
2149     gtk_widget_show (thing);
2150     gtk_box_pack_start (GTK_BOX (hbox), thing, false, true, 0);
2151 
2152     /* More buttons */
2153     buttonbox = gtk_hbox_new (true, 4);
2154     gtk_widget_show (buttonbox);
2155     gtk_box_pack_start (GTK_BOX (vbox), buttonbox, false, false, 0);
2156 
2157     /* Place a separator below those buttons.  */
2158     thing = gtk_hseparator_new ();
2159     gtk_box_pack_start (GTK_BOX (vbox), thing, false, true, 0);
2160     gtk_widget_show (thing);
2161 
2162     /* Now the notebook */
2163     notebook = gtk_notebook_new ();
2164     gtk_box_pack_start (GTK_BOX (vbox), notebook, true, true, 0);
2165     gtk_widget_show (notebook);
2166 
2167     for (i = 0; i < sizeof pages / sizeof (struct _pages); i++) {
2168 		thing = gtk_vbox_new (false, 4);
2169 		gtk_widget_show (thing);
2170 		gtk_container_set_border_width (GTK_CONTAINER (thing), 10);
2171 		pages[i].createfunc (thing);
2172 		gtk_notebook_append_page (GTK_NOTEBOOK (notebook), thing, gtk_label_new (pages[i].title));
2173     }
2174 
2175     /* Put "about" screen first.  */
2176     gtk_notebook_set_page (GTK_NOTEBOOK (notebook), i - 1);
2177 
2178     /* Statusbar for FPS etc */
2179     statusbar = gtk_statusbar_new();
2180     gtk_box_pack_end(GTK_BOX(vbox), statusbar, false, true, 1);
2181     gtk_widget_show(statusbar);
2182     g_signal_connect(G_OBJECT(vstatusbar), "activate", G_CALLBACK(on_vstat_toggle), statusbar);
2183 
2184     gtk_widget_show (vbox);
2185 
2186     gtk_timeout_add (1000, (GtkFunction)leds_callback, 0);
2187 }
2188 
2189 /*
2190  * gtk_gui_thread()
2191  *
2192  * This is launched as a separate thread to the main UAE thread
2193  * to create and handle the GUI. After the GUI has been set up,
2194  * this calls the standard GTK+ event processing loop.
2195  *
2196  */
gtk_gui_thread(void * dummy)2197 static void *gtk_gui_thread (void *dummy)
2198 {
2199     /* fake args for gtk_init() */
2200     int argc = 1;
2201     char *a[] = {"UAE"};
2202     char **argv = a;
2203 
2204     DEBUG_LOG ("Started\n");
2205 
2206     gui_active = 0;
2207 
2208     if (gtk_init_check (&argc, &argv)) {
2209 	DEBUG_LOG ("gtk_init() successful\n");
2210 
2211 	gtk_rc_parse ("uaegtkrc");
2212 	gui_available = 1;
2213 
2214 	/* Add callback to GTK+ mainloop to handle messages from UAE */
2215 	gtk_timeout_add (250, (GtkFunction)my_idle, 0);
2216 
2217 	/* We're ready - tell the world */
2218 	uae_sem_post (&gui_init_sem);
2219 
2220 	/* Enter GTK+ main loop */
2221 	DEBUG_LOG ("Entering GTK+ main loop\n");
2222 	gtk_main ();
2223 
2224 	/* Main loop has exited, so the GUI will quit */
2225 	quitted_gui = 1;
2226 	uae_sem_post (&gui_quit_sem);
2227 	DEBUG_LOG ("Exiting\n");
2228     } else {
2229 	DEBUG_LOG ("gtk_init() failed\n");
2230 	/* If GTK+ can't display, we still need to say we're done */
2231 	uae_sem_post (&gui_init_sem);
2232     }
2233     return 0;
2234 }
2235 
gui_fps(int fps,int idle,int color)2236 void gui_fps (int fps, int idle, int color)
2237 {
2238     gui_data.fps  = fps;
2239     gui_data.idle = idle;
2240 //        gui_led (LED_FPS, 0);
2241 //        gui_led (LED_CPU, 0);
2242 //        gui_led (LED_SND, gui_data.sndbuf_status > 1 || gui_data.sndbuf_status < 0);
2243 
2244 //gchar *str;
2245 //str = g_strdup_printf("FPS: %d",fps);
2246 //gtk_statusbar_push(GTK_STATUSBAR(window),gtk_statusbar_get_context_id(GTK_STATUSBAR(window),str), str);
2247 }
2248 
2249 /*
2250  * gui_led()
2251  *
2252  * Called from the main UAE thread to inform the GUI
2253  * of disk activity so that indicator LEDs may be refreshed.
2254  *
2255  * We don't respond to this, since our LEDs are updated
2256  * periodically by my_idle()
2257  */
gui_led(int num,int on)2258 void gui_led (int num, int on)
2259 {
2260 }
2261 
2262 
2263 /*
2264  * gui_filename()
2265  *
2266  * This is called from the main UAE thread to inform
2267  * the GUI that a floppy disk has been inserted or ejected.
2268  */
gui_filename(int num,const char * name)2269 void gui_filename (int num, const char *name)
2270 {
2271     if (!gui_available)
2272 	    return;
2273 
2274 	write_comm_pipe_int (&to_gui_pipe, GUICMD_DISKCHANGE, 0);
2275 	write_comm_pipe_int (&to_gui_pipe, num, 1);
2276 }
2277 
2278 
2279 /*
2280  * gui_handle_events()
2281  *
2282  * This is called from the main UAE thread to handle the
2283  * processing of GUI-related events sent from the GUI thread.
2284  *
2285  * If the UAE emulation proper is not running yet or is paused,
2286  * this loops continuously waiting for and responding to events
2287  * until the emulation is started or resumed, respectively. When
2288  * the emulation is running, this is called periodically from
2289  * the main UAE event loop.
2290  */
gui_handle_events(void)2291 void gui_handle_events (void)
2292 {
2293     if (!gui_available)
2294 			return;
2295 
2296     while (comm_pipe_has_data (&from_gui_pipe)) {
2297 		int cmd = read_comm_pipe_int_blocking (&from_gui_pipe);
2298 
2299 	switch (cmd) {
2300 	    case UAECMD_EJECTDISK: {
2301 			int n = read_comm_pipe_int_blocking (&from_gui_pipe);
2302 			uae_sem_wait (&gui_sem);
2303 			changed_prefs.floppyslots[n].df[0] = '\0';
2304 			uae_sem_post (&gui_sem);
2305 			if (pause_uae) {
2306 			    /* When UAE is running it will notify the GUI when a disk has been inserted
2307 			     * or removed itself. When UAE is paused, however, we need to do this ourselves
2308 			     * or the change won't be realized in the GUI until UAE is resumed */
2309 			    write_comm_pipe_int (&to_gui_pipe, GUICMD_DISKCHANGE, 0);
2310 			    write_comm_pipe_int (&to_gui_pipe, n, 1);
2311 			}
2312 			break;
2313 		    }
2314 	    case UAECMD_INSERTDISK: {
2315 			int n = read_comm_pipe_int_blocking (&from_gui_pipe);
2316 			uae_sem_wait (&gui_sem);
2317 			strncpy (changed_prefs.floppyslots[n].df, new_disk_string[n], 255);
2318 			xfree (new_disk_string[n]);
2319 			new_disk_string[n] = 0;
2320 			changed_prefs.floppyslots[n].df[255] = '\0';
2321 			uae_sem_post (&gui_sem);
2322 			if (pause_uae) {
2323 			    /* When UAE is running it will notify the GUI when a disk has been inserted
2324 			     * or removed itself. When UAE is paused, however, we need to do this ourselves
2325 			     * or the change won't be realized in the GUI until UAE is resumed */
2326 			    write_comm_pipe_int (&to_gui_pipe, GUICMD_DISKCHANGE, 0);
2327 			    write_comm_pipe_int (&to_gui_pipe, n, 1);
2328 			}
2329 			break;
2330 		    }
2331 	    case UAECMD_RESET:
2332 			uae_reset (0, 0);
2333 			break;
2334 #ifdef DEBUGGER
2335 	    case UAECMD_DEBUG:
2336 			activate_debugger ();
2337 			break;
2338 #endif
2339 	    case UAECMD_QUIT:
2340 			uae_quit ();
2341 			break;
2342 	    case UAECMD_PAUSE:
2343 			pause_uae = 1;
2344 			uae_pause ();
2345 			break;
2346 	    case UAECMD_RESUME:
2347 			pause_uae = 0;
2348 			uae_resume ();
2349 			break;
2350 	    case UAECMD_SAVE_CONFIG:
2351 			uae_sem_wait (&gui_sem);
2352 			//uae_save_config ();
2353 			uae_sem_post (&gui_sem);
2354 			break;
2355 	    case UAECMD_SELECT_ROM:
2356 			uae_sem_wait (&gui_sem);
2357 			strncpy (changed_prefs.romfile, gui_romname, 255);
2358 			changed_prefs.romfile[255] = '\0';
2359 			xfree (gui_romname);
2360 			uae_sem_post (&gui_sem);
2361 			break;
2362 #ifdef SAVESTATE
2363 	    case UAECMD_SAVESTATE_LOAD:
2364 			uae_sem_wait (&gui_sem);
2365 			savestate_initsave (gui_sstate_name, 0, 0, 0);
2366 			savestate_state = STATE_DORESTORE;
2367 			write_log ("Restoring state from '%s'...\n", gui_sstate_name);
2368 			uae_sem_post (&gui_sem);
2369 			break;
2370 	    case UAECMD_SAVESTATE_SAVE:
2371 			uae_sem_wait (&gui_sem);
2372 			savestate_initsave (gui_sstate_name, 0, 0, 0);
2373 			save_state (gui_sstate_name, "puae");
2374 			write_log ("Saved state to '%s'...\n", gui_sstate_name);
2375 			uae_sem_post (&gui_sem);
2376 			break;
2377 #endif
2378 /*	    case UAECMD_START:
2379 			uae_start ();
2380 			break;
2381 		case UAECMD_STOP:
2382 			uae_stop ();
2383 			break;*/
2384 	}
2385     }
2386 }
2387 
2388 /*
2389  * gui_update()
2390  *
2391  * This is called from the main UAE thread to tell the GUI to update itself
2392  * using the current state of currprefs. This function will block
2393  * until it receives a message from the GUI telling it that the update
2394  * is complete.
2395  */
gui_update(void)2396 int gui_update (void)
2397 {
2398     DEBUG_LOG( "Entered\n" );
2399     return 0;
2400     if (gui_available) {
2401 		write_comm_pipe_int (&to_gui_pipe, GUICMD_UPDATE, 1);
2402 		uae_sem_wait (&gui_update_sem);
2403     }
2404     return 0;
2405 }
2406 
2407 
2408 /*
2409  * gui_exit()
2410  *
2411  * This called from the main UAE thread to tell the GUI to gracefully
2412  * quit. We don't need to do anything here for now. Our main() takes
2413  * care of putting the GUI to bed.
2414  */
gui_exit(void)2415 void gui_exit (void)
2416 {
2417 }
2418 
2419 /*
2420  * gui_shutdown()
2421  *
2422  * Tell the GUI thread it's time to say goodnight...
2423  */
gui_shutdown(void)2424 static void gui_shutdown (void)
2425 {
2426     DEBUG_LOG( "Entered\n" );
2427 
2428     if (gui_available) {
2429 	if (!quit_gui) {
2430 	    quit_gui = 1;
2431 	    DEBUG_LOG( "Waiting for GUI thread to quit.\n" );
2432 	    uae_sem_wait (&gui_quit_sem);
2433 	}
2434     }
2435 }
2436 
gui_flicker_led2(int led,int unitnum,int status)2437 static void gui_flicker_led2 (int led, int unitnum, int status)
2438 {
2439         static int resetcounter[LED_MAX];
2440         uae_s8 old;
2441         uae_s8 *p;
2442 
2443         if (led == LED_HD)
2444                 p = &gui_data.hd;
2445         else if (led == LED_CD)
2446                 p = &gui_data.cd;
2447         else if (led == LED_MD)
2448                 p = &gui_data.md;
2449         else
2450                 return;
2451         old = *p;
2452         if (status == 0) {
2453                 resetcounter[led]--;
2454                 if (resetcounter[led] > 0)
2455                         return;
2456         }
2457 #ifdef RETROPLATFORM
2458         if (led == LED_HD)
2459                 rp_hd_activity (unitnum, status ? 1 : 0, status == 2 ? 1 : 0);
2460         else if (led == LED_CD)
2461                 rp_cd_activity (unitnum, status);
2462 #endif
2463         *p = status;
2464         resetcounter[led] = 6;
2465         if (old != *p)
2466                 gui_led (led, *p);
2467 }
2468 
gui_flicker_led(int led,int unitnum,int status)2469 void gui_flicker_led (int led, int unitnum, int status)
2470 {
2471         if (led < 0) {
2472                 gui_flicker_led2 (LED_HD, 0, 0);
2473                 gui_flicker_led2 (LED_CD, 0, 0);
2474                 gui_flicker_led2 (LED_MD, 0, 0);
2475         } else {
2476                 gui_flicker_led2 (led, unitnum, status);
2477         }
2478 }
2479 
gui_display(int shortcut)2480 void gui_display (int shortcut)
2481 {
2482     DEBUG_LOG ("called with shortcut=%d\n", shortcut);
2483 
2484     if (gui_available) {
2485 	/* If running fullscreen, then we must try to switched to windowed
2486 	 * mode before activating the GUI */
2487 	if (is_fullscreen ()) {
2488 	    toggle_fullscreen (0);
2489 	    if (is_fullscreen ()) {
2490 		write_log ("Cannot activate GUI in full-screen mode\n");
2491 		return;
2492 	    }
2493 	}
2494 
2495 	if (shortcut == -1)
2496 	    write_comm_pipe_int (&to_gui_pipe, GUICMD_SHOW, 1);
2497 
2498 	if (shortcut >=0 && shortcut <4) {
2499 	    /* In this case, shortcut is the drive number to display
2500 	     * the insert requester for */
2501 	    write_comm_pipe_int (&to_gui_pipe, GUICMD_FLOPPYDLG, 0);
2502 	    write_comm_pipe_int (&to_gui_pipe, shortcut, 1);
2503 	}
2504     }
2505 
2506 	inputdevice_copyconfig (&changed_prefs, &currprefs);
2507 	inputdevice_config_change_test ();
2508 	clearallkeys ();
2509 	inputdevice_acquire (true);
2510 	setmouseactive (1);
2511 }
2512 
gui_message(const char * format,...)2513 void gui_message (const char *format,...)
2514 {
2515     char msg[2048];
2516     va_list parms;
2517 
2518     va_start (parms,format);
2519     vsprintf ( msg, format, parms);
2520     va_end (parms);
2521 
2522     if (gui_available)
2523 		do_message_box (NULL, msg, true, true);
2524 
2525     write_log ("%s", msg);
2526 }
2527 
2528 /*
2529  * do_message_box()
2530  *
2531  * This makes up for GTK's lack of a function for creating simple message dialogs.
2532  * It can be called from any context. gui_init() must have been called at some point
2533  * previously.
2534  *
2535  * title   - will be displayed in the dialog's titlebar (or NULL for default)
2536  * message - the message itself
2537  * modal   - should the dialog block input to the rest of the GUI
2538  * wait    - should the dialog wait until the user has acknowledged it
2539  */
do_message_box(const gchar * title,const gchar * message,gboolean modal,gboolean wait)2540 static void do_message_box (const gchar *title, const gchar *message, gboolean modal, gboolean wait )
2541 {
2542     uae_sem_t msg_quit_sem = {0};
2543 
2544     // If we a need reply, then this semaphore which will be used
2545     // to signal us when the dialog has been exited.
2546     uae_sem_init (&msg_quit_sem, 0, 0);
2547 
2548     write_comm_pipe_int   (&to_gui_pipe, GUICMD_MSGBOX, 0);
2549     write_comm_pipe_pvoid (&to_gui_pipe, (void *) title, 0);
2550     write_comm_pipe_pvoid (&to_gui_pipe, (void *) message, 0);
2551     write_comm_pipe_int   (&to_gui_pipe, (int) modal, 0);
2552     write_comm_pipe_pvoid (&to_gui_pipe, wait?&msg_quit_sem:NULL, 1);
2553 
2554     if (wait)
2555 	uae_sem_wait (&msg_quit_sem);
2556 
2557     DEBUG_LOG ("do_message_box() done");
2558     return;
2559 }
2560 
2561 /*
2562  * handle_message_box_request()
2563  *
2564  * This is called from the GUI's context in repsonse to do_message_box()
2565  * to actually create the dialog box
2566  */
handle_message_box_request(smp_comm_pipe * msg_pipe)2567 static void handle_message_box_request (smp_comm_pipe *msg_pipe)
2568 {
2569     const gchar *title      = (const gchar *)  read_comm_pipe_pvoid_blocking (msg_pipe);
2570     const gchar *msg        = (const gchar *)  read_comm_pipe_pvoid_blocking (msg_pipe);
2571     int modal               =                  read_comm_pipe_int_blocking   (msg_pipe);
2572     uae_sem_t *msg_quit_sem = (uae_sem_t *)    read_comm_pipe_pvoid_blocking (msg_pipe);
2573 
2574     GtkWidget *dialog = make_message_box (title, msg, modal, msg_quit_sem);
2575 }
2576 
2577 /*
2578  * on_message_box_quit()
2579  *
2580  * Handler called when message box is exited. Signals anybody that cares
2581  * via the semaphore it is supplied.
2582  */
on_message_box_quit(GtkWidget * w,gpointer user_data)2583 void on_message_box_quit (GtkWidget *w, gpointer user_data)
2584 {
2585     uae_sem_post ((uae_sem_t *)user_data);
2586 }
2587 
2588 /*
2589  * make_message_box()
2590  *
2591  * This does the actual work of constructing the message dialog.
2592  *
2593  * title   - displayed in the dialog's titlebar
2594  * message - the message itself
2595  * modal   - whether the dialog should block input to the rest of the GUI
2596  * sem     - semaphore used for signalling that the dialog's finished
2597  *
2598  * TODO: Make that semaphore go away. We shouldn't need to know about it here.
2599  */
make_message_box(const gchar * title,const gchar * message,int modal,uae_sem_t * sem)2600 static GtkWidget *make_message_box (const gchar *title, const gchar *message, int modal, uae_sem_t *sem )
2601 {
2602     GtkWidget *dialog;
2603     GtkWidget *vbox;
2604     GtkWidget *label;
2605     GtkWidget *hseparator;
2606     GtkWidget *hbuttonbox;
2607     GtkWidget *button;
2608     guint      key;
2609     GtkAccelGroup *accel_group;
2610 
2611     accel_group = gtk_accel_group_new ();
2612 
2613     dialog = gtk_window_new ( GTK_WINDOW_TOPLEVEL /*GTK_WINDOW_DIALOG*/);
2614     gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
2615     if (title==NULL || (title!=NULL && strlen(title)==0))
2616 	title = PACKAGE_NAME " information";
2617     gtk_window_set_title (GTK_WINDOW (dialog), title);
2618     gtk_window_set_modal (GTK_WINDOW (dialog), modal);
2619     gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
2620 
2621     vbox = gtk_vbox_new (false, 0);
2622     gtk_widget_show (vbox);
2623     gtk_container_add (GTK_CONTAINER (dialog), vbox);
2624 
2625     label = gtk_label_new (message);
2626     gtk_widget_show (label);
2627     gtk_box_pack_start (GTK_BOX (vbox), label, true, true, 0);
2628     gtk_label_set_line_wrap (GTK_LABEL (label), true);
2629 
2630     hseparator = gtk_hseparator_new ();
2631     gtk_widget_show (hseparator);
2632     gtk_box_pack_start (GTK_BOX (vbox), hseparator, false, false, 8);
2633 
2634     hbuttonbox = gtk_hbutton_box_new ();
2635     gtk_widget_show (hbuttonbox);
2636     gtk_box_pack_start (GTK_BOX (vbox), hbuttonbox, false, false, 0);
2637     gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
2638     gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox), 4);
2639 
2640     button = make_labelled_button ("_Okay", accel_group);
2641     gtk_widget_show (button);
2642     gtk_container_add (GTK_CONTAINER (hbuttonbox), button);
2643     GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2644 
2645     if (sem)
2646 	gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (on_message_box_quit), sem);
2647     gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2648 						   GTK_SIGNAL_FUNC (gtk_widget_destroy),
2649 						   GTK_OBJECT (dialog));
2650 
2651     gtk_widget_grab_default (button);
2652     gtk_window_add_accel_group (GTK_WINDOW (dialog), accel_group);
2653     gtk_widget_show( dialog );
2654 
2655     return dialog;
2656 }
2657 
gui_init(void)2658 int gui_init (void)
2659 {
2660     uae_thread_id tid;
2661 
2662     /* Check whether we are running with SUID bit set */
2663     if (getuid() == geteuid()) {
2664 	/*
2665 	 * Only try to start Gtk+ GUI if SUID bit is not set
2666 	 */
2667 
2668 	init_comm_pipe (&to_gui_pipe, 20, 1);
2669 	init_comm_pipe (&from_gui_pipe, 20, 1);
2670 	uae_sem_init (&gui_sem, 0, 1);          // Unlock mutex on prefs $
2671 	uae_sem_init (&gui_update_sem, 0, 0);
2672 	uae_sem_init (&gui_init_sem, 0, 0);
2673 	uae_sem_init (&gui_quit_sem, 0, 0);
2674 
2675 	/* Start GUI thread to construct GUI */
2676 	uae_start_thread ("GTK-GUI", gtk_gui_thread, NULL, &tid);
2677 
2678 	/* Wait until GUI thread is ready */
2679 	DEBUG_LOG ("Waiting for GUI thread\n");
2680 	uae_sem_wait (&gui_init_sem);
2681 	DEBUG_LOG ("Okay\n");
2682     }
2683 	return 1;
2684 }
2685 
gui_disk_image_change(int unitnum,const TCHAR * name,bool writeprotected)2686 void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected) {}
gui_lock(void)2687 void gui_lock (void) {}
gui_unlock(void)2688 void gui_unlock (void) {}
2689 static int guijoybutton[MAX_JPORTS];
2690 static int guijoyaxis[MAX_JPORTS][4];
2691 static bool guijoychange;
gui_gameport_button_change(int port,int button,int onoff)2692 void gui_gameport_button_change (int port, int button, int onoff)
2693 {
2694         //write_log ("%d %d %d\n", port, button, onoff);
2695 #ifdef RETROPLATFORM
2696         int mask = 0;
2697         if (button == JOYBUTTON_CD32_PLAY)
2698                 mask = RP_JOYSTICK_BUTTON5;
2699         if (button == JOYBUTTON_CD32_RWD)
2700                 mask = RP_JOYSTICK_BUTTON6;
2701         if (button == JOYBUTTON_CD32_FFW)
2702                 mask = RP_JOYSTICK_BUTTON7;
2703         if (button == JOYBUTTON_CD32_GREEN)
2704                 mask = RP_JOYSTICK_BUTTON4;
2705         if (button == JOYBUTTON_3 || button == JOYBUTTON_CD32_YELLOW)
2706                 mask = RP_JOYSTICK_BUTTON3;
2707         if (button == JOYBUTTON_1 || button == JOYBUTTON_CD32_RED)
2708                 mask = RP_JOYSTICK_BUTTON1;
2709         if (button == JOYBUTTON_2 || button == JOYBUTTON_CD32_BLUE)
2710                 mask = RP_JOYSTICK_BUTTON2;
2711         rp_update_gameport (port, mask, onoff);
2712 #endif
2713         if (onoff)
2714                 guijoybutton[port] |= 1 << button;
2715         else
2716                 guijoybutton[port] &= ~(1 << button);
2717         guijoychange = true;
2718 }
2719 
gui_gameport_axis_change(int port,int axis,int state,int max)2720 void gui_gameport_axis_change (int port, int axis, int state, int max)
2721 {
2722         int onoff = state ? 100 : 0;
2723         if (axis < 0 || axis > 3)
2724                 return;
2725         if (max < 0) {
2726                 if (guijoyaxis[port][axis] == 0)
2727                         return;
2728                 if (guijoyaxis[port][axis] > 0)
2729                         guijoyaxis[port][axis]--;
2730         } else {
2731                 if (state > max)
2732                         state = max;
2733                 if (state < 0)
2734                         state = 0;
2735                 guijoyaxis[port][axis] = max ? state * 127 / max : onoff;
2736 #ifdef RETROPLATFORM
2737                 if (axis == DIR_LEFT_BIT)
2738                         rp_update_gameport (port, RP_JOYSTICK_LEFT, onoff);
2739                 if (axis == DIR_RIGHT_BIT)
2740                         rp_update_gameport (port, DIR_RIGHT_BIT, onoff);
2741                 if (axis == DIR_UP_BIT)
2742                         rp_update_gameport (port, DIR_UP_BIT, onoff);
2743                 if (axis == DIR_DOWN_BIT)
2744                         rp_update_gameport (port, DIR_DOWN_BIT, onoff);
2745 #endif
2746         }
2747         guijoychange = true;
2748 }
2749