4 #include <glib/gstdio.h>
7 #include "chimara-glk-private.h"
9 extern ChimaraGlkPrivate *glk_data;
12 * glk_fileref_iterate:
13 * @fref: A file reference, or #NULL.
14 * @rockptr: Return location for the next window's rock, or #NULL.
16 * Iterates over the list of file references; if @fref is #NULL, it returns the
17 * first file reference, otherwise the next file reference after @fref. If
18 * there are no more, it returns #NULL. The file reference's rock is stored in
19 * @rockptr. If you don't want the rocks to be returned, you may set @rockptr
22 * The order in which file references are returned is arbitrary. The order may
23 * change every time you create or destroy a file reference, invalidating the
26 * Returns: the next file reference, or #NULL if there are no more.
29 glk_fileref_iterate(frefid_t fref, glui32 *rockptr)
34 retnode = glk_data->fileref_list;
36 retnode = fref->fileref_list->next;
37 frefid_t retval = retnode? (frefid_t)retnode->data : NULL;
39 /* Store the fileref's rock in rockptr */
41 *rockptr = glk_fileref_get_rock(retval);
47 * glk_fileref_get_rock:
48 * @fref: A file reference.
50 * Returns the file reference @fref's rock value.
52 * Returns: A rock value.
55 glk_fileref_get_rock(frefid_t fref)
57 g_return_val_if_fail(fref != NULL, 0);
61 /* Internal function: create a fileref using the given parameters. */
63 fileref_new(gchar *filename, glui32 rock, glui32 usage, glui32 orig_filemode)
65 g_return_val_if_fail(filename != NULL, NULL);
67 frefid_t f = g_new0(struct glk_fileref_struct, 1);
69 f->filename = g_strdup(filename);
71 f->orig_filemode = orig_filemode;
73 /* Add it to the global fileref list */
74 glk_data->fileref_list = g_list_prepend(glk_data->fileref_list, f);
75 f->fileref_list = glk_data->fileref_list;
81 * glk_fileref_create_temp:
82 * @usage: Bitfield with one or more of the #fileusage_ constants.
83 * @rock: The new fileref's rock value.
85 * Creates a reference to a temporary file. It is always a new file (one which
86 * does not yet exist). The file (once created) will be somewhere out of the
89 * A temporary file should never be used for long-term storage. It may be
90 * deleted automatically when the program exits, or at some later time, say
91 * when the machine is turned off or rebooted. You do not have to worry about
92 * deleting it yourself.
94 * Returns: A new fileref, or #NULL if the fileref creation failed.
97 glk_fileref_create_temp(glui32 usage, glui32 rock)
100 GError *error = NULL;
101 gchar *filename = NULL;
102 gint handle = g_file_open_tmp("glkXXXXXX", &filename, &error);
105 error_dialog(NULL, error, "Error creating temporary file: ");
110 if(close(handle) == -1) /* There is no g_close()? */
112 error_dialog(NULL, NULL, "Error closing temporary file.");
118 frefid_t f = fileref_new(filename, rock, usage, filemode_Write);
124 * glk_fileref_create_by_prompt:
125 * @usage: Bitfield with one or more of the #fileusage_ constants.
126 * @fmode: File mode, contolling the dialog's behavior.
127 * @rock: The new fileref's rock value.
129 * Creates a reference to a file by opening a file chooser dialog. If @fmode is
130 * #filemode_Read, then the file must already exist and the user will be asked
131 * to select from existing files. If @fmode is #filemode_Write, then the file
132 * should not exist; if the user selects an existing file, he or she will be
133 * warned that it will be replaced. If @fmode is #filemode_ReadWrite, then the
134 * file may or may not exist; if it already exists, the user will be warned
135 * that it will be modified. The @fmode argument should generally match the
136 * @fmode which will be used to open the file.
138 * Returns: A new fileref, or #NULL if the fileref creation failed or the
139 * dialog was canceled.
142 glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock)
144 /* TODO: Remember current working directory and last used filename
153 chooser = gtk_file_chooser_dialog_new("Select a file to open", NULL,
154 GTK_FILE_CHOOSER_ACTION_OPEN,
155 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
156 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
158 gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser),
159 GTK_FILE_CHOOSER_ACTION_OPEN);
162 chooser = gtk_file_chooser_dialog_new("Select a file to save to", NULL,
163 GTK_FILE_CHOOSER_ACTION_SAVE,
164 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
165 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
167 gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser),
168 GTK_FILE_CHOOSER_ACTION_SAVE);
169 gtk_file_chooser_set_do_overwrite_confirmation(
170 GTK_FILE_CHOOSER(chooser), TRUE);
172 case filemode_ReadWrite:
173 case filemode_WriteAppend:
174 chooser = gtk_file_chooser_dialog_new("Select a file to save to", NULL,
175 GTK_FILE_CHOOSER_ACTION_SAVE,
176 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
177 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
179 gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser),
180 GTK_FILE_CHOOSER_ACTION_SAVE);
183 g_warning("glk_fileref_create_by_prompt: Unsupported mode");
188 if(gtk_dialog_run( GTK_DIALOG(chooser) ) != GTK_RESPONSE_ACCEPT)
190 gtk_widget_destroy(chooser);
195 gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(chooser) );
196 frefid_t f = fileref_new(filename, rock, usage, fmode);
198 gtk_widget_destroy(chooser);
205 * glk_fileref_create_by_name:
206 * @usage: Bitfield with one or more of the #fileusage_ constants.
208 * @rock: The new fileref's rock value.
210 * This creates a reference to a file with a specific name. The file will be
211 * in the same directory as your program, and visible to the player.
213 * Returns: A new fileref, or #NULL if the fileref creation failed.
216 glk_fileref_create_by_name(glui32 usage, char *name, glui32 rock)
218 g_return_val_if_fail(name != NULL && strlen(name) > 0, NULL);
220 /* Find out what encoding filenames are in */
221 const gchar **charsets; /* Do not free */
222 g_get_filename_charsets(&charsets);
224 /* Convert name to that encoding */
225 GError *error = NULL;
226 gchar *osname = g_convert(name, -1, charsets[0], "ISO-8859-1", NULL, NULL,
230 error_dialog(NULL, error, "Error during latin1->filename conversion: ");
234 /* Do any string-munging here to remove illegal characters from filename.
235 On ext3, the only illegal characters are '/' and '\0'. TODO: Should this
236 function be allowed to reference files in other directories, or should we
239 frefid_t f = fileref_new(osname, rock, usage, filemode_ReadWrite);
245 * glk_fileref_create_from_fileref:
246 * @usage: Bitfield with one or more of the #fileusage_ constants.
247 * @fref: Fileref to copy.
248 * @rock: The new fileref's rock value.
250 * This copies an existing file reference @fref, but changes the usage. (The
251 * original @fref is not modified.)
253 * If you write to a file in text mode and then read from it in binary mode,
254 * the results are platform-dependent.
256 * Returns: A new fileref, or #NULL if the fileref creation failed.
259 glk_fileref_create_from_fileref(glui32 usage, frefid_t fref, glui32 rock)
261 return fileref_new(fref->filename, rock, usage, fref->orig_filemode);
265 * glk_fileref_destroy:
266 * @fref: Fileref to destroy.
268 * Destroys a fileref which you have created. This does not affect the disk
271 * It is legal to destroy a fileref after opening a file with it (while the
272 * file is still open.) The fileref is only used for the opening operation,
273 * not for accessing the file stream.
276 glk_fileref_destroy(frefid_t fref)
278 glk_data->fileref_list = g_list_delete_link(glk_data->fileref_list, fref->fileref_list);
280 g_free(fref->filename);
285 * glk_fileref_delete_file:
286 * @fref: A refrence to the file to delete.
288 * Deletes the file referred to by @fref. Does not destroy @fref itself.
291 glk_fileref_delete_file(frefid_t fref)
293 if( glk_fileref_does_file_exist(fref) )
294 if(g_unlink(fref->filename) == -1)
295 error_dialog(NULL, NULL, "Error deleting file %s", fref->filename);
299 * glk_fileref_does_file_exist:
300 * @fref: A fileref to check.
302 * Checks whether the file referred to by @fref exists.
304 * Returns: #TRUE (1) if @fref refers to an existing file, #FALSE (0) if not.
307 glk_fileref_does_file_exist(frefid_t fref)
309 if( g_file_test(fref->filename, G_FILE_TEST_EXISTS) )