1 /*
2  * TilEm II
3  *
4  * Copyright (c) 2010-2011 Thibault Duponchelle
5  * Copyright (c) 2011-2012 Benjamin Moody
6  *
7  * This program is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24 
25 #include <stdio.h>
26 #include <gtk/gtk.h>
27 #include <ticalcs.h>
28 #include <tilem.h>
29 
30 #include "gui.h"
31 #include "msgbox.h"
32 
action_send_file(G_GNUC_UNUSED GtkAction * act,gpointer data)33 static void action_send_file(G_GNUC_UNUSED GtkAction *act, gpointer data)
34 {
35 	TilemEmulatorWindow *ewin = data;
36 	load_file_dialog(ewin);
37 }
38 
action_receive_file(G_GNUC_UNUSED GtkAction * act,gpointer data)39 static void action_receive_file(G_GNUC_UNUSED GtkAction *act, gpointer data)
40 {
41 	TilemEmulatorWindow *ewin = data;
42 	//tilem_rcvmenu_new(ewin->emu);
43 	//get_var(ewin->emu);
44 	popup_receive_menu(ewin);
45 }
46 
action_start_debugger(G_GNUC_UNUSED GtkAction * act,gpointer data)47 static void action_start_debugger(G_GNUC_UNUSED GtkAction *act, gpointer data)
48 {
49 	TilemEmulatorWindow *ewin = data;
50 	launch_debugger(ewin);
51 }
52 
action_open_calc(G_GNUC_UNUSED GtkAction * act,gpointer data)53 static void action_open_calc(G_GNUC_UNUSED GtkAction *act, gpointer data)
54 {
55 	TilemEmulatorWindow *ewin = data;
56 	tilem_calc_emulator_prompt_open_rom(ewin->emu);
57 }
58 
action_save_calc(G_GNUC_UNUSED GtkAction * act,G_GNUC_UNUSED gpointer data)59 static void action_save_calc(G_GNUC_UNUSED GtkAction *act, G_GNUC_UNUSED gpointer data)
60 {
61 	TilemEmulatorWindow *ewin = data;
62 	GError *err = NULL;
63 
64 	if (!tilem_calc_emulator_save_state(ewin->emu, &err)) {
65 		messagebox01(GTK_WINDOW(ewin->window), GTK_MESSAGE_ERROR,
66 		             "Unable to save calculator state",
67 		             "%s", err->message);
68 		g_error_free(err);
69 	}
70 }
71 
action_revert_calc(G_GNUC_UNUSED GtkAction * act,G_GNUC_UNUSED gpointer data)72 static void action_revert_calc(G_GNUC_UNUSED GtkAction *act, G_GNUC_UNUSED gpointer data)
73 {
74 	TilemEmulatorWindow *ewin = data;
75 	GError *err = NULL;
76 
77 	if (!tilem_calc_emulator_revert_state(ewin->emu, &err)) {
78 		messagebox01(GTK_WINDOW(ewin->window), GTK_MESSAGE_ERROR,
79 		             "Unable to load calculator state",
80 		             "%s", err->message);
81 		g_error_free(err);
82 	}
83 }
84 
action_reset_calc(G_GNUC_UNUSED GtkAction * act,gpointer data)85 static void action_reset_calc(G_GNUC_UNUSED GtkAction *act, gpointer data)
86 {
87 	TilemEmulatorWindow *ewin = data;
88 	tilem_calc_emulator_reset(ewin->emu);
89 }
90 
action_begin_macro(G_GNUC_UNUSED GtkAction * act,gpointer data)91 static void action_begin_macro(G_GNUC_UNUSED GtkAction *act, gpointer data)
92 {
93 	TilemEmulatorWindow *ewin = data;
94 	tilem_macro_start(ewin->emu);
95 }
96 
action_end_macro(G_GNUC_UNUSED GtkAction * act,gpointer data)97 static void action_end_macro(G_GNUC_UNUSED GtkAction *act, gpointer data)
98 {
99 	TilemEmulatorWindow *ewin = data;
100 	tilem_macro_stop(ewin->emu);
101 	/* tilem_macro_print(ewin->emu->macro); */
102 }
103 
action_play_macro(G_GNUC_UNUSED GtkAction * act,gpointer data)104 static void action_play_macro(G_GNUC_UNUSED GtkAction *act, gpointer data)
105 {
106 	TilemEmulatorWindow *ewin = data;
107 	tilem_macro_play(ewin->emu);
108 }
109 
action_open_macro(G_GNUC_UNUSED GtkAction * act,G_GNUC_UNUSED gpointer data)110 static void action_open_macro(G_GNUC_UNUSED GtkAction *act, G_GNUC_UNUSED gpointer data)
111 {
112 	TilemEmulatorWindow *ewin = data;
113 	tilem_macro_load(ewin->emu, NULL);
114 }
115 
116 /* I will improve macro creation by saving it firstly into a macro object
117  * Save macro will only be done if user choose to save it */
action_save_macro(G_GNUC_UNUSED GtkAction * act,G_GNUC_UNUSED gpointer data)118 static void action_save_macro(G_GNUC_UNUSED GtkAction *act, G_GNUC_UNUSED gpointer data)
119 {
120 	TilemEmulatorWindow *ewin = data;
121 	tilem_macro_write_file(ewin->emu);
122 }
123 
action_screenshot(G_GNUC_UNUSED GtkAction * act,gpointer data)124 static void action_screenshot(G_GNUC_UNUSED GtkAction *act, gpointer data)
125 {
126 	TilemEmulatorWindow *ewin = data;
127 	popup_screenshot_window(ewin);
128 }
129 
action_quick_screenshot(G_GNUC_UNUSED GtkAction * act,gpointer data)130 static void action_quick_screenshot(G_GNUC_UNUSED GtkAction *act,
131                                     gpointer data)
132 {
133 	TilemEmulatorWindow *ewin = data;
134 	quick_screenshot(ewin);
135 }
136 
action_preferences(G_GNUC_UNUSED GtkAction * act,gpointer data)137 static void action_preferences(G_GNUC_UNUSED GtkAction *act,
138                                gpointer data)
139 {
140 	TilemEmulatorWindow *ewin = data;
141 	tilem_preferences_dialog(ewin);
142 }
143 
action_about(G_GNUC_UNUSED GtkAction * act,G_GNUC_UNUSED gpointer data)144 static void action_about(G_GNUC_UNUSED GtkAction *act,
145                                     G_GNUC_UNUSED gpointer data)
146 {
147 	show_about();
148 }
149 
action_quit(G_GNUC_UNUSED GtkAction * act,G_GNUC_UNUSED gpointer data)150 static void action_quit(G_GNUC_UNUSED GtkAction *act,
151                         G_GNUC_UNUSED gpointer data)
152 {
153 
154 	TilemEmulatorWindow *ewin = data;
155 	gtk_widget_destroy(ewin->window);
156 }
157 
158 static const GtkActionEntry main_action_ents[] =
159 	{{ "send-file",
160 	   GTK_STOCK_OPEN, "Send _File...", "<ctrl>O",
161 	   "Send a program or variable file to the calculator",
162 	   G_CALLBACK(action_send_file) },
163 
164 	 { "receive-file",
165 	   GTK_STOCK_SAVE_AS, "Re_ceive File...", "<ctrl>S",
166 	   "Receive a program or variable from the calculator",
167 	   G_CALLBACK(action_receive_file) },
168 
169 	 { "open-calc",
170 	   GTK_STOCK_OPEN, "_Open Calculator...", "<shift><ctrl>O",
171 	   "Open a calculator ROM file",
172 	   G_CALLBACK(action_open_calc) },
173 	 { "save-calc",
174 	   GTK_STOCK_SAVE, "_Save Calculator", "<shift><ctrl>S",
175 	   "Save current calculator state",
176 	   G_CALLBACK(action_save_calc) },
177 	 { "revert-calc",
178 	   GTK_STOCK_REVERT_TO_SAVED, "Re_vert Calculator State", 0,
179 	   "Revert to saved calculator state",
180 	   G_CALLBACK(action_revert_calc) },
181 	 { "reset-calc",
182 	   GTK_STOCK_CLEAR, "_Reset Calculator", "<shift><ctrl>Delete",
183 	   "Reset the calculator",
184 	   G_CALLBACK(action_reset_calc) },
185 
186 	 { "start-debugger",
187 	   0, "_Debugger", "Pause",
188 	   "Pause emulation and start the debugger",
189 	   G_CALLBACK(action_start_debugger) },
190 
191 	 { "begin-macro",
192 	   GTK_STOCK_MEDIA_RECORD, "_Record", 0,
193 	   "Begin recording a macro",
194 	   G_CALLBACK(action_begin_macro) },
195 	 { "end-macro",
196 	   GTK_STOCK_MEDIA_STOP, "S_top", 0,
197 	   "Begin recording a macro",
198 	   G_CALLBACK(action_end_macro) },
199 	 { "play-macro",
200 	   GTK_STOCK_MEDIA_PLAY, "_Play", 0,
201 	   "Play back the current macro",
202 	   G_CALLBACK(action_play_macro) },
203 	 { "open-macro",
204 	   GTK_STOCK_OPEN, "_Open Macro File...", "",
205 	   "Load a macro from a file",
206 	   G_CALLBACK(action_open_macro) },
207 	 { "save-macro",
208 	   GTK_STOCK_SAVE_AS, "_Save Macro File...", "",
209 	   "Save current macro to a file",
210 	   G_CALLBACK(action_save_macro) },
211 
212 	 { "screenshot",
213 	   0, "S_creenshot...", "<ctrl>Print",
214 	   "Save a screenshot",
215 	   G_CALLBACK(action_screenshot) },
216 	 { "quick-screenshot",
217 	   0, "_Quick Screenshot", "<shift><ctrl>Print",
218 	   "Save a screenshot using default settings",
219 	   G_CALLBACK(action_quick_screenshot) },
220 
221 	 { "preferences",
222 	   GTK_STOCK_PREFERENCES, 0, 0,
223 	   "Edit emulator settings",
224 	   G_CALLBACK(action_preferences) },
225 
226 	 { "about",
227 	   GTK_STOCK_ABOUT, "_About", "",
228 	   "Print some informations about TilEm 2 and its authors",
229 	   G_CALLBACK(action_about) },
230 
231 	 { "quit",
232 	   GTK_STOCK_QUIT, "_Quit", "<ctrl>Q",
233 	   "Quit the application",
234 	   G_CALLBACK(action_quit) }};
235 
add_item(GtkWidget * menu,GtkAccelGroup * accelgrp,GtkActionGroup * actions,const char * name)236 static GtkWidget *add_item(GtkWidget *menu, GtkAccelGroup *accelgrp,
237                            GtkActionGroup *actions, const char *name)
238 {
239 	GtkAction *action;
240 	GtkWidget *item;
241 
242 	action = gtk_action_group_get_action(actions, name);
243 	g_return_val_if_fail(action != NULL, NULL);
244 
245 	gtk_action_set_accel_group(action, accelgrp);
246 	item = gtk_action_create_menu_item(action);
247 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
248 	gtk_widget_show(item);
249 	return item;
250 }
251 
add_separator(GtkWidget * menu)252 static GtkWidget *add_separator(GtkWidget *menu)
253 {
254 	GtkWidget *item;
255 	item = gtk_separator_menu_item_new();
256 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
257 	gtk_widget_show(item);
258 	return item;
259 }
260 
add_submenu(GtkWidget * menu,const char * label)261 static GtkWidget *add_submenu(GtkWidget *menu, const char *label)
262 {
263 	GtkWidget *item, *submenu;
264 
265 	item = gtk_menu_item_new_with_mnemonic(label);
266 	submenu = gtk_menu_new();
267 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
268 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
269 	gtk_widget_show(item);
270 	return submenu;
271 }
272 
273 /* Build the menu */
build_menu(TilemEmulatorWindow * ewin)274 void build_menu(TilemEmulatorWindow* ewin)
275 {
276 	GtkActionGroup *acts;
277 	GtkAccelGroup *ag;
278 	GtkWidget *menu, *submenu;
279 
280 	ewin->actions = acts = gtk_action_group_new("Emulator");
281 	gtk_action_group_add_actions(ewin->actions, main_action_ents,
282 	                             G_N_ELEMENTS(main_action_ents), ewin);
283 
284 	ag = gtk_accel_group_new();
285 	gtk_window_add_accel_group(GTK_WINDOW(ewin->window), ag);
286 
287 	ewin->popup_menu = menu = gtk_menu_new();
288 
289 	add_item(menu, ag, acts, "send-file");
290 	add_item(menu, ag, acts, "receive-file");
291 	add_separator(menu);
292 
293 	add_item(menu, ag, acts, "open-calc");
294 	add_item(menu, ag, acts, "save-calc");
295 	add_item(menu, ag, acts, "revert-calc");
296 	add_item(menu, ag, acts, "reset-calc");
297 	add_separator(menu);
298 
299 	add_item(menu, ag, acts, "start-debugger");
300 
301 	submenu = add_submenu(menu, "_Macro");
302 	add_item(submenu, ag, acts, "begin-macro");
303 	add_item(submenu, ag, acts, "end-macro");
304 	add_item(submenu, ag, acts, "play-macro");
305 	add_separator(submenu);
306 	add_item(submenu, ag, acts, "open-macro");
307 	add_item(submenu, ag, acts, "save-macro");
308 
309 	add_item(menu, ag, acts, "screenshot");
310 	add_item(menu, ag, acts, "quick-screenshot");
311 	add_separator(menu);
312 
313 	add_item(menu, ag, acts, "preferences");
314 	add_separator(menu);
315 
316 	add_item(menu, ag, acts, "about");
317 	add_item(menu, ag, acts, "quit");
318 }
319