1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id: popup.c 2840 2009-05-08 20:43:47Z kevinkofler $ */
3 
4 /*  TiEmu - Tiemu Is an EMUlator
5  *
6  *  Copyright (c) 2000-2001, Thomas Corvazier, Romain Lievin
7  *  Copyright (c) 2001-2003, Romain Lievin
8  *  Copyright (c) 2003, Julien Blache
9  *  Copyright (c) 2004, Romain Li�vin
10  *  Copyright (c) 2005-2007, Romain Li�vin, Kevin Kofler
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details. *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28 
29 #include <gtk/gtk.h>
30 #include <glade/glade.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #ifdef __MINGW32__
34 #include <windows.h>
35 #endif
36 
37 #include "intl.h"
38 #include "support.h"
39 #include "struct.h"
40 #include "version.h"
41 #include "popup.h"
42 #include "paths.h"
43 #include "engine.h"
44 #include "fs_misc.h"
45 #include "device.h"
46 #include "rcfile.h"
47 #include "dboxes.h"
48 #include "romversion.h"
49 #include "calc.h"
50 #include "release.h"
51 #include "about.h"
52 #include "infos.h"
53 #include "manpage.h"
54 #include "scroptions.h"
55 #include "tie_error.h"
56 #include "dbg_all.h"
57 #include "quicksend.h"
58 #include "filesel.h"
59 #include "keypress.h"
60 #ifndef NO_SOUND
61 #include "audio.h"
62 #endif
63 
64 #include "ti68k_int.h"
65 #include "ti68k_def.h"
66 
67 GLADE_CB void
on_popup_menu_header(GtkMenuItem * menuitem,gpointer user_data)68 on_popup_menu_header                   (GtkMenuItem     *menuitem,
69                                         gpointer         user_data)
70 {
71 	fprintf(stdout, _("* TiEmu version %s (cables=%s, files=%s, calcs=%s, conv=%s)"),
72 	     TIEMU_VERSION,
73 		 ticables_version_get(), tifiles_version_get(), ticalcs_version_get(), ticonv_version_get());
74 }
75 
76 /* menu part 1 (link) */
77 
78 GLADE_CB void
on_send_file_to_tiemu1_activate(GtkMenuItem * menuitem,gpointer user_data)79 on_send_file_to_tiemu1_activate     (GtkMenuItem     *menuitem,
80                                      gpointer         user_data)
81 {
82 	if(engine_is_stopped()) return;
83 
84 	engine_stop();
85 
86 	if(!options.qs_enabled)
87 		display_send_files_dbox();
88 	else if(options.qs_enabled && options.qs_file && strlen(options.qs_file))
89 		fs_send_file(options.qs_file);
90 
91 	engine_start();
92 }
93 
94 GLADE_CB void
on_recv_file_from_tiemu1_activate(GtkMenuItem * menuitem,gpointer user_data)95 on_recv_file_from_tiemu1_activate     (GtkMenuItem     *menuitem,
96                                        gpointer         user_data)
97 {
98 	int active;
99 	if(engine_is_stopped()) return;
100 	active = GTK_CHECK_MENU_ITEM(menuitem)->active;
101 #ifndef NO_SOUND
102 	if (active)
103 		audio_disable();
104 #endif
105 	params.recv_file = active;
106 }
107 
108 GLADE_CB void
on_emulate_sound1_activate(GtkMenuItem * menuitem,gpointer user_data)109 on_emulate_sound1_activate     (GtkMenuItem     *menuitem,
110                                 gpointer         user_data)
111 {
112 #ifndef NO_SOUND
113 	int active;
114 	if(engine_is_stopped()) return;
115 	active = GTK_CHECK_MENU_ITEM(menuitem)->active;
116 	if (active) {
117 		params.recv_file = 0;
118 		audio_enable();
119 	} else
120 		audio_disable();
121 #endif
122 }
123 
124 
125 GLADE_CB void
on_debug_file_with_tiemu1_activate(GtkMenuItem * menuitem,gpointer user_data)126 on_debug_file_with_tiemu1_activate     (GtkMenuItem     *menuitem,
127                                         gpointer         user_data)
128 {
129 	if(engine_is_stopped()) return;
130 
131 	engine_stop();
132 #ifndef NO_GDB
133 	display_debug_dbox();
134 #endif
135 	engine_start();
136 }
137 
138 
139 GLADE_CB void
on_link_cable1_activate(GtkMenuItem * menuitem,gpointer user_data)140 on_link_cable1_activate                (GtkMenuItem     *menuitem,
141                                         gpointer         user_data)
142 {
143 	if(engine_is_stopped()) return;
144 
145 	engine_stop();
146 	display_device_dbox();
147 	engine_start();
148 }
149 
150 GLADE_CB void
on_quick_send1_activate(GtkMenuItem * menuitem,gpointer user_data)151 on_quick_send1_activate                (GtkMenuItem     *menuitem,
152                                         gpointer         user_data)
153 {
154 	if(engine_is_stopped()) return;
155 
156 	engine_stop();
157 	display_quicksend_dbox();
158 	engine_start();
159 }
160 
161 /* menu part 2 (config & state) */
162 
163 void window_get_rect(GtkWidget *widget, GdkRect *rect);
164 
165 GLADE_CB void
on_save_config1_activate(GtkMenuItem * menuitem,gpointer user_data)166 on_save_config1_activate               (GtkMenuItem     *menuitem,
167                                         gpointer         user_data)
168 {
169 	// save main window position
170 	window_get_rect(main_wnd, &options3.calc.rect);
171 
172 	//write config
173 	rcfile_write();
174 
175 #ifdef __WIN32__
176   	msg_box1(_("Information"),
177 	  _("Configuration file saved (in tiemu.ini)."));
178 #else
179 	msg_box1(_("Information"),
180 	  _("Configuration file saved (in ~/.tiemu)."));
181 #endif
182 }
183 
184 
185 GLADE_CB void
on_load_config1_activate(GtkMenuItem * menuitem,gpointer user_data)186 on_load_config1_activate               (GtkMenuItem     *menuitem,
187                                         gpointer         user_data)
188 {
189 	rcfile_read();
190 
191   	msg_box1(_("Information"), _("Configuration file loaded."));
192 }
193 
194 
195 GLADE_CB void
on_load_state_image1_activate(GtkMenuItem * menuitem,gpointer user_data)196 on_load_state_image1_activate          (GtkMenuItem     *menuitem,
197                                         gpointer         user_data)
198 {
199 	engine_stop();
200 	display_load_state_dbox();
201 	engine_start();
202 }
203 
204 
205 GLADE_CB void
on_save_state_image1_activate(GtkMenuItem * menuitem,gpointer user_data)206 on_save_state_image1_activate          (GtkMenuItem     *menuitem,
207                                         gpointer         user_data)
208 {
209 	engine_stop();
210 	display_save_state_dbox();
211 	engine_start();
212 }
213 
214 
215 GLADE_CB void
on_revert_to_saved_state1_activate(GtkMenuItem * menuitem,gpointer user_data)216 on_revert_to_saved_state1_activate     (GtkMenuItem     *menuitem,
217                                         gpointer         user_data)
218 {
219 	engine_stop();
220 	ti68k_state_load(params.sav_file);
221   	engine_start();
222 }
223 
224 void
on_quick_save_state_image1_activate(GtkMenuItem * menuitem,gpointer user_data)225 on_quick_save_state_image1_activate    (GtkMenuItem     *menuitem,
226                                         gpointer         user_data)
227 {
228 	gchar *basename;
229 	gchar *dot;
230 
231 	// build name
232 	basename = g_path_get_basename(params.rom_file);
233 	dot = strrchr(basename, '.');
234 	if(dot != NULL)
235 		*dot = '\0';
236 
237 	// set path
238 	g_free(params.sav_file);
239 	params.sav_file = g_strconcat(inst_paths.img_dir, basename, ".sav", NULL);
240 	g_free(basename);
241 
242 	// save state
243 	ti68k_state_save(params.sav_file);
244 }
245 
246 /* menu part 3 (debug) */
247 
248 GLADE_CB void
on_enter_debugger1_activate(GtkMenuItem * menuitem,gpointer user_data)249 on_enter_debugger1_activate            (GtkMenuItem     *menuitem,
250                                         gpointer         user_data)
251 {
252 #ifndef __IPAQ__
253     if(dbg_on) return;
254 	if(!dbg_load) return;
255 
256 	engine_stop();
257     ti68k_debug_break();
258 	engine_start();
259 #endif
260 }
261 
262 GLADE_CB void
on_reset_calc1_activate(GtkMenuItem * menuitem,gpointer user_data)263 on_reset_calc1_activate                (GtkMenuItem     *menuitem,
264                                         gpointer         user_data)
265 {
266 	engine_stop();
267 	switch (msg_box3(_("Question"), _("Clear RAM?"), GTK_STOCK_YES, GTK_STOCK_NO, GTK_STOCK_CANCEL)) {
268 	  case BUTTON1:
269 	    memset(tihw.ram, 0, tihw.ram_size);
270 	  case BUTTON2:
271 	    ti68k_reset();
272 	    if (dbg_on)
273 	      gtk_debugger_close();
274 	    else {
275 	      default:
276 	        engine_start();
277 	    }
278 	}
279 }
280 
281 /* menu part 4 (images) */
282 
283 GLADE_CB void
on_upgrade_calc1_activate(GtkMenuItem * menuitem,gpointer user_data)284 on_upgrade_calc1_activate                (GtkMenuItem     *menuitem,
285                                         gpointer         user_data)
286 {
287 	engine_stop();
288   	display_set_tib_dbox();
289 	engine_start();
290 }
291 
292 
293 GLADE_CB void
on_set_rom1_activate(GtkMenuItem * menuitem,gpointer user_data)294 on_set_rom1_activate                   (GtkMenuItem     *menuitem,
295                                         gpointer         user_data)
296 {
297 	engine_stop();
298 	display_romversion_dbox (FALSE);
299 	engine_start();
300 }
301 
302 /* menu part 5.1 (emulator options) */
303 
304 GLADE_CB void
on_restrict_to_actual_speed1_activate(GtkMenuItem * menuitem,gpointer user_data)305 on_restrict_to_actual_speed1_activate  (GtkMenuItem     *menuitem,
306                                         gpointer         user_data)
307 {
308 	int engine_was_stopped = engine_is_stopped();
309 	engine_stop();
310     if(GTK_CHECK_MENU_ITEM(menuitem)->active != TRUE)
311     	params.restricted = 0;
312   	else
313     	params.restricted = 1;
314 	if (!engine_was_stopped) engine_start();
315 }
316 
317 GLADE_CB void
on_hw_protection1_activate(GtkMenuItem * menuitem,gpointer user_data)318 on_hw_protection1_activate             (GtkMenuItem     *menuitem,
319                                         gpointer         user_data)
320 {
321     if(GTK_CHECK_MENU_ITEM(menuitem)->active != TRUE)
322     	params.hw_protect = 0;
323   	else
324     	params.hw_protect = 1;
325 }
326 
327 GLADE_CB void
on_high_lcd_update1_activate(GtkMenuItem * menuitem,gpointer user_data)328 on_high_lcd_update1_activate           (GtkMenuItem     *menuitem,
329                                         gpointer         user_data)
330 {
331 	params.lcd_rate = 25;
332 	hid_lcd_rate_set();
333 }
334 
335 GLADE_CB void
on_med_lcd_update1_activate(GtkMenuItem * menuitem,gpointer user_data)336 on_med_lcd_update1_activate            (GtkMenuItem     *menuitem,
337                                         gpointer         user_data)
338 {
339 	params.lcd_rate = 55;
340 	hid_lcd_rate_set();
341 }
342 
343 GLADE_CB void
on_low_lcd_update1_activate(GtkMenuItem * menuitem,gpointer user_data)344 on_low_lcd_update1_activate            (GtkMenuItem     *menuitem,
345                                         gpointer         user_data)
346 {
347 	params.lcd_rate = 85;
348 	hid_lcd_rate_set();
349 }
350 
351 GLADE_CB void
on_normal_view1_activate(GtkMenuItem * menuitem,gpointer user_data)352 on_normal_view1_activate               (GtkMenuItem     *menuitem,
353                                         gpointer         user_data)
354 {
355 	if(GTK_CHECK_MENU_ITEM(menuitem)->active == TRUE)
356 		hid_switch_normal_view();
357 }
358 
359 
360 GLADE_CB void
on_large_view1_activate(GtkMenuItem * menuitem,gpointer user_data)361 on_large_view1_activate                (GtkMenuItem     *menuitem,
362                                         gpointer         user_data)
363 {
364 	if(GTK_CHECK_MENU_ITEM(menuitem)->active == TRUE)
365 		hid_switch_large_view();
366 }
367 
368 
369 GLADE_CB void
on_full_view1_activate(GtkMenuItem * menuitem,gpointer user_data)370 on_full_view1_activate                 (GtkMenuItem     *menuitem,
371                                         gpointer         user_data)
372 {
373 	if(GTK_CHECK_MENU_ITEM(menuitem)->active == TRUE)
374 		hid_switch_fullscreen();
375 }
376 
377 GLADE_CB void
on_custom_view1_activate(GtkMenuItem * menuitem,gpointer user_data)378 on_custom_view1_activate               (GtkMenuItem     *menuitem,
379                                         gpointer         user_data)
380 {
381 }
382 
383 /* menu part 5.2 (skin options) */
384 
385 GLADE_CB void
on_no_skin1_activate(GtkMenuItem * menuitem,gpointer user_data)386 on_no_skin1_activate                      (GtkMenuItem     *menuitem,
387                                         gpointer         user_data)
388 {
389 #ifndef __IPAQ__
390 	hid_switch_without_skin();
391 #endif
392 }
393 
394 
395 GLADE_CB void
on_default_skin1_activate(GtkMenuItem * menuitem,gpointer user_data)396 on_default_skin1_activate                      (GtkMenuItem     *menuitem,
397                                         gpointer         user_data)
398 {
399 #ifndef __IPAQ__
400 	hid_switch_with_skin();
401 #endif
402 }
403 
404 
405 GLADE_CB void
on_set_skin1_activate(GtkMenuItem * menuitem,gpointer user_data)406 on_set_skin1_activate                  (GtkMenuItem     *menuitem,
407                                         gpointer         user_data)
408 {
409 	display_skin_dbox();
410 }
411 
412 /* menu part 5.3 (screenshot options) */
413 
414 GLADE_CB void
on_now1_activate(GtkMenuItem * menuitem,gpointer user_data)415 on_now1_activate                     (GtkMenuItem     *menuitem,
416                                         gpointer         user_data)
417 {
418 	if(options2.shots > 1)
419 		hid_screenshot_burst();
420 	else
421 		hid_screenshot_single();
422 }
423 
424 
425 GLADE_CB void
on_screen_options1_activate(GtkMenuItem * menuitem,gpointer user_data)426 on_screen_options1_activate               (GtkMenuItem     *menuitem,
427                                         gpointer         user_data)
428 {
429 	display_scroptions_dbox();
430 }
431 
432 GLADE_CB void
on_copy_to_clipboard1_activate(GtkMenuItem * menuitem,gpointer user_data)433 on_copy_to_clipboard1_activate        (GtkMenuItem     *menuitem,
434                                        gpointer         user_data)
435 {
436 	options2.clipboard = GTK_CHECK_MENU_ITEM(menuitem)->active ? 1 : 0;
437 }
438 
439 /* menu part 5.4 (key press options) */
440 
441 GLADE_CB void
on_setup_recording1_activate(GtkMenuItem * menuitem,gpointer user_data)442 on_setup_recording1_activate             (GtkMenuItem     *menuitem,
443                                           gpointer         user_data)
444 {
445 	const gchar *filename = create_fsel(inst_paths.base_dir, "keypress.txt", "*.txt", TRUE);
446 	if (!filename)
447 		return;
448 
449 	g_free(options.kp_rec_file);
450 	options.kp_rec_file = g_strdup(filename);
451 }
452 
453 GLADE_CB void
on_start_recording1_activate(GtkMenuItem * menuitem,gpointer user_data)454 on_start_recording1_activate             (GtkMenuItem     *menuitem,
455                                           gpointer         user_data)
456 {
457 	if(options.kp_ply_enabled || !options.kp_rec_file) return;
458 
459 	options.kp_rec_enabled = !options.kp_rec_enabled;
460 
461 	if(options.kp_rec_enabled)
462 		kp_recording_start(options.kp_rec_file);
463 	else
464 		kp_recording_stop();
465 }
466 
467 GLADE_CB void
on_setup_playing1_activate(GtkMenuItem * menuitem,gpointer user_data)468 on_setup_playing1_activate             (GtkMenuItem     *menuitem,
469                                         gpointer         user_data)
470 {
471 	const gchar *filename = create_fsel(inst_paths.base_dir, NULL, "*.txt", FALSE);
472 	if (!filename)
473 		return;
474 
475 	g_free(options.kp_ply_file);
476 	options.kp_ply_file = g_strdup(filename);
477 }
478 
kp_callback(gpointer data)479 static gboolean kp_callback(gpointer data)
480 {
481 	int key, action, ret;
482 
483 	ret = kp_playing_key(&key, &action);
484 	if(ret)
485 	{
486 		kp_playing_stop();
487 		return FALSE;
488 	}
489 
490 	ti68k_kbd_set_key(key, action);
491 	//printf("%i %i\n", key, action);
492 
493 	return TRUE;
494 }
495 
496 GLADE_CB void
on_start_playing1_activate(GtkMenuItem * menuitem,gpointer user_data)497 on_start_playing1_activate             (GtkMenuItem     *menuitem,
498                                         gpointer         user_data)
499 {
500 	kp_playing_start(options.kp_ply_file);
501 	g_timeout_add(250, kp_callback, NULL);
502 }
503 
504 /* menu part 6 (misc) */
505 
506 static void go_to_bookmark(const char *link);
507 
508 GLADE_CB void
on_help1_activate(GtkMenuItem * menuitem,gpointer user_data)509 on_help1_activate                      (GtkMenuItem     *menuitem,
510                                         gpointer         user_data)
511 {
512 	gchar *path = g_strconcat(inst_paths.help_dir, _("Manual_en.html"), NULL);
513 
514 	go_to_bookmark(path);
515 	g_free(path);
516 }
517 
518 
519 GLADE_CB void
on_manpage1_activate(GtkMenuItem * menuitem,gpointer user_data)520 on_manpage1_activate                   (GtkMenuItem     *menuitem,
521                                         gpointer         user_data)
522 {
523 	display_manpage_dbox();
524 }
525 
526 GLADE_CB void
on_bookmarks1_activate(GtkMenuItem * menuitem,gpointer user_data)527 on_bookmarks1_activate				   (GtkMenuItem		*menuitem,
528 										gpointer		user_data)
529 {
530 #if GTK_CHECK_VERSION(2,12,0)
531 	GtkWidget *dialog;
532 	const gchar *message =
533     _("You're using GTK+ >= 2.12 so bookmark support is currently unavailable.");
534 
535 	dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
536 				  GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
537 				  message);
538 	gtk_dialog_run(GTK_DIALOG(dialog));
539 	gtk_widget_destroy(dialog);
540 #else
541 	GtkTooltipsData* data = gtk_tooltips_data_get(GTK_WIDGET(menuitem)); /* FIXME: deprecated in GTK+ 2.12 */
542 	go_to_bookmark(data->tip_text);
543 #endif
544 }
545 
546 
547 GLADE_CB void
on_bugreport1_activate(GtkMenuItem * menuitem,gpointer user_data)548 on_bugreport1_activate				   (GtkMenuItem     *menuitem,
549                                         gpointer         user_data)
550 {
551 	GtkWidget *dialog;
552 	const gchar *message =
553     _("There are several ways to get in touch if you encounter a problem with TiEmu or if you have questions, suggestions, bug reports, etc:\n- if you have general questions or problems, please consider the users' mailing list first (http://tiemu-users@list.sf.net).\n- if you want to discuss about TiEmu, you can use the TiEmu forum (http://sourceforge.net/forum/?group_id=23169).\n- for bug reports, use the 'Bug Tracking System' (http://sourceforge.net/tracker/?group_id=23169).\n\nBefore e-mailing the TiEmu team, make sure you have read the manual and/or the FAQ....");
554 
555 	dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
556 				  GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
557 				  message);
558 	gtk_dialog_run(GTK_DIALOG(dialog));
559 	gtk_widget_destroy(dialog);
560 }
561 
562 GLADE_CB void
on_changelog1_activate(GtkMenuItem * menuitem,gpointer user_data)563 on_changelog1_activate               (GtkMenuItem     *menuitem,
564                                         gpointer         user_data)
565 {
566 	display_release_dbox ();
567 }
568 
569 
570 GLADE_CB void
on_about1_activate(GtkMenuItem * menuitem,gpointer user_data)571 on_about1_activate                     (GtkMenuItem     *menuitem,
572                                         gpointer         user_data)
573 {
574 	display_about_dbox ();
575 }
576 
577 
578 GLADE_CB void
on_infos1_activate(GtkMenuItem * menuitem,gpointer user_data)579 on_infos1_activate                     (GtkMenuItem     *menuitem,
580                                         gpointer         user_data)
581 {
582 	display_infos_dbox();
583 }
584 
585 void exit_main_loop(void);
586 
587 GLADE_CB void
on_exit_and_save_state1_activate(GtkMenuItem * menuitem,gpointer user_data)588 on_exit_and_save_state1_activate       (GtkMenuItem     *menuitem,
589                                         gpointer         user_data)
590 {
591 	// stop emulation engine
592 	engine_stop();
593 
594 	// save state
595 	on_quick_save_state_image1_activate(NULL, NULL);
596 
597 	// and config
598 	window_get_rect(main_wnd, &options3.calc.rect);
599     rcfile_write();
600 
601 	// exit
602 	exit_main_loop();
603   	gtk_main_quit();
604 }
605 
606 
607 GLADE_CB void
on_exit_without_saving_state1_activate(GtkMenuItem * menuitem,gpointer user_data)608 on_exit_without_saving_state1_activate (GtkMenuItem     *menuitem,
609                                         gpointer         user_data)
610 {
611 #if 0
612 	{
613 		//testing...
614 		GdkEvent* event = gdk_event_new(GDK_KEY_PRESS);
615 
616 		event->key.type = GDK_KEY_PRESS;
617 		event->key.window = main_wnd->window;
618 		event->key.send_event = FALSE;
619 		event->key.time = GDK_CURRENT_TIME;
620 		event->key.state = GDK_LOCK_MASK;
621 		event->key.keyval = -1;
622 		event->key.length = 0;
623 		event->key.string = "";
624 		event->key.hardware_keycode = 0x14;
625 		event->key.group = 0;
626 
627 		gdk_event_put(event);
628 		while(gtk_events_pending()) gtk_main_iteration_do(FALSE);
629 		//gdk_event_free(event);
630 	}
631 #endif
632 
633 	exit_main_loop();
634 	gtk_main_quit();
635 }
636 
637 typedef void (*VCB) (void);
638 extern int reset_disabled;
639 
640 /*
641   Display the GTK popup menu and configure some items
642 */
display_popup_menu(void)643 GtkWidget* display_popup_menu(void)
644 {
645 	GladeXML *xml;
646 	GtkWidget *menu;
647 	GtkWidget *data;
648 	gchar *s;
649 
650 	//menu = create_popup_menu();
651 	xml = glade_xml_new
652 	    (tilp_paths_build_glade("popup-2.glade"), "popup_menu",
653 	     PACKAGE);
654 	if (!xml)
655 		g_error(_("%s: GUI loading failed!\n"), __FILE__);
656 	glade_xml_signal_autoconnect(xml);
657 
658 	menu = glade_xml_get_widget(xml, "popup_menu");
659 
660 	// set version
661 	data = glade_xml_get_widget(xml, "popup_menu_header");
662 	s = g_strdup_printf("TiEmu, version %s", TIEMU_VERSION);
663 	gtk_label_set_text(GTK_LABEL(GTK_BIN(data)->child), s);
664 	g_free(s);
665 
666 	// init check buttons
667 	data = glade_xml_get_widget(xml, "recv_file_from_tiemu1");
668 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), params.recv_file);
669 	data = glade_xml_get_widget(xml, "emulate_sound1");
670 #ifdef NO_SOUND
671 	gtk_widget_set_sensitive(data, FALSE);
672 #else
673 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), audio_isactive);
674 #endif
675 
676 	data = glade_xml_get_widget(xml, "restrict1");
677 	g_signal_handlers_block_by_func(GTK_OBJECT(data), (VCB)on_restrict_to_actual_speed1_activate, NULL);
678 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), params.restricted);
679 	g_signal_handlers_unblock_by_func(GTK_OBJECT(data), (VCB)on_restrict_to_actual_speed1_activate, NULL);
680 
681 	data = glade_xml_get_widget(xml, "hw_protection1");
682 	g_signal_handlers_block_by_func(GTK_OBJECT(data), (VCB)on_hw_protection1_activate, NULL);
683 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), params.hw_protect);
684 	g_signal_handlers_unblock_by_func(GTK_OBJECT(data), (VCB)on_hw_protection1_activate, NULL);
685 
686 	// hide the custom view radio button
687 	data = glade_xml_get_widget(xml, "custom_view1");
688 	gtk_widget_hide(data);
689 	data = glade_xml_get_widget(xml, "full_view1");
690 	gtk_widget_set_sensitive(data, FALSE);
691 
692 #ifdef NO_GDB
693 	data = glade_xml_get_widget(xml, "debug_file_with_tiemu1");
694 	gtk_widget_set_sensitive(data, FALSE);
695 #endif
696 
697 	// init radio buttons
698     switch(options.view)
699     {
700     case VIEW_NORMAL:
701         data = glade_xml_get_widget(xml, "normal_view1");
702         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), TRUE);
703         break;
704     case VIEW_LARGE:
705         data = glade_xml_get_widget(xml, "large_view1");
706         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), TRUE);
707         break;
708 	case VIEW_FULL:
709 		data = glade_xml_get_widget(xml, "full_view1");
710         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), TRUE);
711 		break;
712 	case VIEW_CUSTOM:
713 		data = glade_xml_get_widget(xml, "custom_view1");
714         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), TRUE);
715 		break;
716     default:
717         break;
718     }
719 
720 	if(params.lcd_rate >= 10 && params.lcd_rate < 40)
721 	{
722 		data = glade_xml_get_widget(xml, "high_lcd_update1");
723         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), TRUE);
724 	}
725 	else if((params.lcd_rate >= 40 && params.lcd_rate < 70) || params.lcd_rate == -1)
726 	{
727 		data = glade_xml_get_widget(xml, "med_lcd_update1");
728         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), TRUE);
729 	}
730 	else if(params.lcd_rate >= 70 && params.lcd_rate < 100)
731 	{
732 		data = glade_xml_get_widget(xml, "low_lcd_update1");
733         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), TRUE);
734 	}
735 
736 	// if debugger is open, blocks some items
737 	if(dbg_on || !dbg_load)
738 	{
739 #ifndef NO_GDB
740 		data = glade_xml_get_widget(xml, "send_file_to_tiemu1");
741 		gtk_widget_set_sensitive(data, FALSE);
742 
743 		data = glade_xml_get_widget(xml, "debug_file_with_tiemu1");
744 		gtk_widget_set_sensitive(data, FALSE);
745 #endif
746 
747 		data = glade_xml_get_widget(xml, "recv_file_from_tiemu1");
748 		gtk_widget_set_sensitive(data, FALSE);
749 
750 		data = glade_xml_get_widget(xml, "link_cable1");
751 		gtk_widget_set_sensitive(data, FALSE);
752 
753 		data = glade_xml_get_widget(xml, "upgrade_calc1");
754 		gtk_widget_set_sensitive(data, FALSE);
755 
756 		data = glade_xml_get_widget(xml, "set_rom1");
757 		gtk_widget_set_sensitive(data, FALSE);
758 
759 		if (reset_disabled)
760 		{
761 			data = glade_xml_get_widget(xml, "reset_calc1");
762 			gtk_widget_set_sensitive(data, FALSE);
763 		}
764 
765 		data = glade_xml_get_widget(xml, "calculator_state1");
766 		gtk_widget_set_sensitive(data, FALSE);
767 	}
768 
769 	data = glade_xml_get_widget(xml, "start_recording1");
770 	g_signal_handlers_block_by_func(GTK_OBJECT(data), (VCB)on_start_recording1_activate, NULL);
771 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), options.kp_rec_enabled);
772 	g_signal_handlers_unblock_by_func(GTK_OBJECT(data), (VCB)on_start_recording1_activate, NULL);
773 
774 	data = glade_xml_get_widget(xml, "start_playing1");
775 	g_signal_handlers_block_by_func(GTK_OBJECT(data), (VCB)on_start_playing1_activate, NULL);
776 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), options.kp_ply_enabled);
777 	g_signal_handlers_unblock_by_func(GTK_OBJECT(data), (VCB)on_start_playing1_activate, NULL);
778 
779 	data = glade_xml_get_widget(xml, "copy_to_clipboard1");
780 	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data), options2.clipboard);
781 
782 	return menu;
783 }
784 
785 
786 /* */
787 
go_to_bookmark(const char * link)788 static void go_to_bookmark(const char *link)
789 {
790 #ifdef __WIN32__
791 	HINSTANCE hInst;
792 
793 	// Windows do the whole work for us, let's go...
794 	hInst = ShellExecute(NULL, "open", link, NULL, NULL, SW_SHOWNORMAL);
795 	if((int)hInst <= 32)
796 	{
797 		msg_box1(_("Error"), _("Unable to run ShellExecute extension."));
798 	}
799 #else
800 	// Kevin's list:
801 	// These ones should be first, as they will honor the user's choice rather
802 	// than guessing an arbitrary one:
803 	// * /usr/bin/xdg-open (runs the default browser of the desktop environment
804 	// currently in use, this is the best solution)
805 	// * /usr/bin/gnome-open (GNOME 2.6+ default browser, user-configurable)
806 	// Distro-specific browser wrapper scripts:
807 	// * /usr/bin/sensible-browser (Debian's browser script)
808 	// * /usr/bin/htmlview (old RHL/Fedora default browser script, current
809 	// versions will honor the GNOME browser preference)
810 	// Fallback to a hardcoded list of browsers:
811 	// * /usr/bin/firefox (Mozilla Firefox)
812 	// * /usr/bin/seamonkey (Seamonkey)
813 	// * /usr/bin/konqueror (Konqueror)
814 	// * /usr/bin/mozilla (old Mozilla Suite)
815 	//
816 	gboolean result;
817 	char *apps[] = {
818 			"/usr/bin/xdg-open",
819 			"/usr/bin/gnome-open",
820 			"/usr/bin/sensible-browser",
821 			"/usr/bin/htmlview",
822 			"/usr/bin/firefox",
823 			"/usr/bin/seamonkey",
824 			"/usr/bin/konqueror",
825 			"/usr/bin/mozilla",
826 	};
827 	gint i, n;
828 
829 	n = sizeof(apps) / sizeof(char *);
830 	for(i = 0; i < n; i++)
831 	{
832 		gchar **argv = g_malloc0(3 * sizeof(gchar *));
833 
834 		argv[0] = g_strdup(apps[i]);
835 		argv[1] = g_strdup(link);
836 		argv[2] = NULL;
837 
838 		result = g_spawn_async(NULL, argv, NULL, 0, NULL, NULL, NULL, NULL);
839 		g_strfreev(argv);
840 
841 		if(result != FALSE)
842 			break;
843 	}
844 
845 	if (i == n)
846 	{
847 		msg_box1(_("Error"), _("Spawn error: do you have Firefox installed?"));
848 	}
849 #endif
850 	else
851 	{
852 		GtkWidget *dialog;
853 		GTimer *timer;
854 		const gchar *message = "A web browser has been launched: this may take a while before it appears. If it is already launched, the page will be opened in the existing frame.";
855 
856 		dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
857 					   GTK_MESSAGE_INFO,
858 					   GTK_BUTTONS_CLOSE, message);
859 		g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
860 					 G_CALLBACK(gtk_widget_destroy),
861 					 GTK_OBJECT(dialog));
862 		gtk_widget_show_all(GTK_WIDGET(dialog));
863 
864 		while(gtk_events_pending()) gtk_main_iteration();
865 		for(timer = g_timer_new(); g_timer_elapsed(timer, NULL) < 3.0;);
866 
867 		g_timer_destroy(timer);
868 		gtk_widget_destroy(GTK_WIDGET(dialog));
869 	}
870 }
871