X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=libchimara%2Ffileref.c;h=937933cedd914badf737bfba208d9d4d94151331;hb=4b0bbd6bb235b4cad89d321cdd7f570610a97712;hp=2b5cf53efd65d9f8c04bc32732699e16c6db33a4;hpb=0b85f1dd5993e2ed111ec2ba13bbbb4ebda06ada;p=rodin%2Fchimara.git
diff --git a/libchimara/fileref.c b/libchimara/fileref.c
index 2b5cf53..937933c 100644
--- a/libchimara/fileref.c
+++ b/libchimara/fileref.c
@@ -6,8 +6,54 @@
#include "fileref.h"
#include "magic.h"
#include "chimara-glk-private.h"
+#include "gi_dispa.h"
-extern ChimaraGlkPrivate *glk_data;
+extern GPrivate *glk_data_key;
+
+/* Internal function: create a fileref using the given parameters. */
+frefid_t
+fileref_new(gchar *filename, glui32 rock, glui32 usage, glui32 orig_filemode)
+{
+ g_return_val_if_fail(filename != NULL, NULL);
+
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
+ frefid_t f = g_new0(struct glk_fileref_struct, 1);
+ f->magic = MAGIC_FILEREF;
+ f->rock = rock;
+ if(glk_data->register_obj)
+ f->disprock = (*glk_data->register_obj)(f, gidisp_Class_Fileref);
+
+ f->filename = g_strdup(filename);
+ f->usage = usage;
+ f->orig_filemode = orig_filemode;
+
+ /* Add it to the global fileref list */
+ glk_data->fileref_list = g_list_prepend(glk_data->fileref_list, f);
+ f->fileref_list = glk_data->fileref_list;
+
+ return f;
+}
+
+static void
+fileref_close_common(frefid_t fref)
+{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
+ glk_data->fileref_list = g_list_delete_link(glk_data->fileref_list, fref->fileref_list);
+
+ if(glk_data->unregister_obj)
+ {
+ (*glk_data->unregister_obj)(fref, gidisp_Class_Fileref, fref->disprock);
+ fref->disprock.ptr = NULL;
+ }
+
+ if(fref->filename)
+ g_free(fref->filename);
+
+ fref->magic = MAGIC_FREE;
+ g_free(fref);
+}
/**
* glk_fileref_iterate:
@@ -24,7 +70,8 @@ frefid_t
glk_fileref_iterate(frefid_t fref, glui32 *rockptr)
{
VALID_FILEREF_OR_NULL(fref, return NULL);
-
+
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
GList *retnode;
if(fref == NULL)
@@ -56,26 +103,6 @@ glk_fileref_get_rock(frefid_t fref)
return fref->rock;
}
-/* Internal function: create a fileref using the given parameters. */
-static frefid_t
-fileref_new(gchar *filename, glui32 rock, glui32 usage, glui32 orig_filemode)
-{
- g_return_val_if_fail(filename != NULL, NULL);
-
- frefid_t f = g_new0(struct glk_fileref_struct, 1);
- f->magic = MAGIC_FILEREF;
- f->rock = rock;
- f->filename = g_strdup(filename);
- f->usage = usage;
- f->orig_filemode = orig_filemode;
-
- /* Add it to the global fileref list */
- glk_data->fileref_list = g_list_prepend(glk_data->fileref_list, f);
- f->fileref_list = glk_data->fileref_list;
-
- return f;
-}
-
/**
* glk_fileref_create_temp:
* @usage: Bitfield with one or more of the fileusage_ constants.
@@ -137,30 +164,31 @@ glk_fileref_create_temp(glui32 usage, glui32 rock)
* Chimara
*
* Chimara uses a GtkFileChooserDialog.
+ * linkend="gtk-GtkFileChooserDialog">GtkFileChooserDialog. The default
+ * starting location for the dialog may be set with glkunix_set_base_file().
*
*
* @fmode must be one of these values:
*
*
- * #filemode_Read
+ * %filemode_Read
* The file must already exist; and the player will be asked
* to select from existing files which match the usage.
*
*
- * #filemode_Write
+ * %filemode_Write
* The file should not exist; if the player selects an
* existing file, he will be warned that it will be replaced.
*
*
*
- * #filemode_ReadWrite
+ * %filemode_ReadWrite
* The file may or may not exist; if it already exists, the
* player will be warned that it will be modified.
*
*
- * #filemode_WriteAppend
- * Same behavior as #filemode_ReadWrite.
+ * %filemode_WriteAppend
+ * Same behavior as %filemode_ReadWrite.
*
*
*
@@ -184,6 +212,8 @@ glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock)
for each usage */
GtkWidget *chooser;
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
gdk_threads_enter();
switch(fmode)
@@ -194,8 +224,7 @@ glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock)
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
- gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser),
- GTK_FILE_CHOOSER_ACTION_OPEN);
+ gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser), GTK_FILE_CHOOSER_ACTION_OPEN);
break;
case filemode_Write:
chooser = gtk_file_chooser_dialog_new("Select a file to save to", NULL,
@@ -203,10 +232,8 @@ glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock)
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
- gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser),
- GTK_FILE_CHOOSER_ACTION_SAVE);
- gtk_file_chooser_set_do_overwrite_confirmation(
- GTK_FILE_CHOOSER(chooser), TRUE);
+ gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser), GTK_FILE_CHOOSER_ACTION_SAVE);
+ gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser), TRUE);
break;
case filemode_ReadWrite:
case filemode_WriteAppend:
@@ -215,8 +242,7 @@ glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock)
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
- gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser),
- GTK_FILE_CHOOSER_ACTION_SAVE);
+ gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser), GTK_FILE_CHOOSER_ACTION_SAVE);
break;
default:
ILLEGAL_PARAM("Unknown file mode: %u", fmode);
@@ -224,14 +250,16 @@ glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock)
return NULL;
}
+ if(glk_data->current_dir)
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), glk_data->current_dir);
+
if(gtk_dialog_run( GTK_DIALOG(chooser) ) != GTK_RESPONSE_ACCEPT)
{
gtk_widget_destroy(chooser);
gdk_threads_leave();
return NULL;
}
- gchar *filename =
- gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(chooser) );
+ gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(chooser) );
frefid_t f = fileref_new(filename, rock, usage, fmode);
g_free(filename);
gtk_widget_destroy(chooser);
@@ -254,7 +282,8 @@ glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock)
*
* Chimara
*
- * In Chimara, the file is created in the current working directory.
+ * In Chimara, the file is created in the directory last set by
+ * glkunix_set_base_file(), and otherwise in the current working directory.
*
*
* Since filenames are highly platform-specific, you should use
@@ -284,6 +313,12 @@ glk_fileref_create_by_name(glui32 usage, char *name, glui32 rock)
{
g_return_val_if_fail(name != NULL && strlen(name) > 0, NULL);
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
+ /* Do any string-munging here to remove illegal Latin-1 characters from
+ filename. On ext3, the only illegal characters are '/' and '\0'. */
+ g_strdelimit(name, "/", '_');
+
/* Find out what encoding filenames are in */
const gchar **charsets; /* Do not free */
g_get_filename_charsets(&charsets);
@@ -297,14 +332,16 @@ glk_fileref_create_by_name(glui32 usage, char *name, glui32 rock)
WARNING_S("Error during latin1->filename conversion", error->message);
return NULL;
}
-
- /* Do any string-munging here to remove illegal characters from filename.
- On ext3, the only illegal characters are '/' and '\0'. TODO: Should this
- function be allowed to reference files in other directories, or should we
- disallow '/'? */
-
- frefid_t f = fileref_new(osname, rock, usage, filemode_ReadWrite);
+
+ gchar *path;
+ if(glk_data->current_dir)
+ path = g_build_filename(glk_data->current_dir, osname, NULL);
+ else
+ path = g_strdup(osname);
g_free(osname);
+
+ frefid_t f = fileref_new(path, rock, usage, filemode_ReadWrite);
+ g_free(path);
return f;
}
@@ -318,7 +355,7 @@ glk_fileref_create_by_name(glui32 usage, char *name, glui32 rock)
* original fileref is not modified.)
*
* The use of this function can be tricky. If you change the type of the fileref
- * (#fileusage_Data, #fileusage_SavedGame, etc), the new reference may or may
+ * (%fileusage_Data, %fileusage_SavedGame, etc), the new reference may or may
* not point to the same actual disk file.
*
*
@@ -330,8 +367,8 @@ glk_fileref_create_by_name(glui32 usage, char *name, glui32 rock)
* unpredictable. It is safest to change the type of a fileref only if it refers
* to a nonexistent file.
*
- * If you change the mode of a fileref (#fileusage_TextMode,
- * #fileusage_BinaryMode), but leave the rest of the type unchanged, the new
+ * If you change the mode of a fileref (%fileusage_TextMode,
+ * %fileusage_BinaryMode), but leave the rest of the type unchanged, the new
* fileref will definitely point to the same disk file as the old one.
*
* Obviously, if you write to a file in text mode and then read from it in
@@ -362,13 +399,7 @@ void
glk_fileref_destroy(frefid_t fref)
{
VALID_FILEREF(fref, return);
-
- glk_data->fileref_list = g_list_delete_link(glk_data->fileref_list, fref->fileref_list);
- if(fref->filename)
- g_free(fref->filename);
-
- fref->magic = MAGIC_FREE;
- g_free(fref);
+ fileref_close_common(fref);
}
/**