1 /*
2  * TilEm II
3  *
4  * Copyright (c) 2010-2011 Thibault Duponchelle
5  * Copyright (c) 2010-2011 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 #include "animation.h"
22 #include "emulator.h"
23 #include "skinops.h"
24 #include "emuwin.h"
25 #include "debugger.h"
26 
27 #include "gtk-compat.h"
28 
29 /* This struture is a wrapper for VarEntry with additionnal informations used by tilem */
30 typedef struct {
31 	int model;
32 
33 	VarEntry *ve;   	/* Original variable info retrieved
34 	                	   from calculator */
35 	int slot;       	/* Slot number */
36 
37 	/* Strings for display (UTF-8) */
38 	char *name_str; 	/* Variable name */
39 	char *type_str; 	/* Variable type */
40 	char *slot_str; 	/* Program slot */
41 	char *file_ext; 	/* Default file extension */
42 	char *filetype_desc; 	/* File format description */
43 
44 	int size;            	/* Variable size */
45 	gboolean archived;   	/* Is archived */
46 	gboolean can_group;  	/* Can be stored in group file */
47 
48 } TilemVarEntry;
49 
50 /* Screenshot view (widgets and flags) */
51 typedef struct _TilemScreenshotDialog {
52 	TilemCalcEmulator *emu;
53 
54 	GtkWidget* window;		/* The window itself */
55 
56 	/* Buttons */
57 	GtkWidget* screenshot;		/* Grab button */
58 	GtkWidget* record;		/* Record button */
59 	GtkWidget* stop;		/* Stop button */
60 
61 	/* Screenshot menu */
62 	GtkWidget* screenshot_preview_image; /* Review pixbuf */
63 	GtkWidget* ss_ext_combo; 	/* Combo box for file format */
64 	GtkWidget* ss_size_combo; 	/* Combo box for size */
65 	GtkWidget* width_spin;		/* The width of the gif */
66 	GtkWidget* height_spin;		/* The height of the gif */
67 	GtkWidget* grayscale_tb;	/* Toggle Button for enabling/disabling grayscale */
68 	GtkWidget* animation_speed;	/* A scale for the speed of the animation */
69 	GtkWidget* background_color;	/* Color chooser : Color used for pixel-off */
70 	GtkWidget* foreground_color;	/* Color chooser : Color used for pixel-on */
71 
72 	TilemAnimation *current_anim;
73 	gboolean current_anim_grayscale;
74 } TilemScreenshotDialog;
75 
76 /* This struture is used by receive menu */
77 typedef struct _TilemReceiveDialog {
78 	TilemCalcEmulator *emu;
79 
80 	GSList *vars;			/* The list of vars */
81 
82 	GtkWidget* window;		/* The window itself */
83 
84 	GtkWidget* treeview;		/* The treeview to print the list of vars */
85 	GtkTreeModel* model;		/* The model used by the treeview */
86 
87 	/* Radio buttons */
88 	GtkWidget* mode_box;
89 	GtkWidget* multiple_rb;		/* Write multiple files */
90 	GtkWidget* group_rb;		/* Write a single group file */
91 
92 	gboolean refresh_pending;
93 } TilemReceiveDialog;
94 
95 /* Handle the ilp progress stuff */
96 typedef struct _TilemLinkProgress {
97 	TilemCalcEmulator *emu;
98 
99 	GtkProgressBar* progress_bar; /* progress bar (total) */
100 	GtkLabel* title_lbl;
101 	GtkLabel* status_lbl;
102 	GtkWidget* window;
103 } TilemLinkProgress;
104 
105 #define LABEL_X_ALIGN 0.0
106 
107 
108 /* ###### event.c ##### */
109 
110 /* Dialog mesg */
111 void show_about();
112 
113 /* Launch the debugger */
114 void launch_debugger(TilemEmulatorWindow *ewin);
115 
116 /* Button-press event */
117 gboolean mouse_press_event(GtkWidget* w, GdkEventButton *event, gpointer data);
118 
119 /* Pointer-motion event */
120 gboolean pointer_motion_event(GtkWidget* w, GdkEventMotion *event, gpointer data);
121 
122 /* Button-release event */
123 gboolean mouse_release_event(GtkWidget* w, GdkEventButton *event, gpointer data);
124 
125 /* Key-press event */
126 gboolean key_press_event(GtkWidget* w, GdkEventKey *event, gpointer data);
127 
128 /* Key-release event */
129 gboolean key_release_event(GtkWidget* w, GdkEventKey *event, gpointer data);
130 
131 /* Pop up menu on main window */
132 gboolean popup_menu_event(GtkWidget* w, gpointer data);
133 
134 /* Handle drag and drop */
135 void drag_data_received(GtkWidget *win, GdkDragContext *dc, gint x, gint y,
136                         GtkSelectionData *seldata, guint info, guint t,
137                         gpointer data);
138 
139 
140 /* ###### emuwin.c ##### */
141 
142 /* Display the lcd image into the terminal */
143 void display_lcdimage_into_terminal(TilemEmulatorWindow *ewin);
144 
145 /* Redraw the screen with or without skin */
146 void redraw_screen(TilemEmulatorWindow *ewin);
147 
148 
149 /* ##### preferences.c ##### */
150 
151 /* Run preferences dialog. */
152 void tilem_preferences_dialog(TilemEmulatorWindow *ewin);
153 
154 
155 /* ##### address.c ##### */
156 
157 /* Convert address to a displayable string. */
158 char * tilem_format_addr(TilemDebugger *dbg, dword addr, gboolean physical);
159 
160 /* Parse physical address expressed as page and offset. */
161 gboolean tilem_parse_paged_addr(TilemDebugger *dbg, const char *pagestr,
162                                 const char *offsstr, dword *value);
163 
164 /* Parse an address or hex constant.  If PHYSICAL is null, only a
165    logical address (simple hex value or symbol) is allowed.  If
166    PHYSICAL is non-null, physical addresses in the form "PAGE:OFFSET"
167    are also allowed.  *PHYSICAL will be set to true if the user
168    entered a physical address. */
169 gboolean tilem_parse_addr(TilemDebugger *dbg, const char *string,
170                           dword *value, gboolean *physical);
171 
172 /* Open a dialog box prompting the user to enter an address.  PARENT
173    is the transient-for window; TITLE is the dialog's title; PROMPT is
174    a label for the input. */
175 gboolean tilem_prompt_address(TilemDebugger *dbg, GtkWindow *parent,
176                               const char *title, const char *prompt,
177                               dword *value, gboolean physical,
178                               gboolean usedefault);
179 
180 
181 /* ##### tool.c ##### */
182 
183 /* Get model name (abbreviation) for a TilEm model ID. */
184 const char * model_to_name(int model);
185 
186 /* Convert model name to a model ID. */
187 int name_to_model(const char *name);
188 
189 /* Convert TilEm model ID to tifiles2 model ID. */
190 CalcModel model_to_calcmodel(int model);
191 
192 /* Convert tifiles2 model ID to TilEm model ID. */
193 int calcmodel_to_model(CalcModel model);
194 
195 /* Get model ID for a given file. */
196 int file_to_model(const char *name);
197 
198 /* Get "base" model for file type support. */
199 int model_to_base_model(int calc_model);
200 
201 /* Check if calc is compatible with given file type. */
202 gboolean model_supports_file(int calc_model, int file_model);
203 
204 /* Create a frame around the given widget */
205 GtkWidget* new_frame(const gchar* label, GtkWidget* contents);
206 
207 /* The popup to choose what kind of rom you are trying to load  (at startup)*/
208 char choose_rom_popup(GtkWidget *parent_window, const char *filename, char default_model);
209 
210 /* Convert UTF-8 to filename encoding.  Use ASCII digits in place of
211    subscripts if necessary.  If conversion fails utterly, fall back to
212    the UTF-8 name, which is broken but better than nothing. */
213 char * utf8_to_filename(const char *utf8str);
214 
215 /* Convert UTF-8 to a subset of UTF-8 that is compatible with the
216    locale */
217 char * utf8_to_restricted_utf8(const char *utf8str);
218 
219 /* Generate default filename (UTF-8) for a variable */
220 char * get_default_filename(const TilemVarEntry *tve);
221 
222 
223 /* ##### config.c ##### */
224 
225 /* Retrieve settings from configuration file.  GROUP is the
226    configuration group; following arguments are a series of OPTION
227    strings, each followed by a pointer to a variable that will receive
228    the value.  The list of options is terminated by NULL.
229 
230    Each OPTION is a string of the form "KEY/TYPE" or "KEY/TYPE=VALUE",
231    where KEY is the name of the configuration property, and TYPE is
232    either 'f' for a filename (char*), 's' for a UTF-8 string (char*),
233    'i' for an integer (int), 'r' for a real number (double), or 'b'
234    for a boolean (int).
235 
236    VALUE, if specified, is the default value for the option if it has
237    not been defined by the user.  If no VALUE is specified, the option
238    defaults to zero or NULL.
239 
240    Strings returned by this function must be freed by the caller
241    (using g_free().) */
242 void tilem_config_get(const char *group, const char *option, ...)
243 	G_GNUC_NULL_TERMINATED;
244 
245 /* Save settings to the configuration file.  Arguments are a series of
246    option names, as above, each followed by the new value of the
247    option.  The list is terminated by NULL. */
248 void tilem_config_set(const char *group, const char *option, ...)
249 	G_GNUC_NULL_TERMINATED;
250 
251 
252 /* ##### link.c ##### */
253 
254 /* This structure is used to send a file (usually slot=-1, first=TRUE, last=TRUE)*/
255 struct TilemSendFileInfo {
256 	char *filename;
257 	char *display_name;
258 	int slot;
259 	int first;
260 	int last;
261 	char *error_message;
262 };
263 
264 /* This structure is used to receive a file */
265 struct TilemReceiveFileInfo {
266 	GSList *entries;
267 	char* destination;
268 	char *error_message;
269 	gboolean output_tig;
270 };
271 
272 /* Copy a TilemVarEntry structure */
273 TilemVarEntry *tilem_var_entry_copy(const TilemVarEntry *tve);
274 
275 /* Free a previous allocated TilemVarEntry */
276 void tilem_var_entry_free(TilemVarEntry *tve);
277 
278 /* Send a file to the calculator through the GUI.  SLOT is the
279    destination program slot (for TI-81.)  FIRST must be true if this
280    is the first variable in a series; LAST must be true if this is the
281    last in a series. */
282 void tilem_link_send_file(TilemCalcEmulator *emu, const char *filename,
283                           int slot, gboolean first, gboolean last);
284 
285 /* The effective send file function. If there's no good reason, use tilem_link_send_file instead. */
286 gboolean send_file_main(TilemCalcEmulator *emu, gpointer data);
287 
288 /* Request directory listing. */
289 void tilem_link_get_dirlist(TilemCalcEmulator *emu);
290 
291 /* Get the calc model as needed by ticalcs functions */
292 int get_calc_model(TilemCalc *calc);
293 
294 /* Show error */
295 void show_error(TilemCalcEmulator *emu, const char *title, const char *message);
296 
297 /* Receive a variable and write it to a file. */
298 void tilem_link_receive_file(TilemCalcEmulator *emu,
299                              const TilemVarEntry* varentry,
300                              const char* destination);
301 
302 /* Receive a list of variables (GSList of TilemVarEntries) and save
303    them to a group file. */
304 void tilem_link_receive_group(TilemCalcEmulator *emu,
305                               GSList *entries,
306                               const char *destination);
307 
308 /* Receive variables with names matching a pattern.  PATTERN is a
309    glob-like pattern in UTF-8.  Files will be written out to
310    DESTDIR. */
311 void tilem_link_receive_matching(TilemCalcEmulator *emu,
312                                  const char *pattern,
313                                  const char *destdir);
314 
315 
316 /* ##### pbar.c ##### */
317 
318 /* Create or update the progress bar */
319 void progress_bar_update(TilemCalcEmulator* emu);
320 
321 
322 
323 /* ##### animatedgif.c ##### */
324 
325 /* Save a TilemAnimation to a GIF file. */
326 void tilem_animation_write_gif(TilemAnimation *anim, byte* palette, int palette_size, FILE *fp);
327 
328 
329 /* ##### gifencod.c ##### */
330 
331 /* Encode gif data */
332 void GifEncode(FILE *fout, unsigned char *pixels, int depth, int siz);
333 
334 
335 /* ##### screenshot.c ##### */
336 
337 /* create the screenshot popup */
338 void popup_screenshot_window(TilemEmulatorWindow* ewin);
339 
340 /* Take a single screenshot */
341 void quick_screenshot(TilemEmulatorWindow *ewin);
342 
343 
344 /* ##### keybindings.c ##### */
345 
346 /* Load the keybindings */
347 void tilem_keybindings_init(TilemCalcEmulator* emu, const char* model);
348 
349 
350 /* ##### menu.c ##### */
351 
352 /* Build the menu (do not print it) */
353 void build_menu(TilemEmulatorWindow* ewin);
354 
355 
356 /* ##### sendfile.c ##### */
357 
358 /* Load a list of files through the GUI.  The list of filenames must
359    end with NULL. */
360 void load_files(TilemEmulatorWindow *ewin, char **filenames);
361 
362 /* Load a list of files from the command line.  Filenames may begin
363    with an optional slot designation. */
364 void load_files_cmdline(TilemEmulatorWindow *ewin, char **filenames);
365 
366 /* Prompt user to load a file from PC to TI */
367 void load_file_dialog(TilemEmulatorWindow *ewin);
368 
369 
370 /* ##### rcvmenu.c ##### */
371 
372 /* Createe the popup dialog */
373 void popup_receive_menu(TilemEmulatorWindow *ewin);
374 
375 /* Create a TilemReceiveDialog */
376 TilemReceiveDialog* tilem_receive_dialog_new(TilemCalcEmulator *emu);
377 
378 /* Destroy a TilemReceiveDialog */
379 void tilem_receive_dialog_free(TilemReceiveDialog *rcvdlg);
380 
381 /* Update TilemReceiveDialog with directory listing.  VARLIST is a
382    GSList of TilemVarEntries; the dialog assumes ownership of this
383    list.  Display the dialog if it's currently hidden. */
384 void tilem_receive_dialog_update(TilemReceiveDialog *rcvdlg,
385                                  GSList *varlist);
386 
387