From 824548f1e481e25add5edfc9c798ee4e5501d083 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 19 Feb 2004 07:43:39 +0000 Subject: [PATCH] Remove old file-system property. Add new file-system-backend string 2004-02-19 Alexander Larsson * gtk/gtkfilechooser.c: (gtk_file_chooser_class_init): * gtk/gtkfilechooserutils.c: * gtk/gtkfilechooserutils.h: * gtk/gtkfilechooserwidget.c: Remove old file-system property. Add new file-system-backend string property * gtk/gtkfilechooserdefault.[ch]: Handle the file-system-backend property * gtk/gtkfilechooserdialog.[ch]: (gtk_file_chooser_dialog_new_with_backend): Remove old file-system property. Add new file-system-backend string property Add new function gtk_file_chooser_dialog_new_with_backend * gtk/gtkfilesystem.c: * gtk/gtkfilesystem.h: Add filesystem module support. --- ChangeLog | 22 +++++ ChangeLog.pre-2-10 | 22 +++++ ChangeLog.pre-2-4 | 22 +++++ ChangeLog.pre-2-6 | 22 +++++ ChangeLog.pre-2-8 | 22 +++++ gtk/gtkfilechooser.c | 8 +- gtk/gtkfilechooserdefault.c | 77 ++++++++++------ gtk/gtkfilechooserdefault.h | 2 +- gtk/gtkfilechooserdialog.c | 121 ++++++++++++++++++------- gtk/gtkfilechooserdialog.h | 18 ++-- gtk/gtkfilechooserutils.c | 4 +- gtk/gtkfilechooserutils.h | 2 +- gtk/gtkfilechooserwidget.c | 43 ++++----- gtk/gtkfilesystem.c | 170 +++++++++++++++++++++++++++++++++++- gtk/gtkfilesystem.h | 4 + 15 files changed, 455 insertions(+), 104 deletions(-) diff --git a/ChangeLog b/ChangeLog index eaef75c0f..53e1f1123 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2004-02-19 Alexander Larsson + + * gtk/gtkfilechooser.c: (gtk_file_chooser_class_init): + * gtk/gtkfilechooserutils.c: + * gtk/gtkfilechooserutils.h: + * gtk/gtkfilechooserwidget.c: + Remove old file-system property. + Add new file-system-backend string property + + * gtk/gtkfilechooserdefault.[ch]: + Handle the file-system-backend property + + * gtk/gtkfilechooserdialog.[ch]: + (gtk_file_chooser_dialog_new_with_backend): + Remove old file-system property. + Add new file-system-backend string property + Add new function gtk_file_chooser_dialog_new_with_backend + + * gtk/gtkfilesystem.c: + * gtk/gtkfilesystem.h: + Add filesystem module support. + 2004-02-18 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_tree_create): Renamed diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index eaef75c0f..53e1f1123 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,25 @@ +2004-02-19 Alexander Larsson + + * gtk/gtkfilechooser.c: (gtk_file_chooser_class_init): + * gtk/gtkfilechooserutils.c: + * gtk/gtkfilechooserutils.h: + * gtk/gtkfilechooserwidget.c: + Remove old file-system property. + Add new file-system-backend string property + + * gtk/gtkfilechooserdefault.[ch]: + Handle the file-system-backend property + + * gtk/gtkfilechooserdialog.[ch]: + (gtk_file_chooser_dialog_new_with_backend): + Remove old file-system property. + Add new file-system-backend string property + Add new function gtk_file_chooser_dialog_new_with_backend + + * gtk/gtkfilesystem.c: + * gtk/gtkfilesystem.h: + Add filesystem module support. + 2004-02-18 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_tree_create): Renamed diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index eaef75c0f..53e1f1123 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,25 @@ +2004-02-19 Alexander Larsson + + * gtk/gtkfilechooser.c: (gtk_file_chooser_class_init): + * gtk/gtkfilechooserutils.c: + * gtk/gtkfilechooserutils.h: + * gtk/gtkfilechooserwidget.c: + Remove old file-system property. + Add new file-system-backend string property + + * gtk/gtkfilechooserdefault.[ch]: + Handle the file-system-backend property + + * gtk/gtkfilechooserdialog.[ch]: + (gtk_file_chooser_dialog_new_with_backend): + Remove old file-system property. + Add new file-system-backend string property + Add new function gtk_file_chooser_dialog_new_with_backend + + * gtk/gtkfilesystem.c: + * gtk/gtkfilesystem.h: + Add filesystem module support. + 2004-02-18 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_tree_create): Renamed diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index eaef75c0f..53e1f1123 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,25 @@ +2004-02-19 Alexander Larsson + + * gtk/gtkfilechooser.c: (gtk_file_chooser_class_init): + * gtk/gtkfilechooserutils.c: + * gtk/gtkfilechooserutils.h: + * gtk/gtkfilechooserwidget.c: + Remove old file-system property. + Add new file-system-backend string property + + * gtk/gtkfilechooserdefault.[ch]: + Handle the file-system-backend property + + * gtk/gtkfilechooserdialog.[ch]: + (gtk_file_chooser_dialog_new_with_backend): + Remove old file-system property. + Add new file-system-backend string property + Add new function gtk_file_chooser_dialog_new_with_backend + + * gtk/gtkfilesystem.c: + * gtk/gtkfilesystem.h: + Add filesystem module support. + 2004-02-18 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_tree_create): Renamed diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index eaef75c0f..53e1f1123 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,25 @@ +2004-02-19 Alexander Larsson + + * gtk/gtkfilechooser.c: (gtk_file_chooser_class_init): + * gtk/gtkfilechooserutils.c: + * gtk/gtkfilechooserutils.h: + * gtk/gtkfilechooserwidget.c: + Remove old file-system property. + Add new file-system-backend string property + + * gtk/gtkfilechooserdefault.[ch]: + Handle the file-system-backend property + + * gtk/gtkfilechooserdialog.[ch]: + (gtk_file_chooser_dialog_new_with_backend): + Remove old file-system property. + Add new file-system-backend string property + Add new function gtk_file_chooser_dialog_new_with_backend + + * gtk/gtkfilesystem.c: + * gtk/gtkfilesystem.h: + Add filesystem module support. + 2004-02-18 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_tree_create): Renamed diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c index 516f24a3f..08c0811df 100644 --- a/gtk/gtkfilechooser.c +++ b/gtk/gtkfilechooser.c @@ -95,10 +95,10 @@ gtk_file_chooser_class_init (gpointer g_iface) GTK_FILE_CHOOSER_ACTION_OPEN, G_PARAM_READWRITE)); g_object_interface_install_property (g_iface, - g_param_spec_object ("file-system", - P_("File System"), - P_("File system object to use"), - GTK_TYPE_FILE_SYSTEM, + g_param_spec_string ("file-system-backend", + P_("File System Backend"), + P_("Name of file system backend to use"), + NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_interface_install_property (g_iface, g_param_spec_object ("filter", diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index a546c4150..50ac4eb97 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -51,6 +51,12 @@ #include "gtktypebuiltins.h" #include "gtkvbox.h" +#if defined (G_OS_UNIX) +#include "gtkfilesystemunix.h" +#elif defined (G_OS_WIN32) +#include "gtkfilesystemwin32.h" +#endif + #include #include @@ -1734,6 +1740,45 @@ set_select_multiple (GtkFileChooserDefault *impl, check_preview_change (impl); } +static void +set_file_system_backend (GtkFileChooserDefault *impl, + const char *backend) +{ + if (impl->file_system) + { + g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); + impl->volumes_changed_id = 0; + g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id); + impl->bookmarks_changed_id = 0; + g_object_unref (impl->file_system); + } + + impl->file_system = NULL; + if (backend) + impl->file_system = _gtk_file_system_create (backend); + + if (!impl->file_system) + { +#if defined (G_OS_UNIX) + impl->file_system = gtk_file_system_unix_new (); +#elif defined (G_OS_WIN32) + impl->file_system = gtk_file_system_win32_new (); +#else +#error "No default filesystem implementation on the platform" +#endif + } + + if (impl->file_system) + { + impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed", + G_CALLBACK (volumes_changed_cb), + impl); + impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed", + G_CALLBACK (bookmarks_changed_cb), + impl); + } +} + static void gtk_file_chooser_default_set_property (GObject *object, guint prop_id, @@ -1762,32 +1807,8 @@ gtk_file_chooser_default_set_property (GObject *object, gtk_widget_hide (impl->new_folder_button); break; - case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM: - { - GtkFileSystem *file_system = g_value_get_object (value); - if (impl->file_system != file_system) - { - if (impl->file_system) - { - g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); - impl->volumes_changed_id = 0; - g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id); - impl->bookmarks_changed_id = 0; - g_object_unref (impl->file_system); - } - impl->file_system = file_system; - if (impl->file_system) - { - g_object_ref (impl->file_system); - impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed", - G_CALLBACK (volumes_changed_cb), - impl); - impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed", - G_CALLBACK (bookmarks_changed_cb), - impl); - } - } - } + case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND: + set_file_system_backend (impl, g_value_get_string (value)); break; case GTK_FILE_CHOOSER_PROP_FILTER: set_current_filter (impl, g_value_get_object (value)); @@ -3238,9 +3259,9 @@ list_mtime_data_func (GtkTreeViewColumn *tree_column, } GtkWidget * -_gtk_file_chooser_default_new (GtkFileSystem *file_system) +_gtk_file_chooser_default_new (const char *file_system) { return g_object_new (GTK_TYPE_FILE_CHOOSER_DEFAULT, - "file-system", file_system, + "file-system-backend", file_system, NULL); } diff --git a/gtk/gtkfilechooserdefault.h b/gtk/gtkfilechooserdefault.h index 785b896f1..aeaa0965b 100644 --- a/gtk/gtkfilechooserdefault.h +++ b/gtk/gtkfilechooserdefault.h @@ -33,7 +33,7 @@ G_BEGIN_DECLS typedef struct _GtkFileChooserDefault GtkFileChooserDefault; GType _gtk_file_chooser_default_get_type (void); -GtkWidget *_gtk_file_chooser_default_new (GtkFileSystem *file_system); +GtkWidget *_gtk_file_chooser_default_new (const char *file_system); G_END_DECLS diff --git a/gtk/gtkfilechooserdialog.c b/gtk/gtkfilechooserdialog.c index 79bbec943..8ce52c398 100644 --- a/gtk/gtkfilechooserdialog.c +++ b/gtk/gtkfilechooserdialog.c @@ -33,13 +33,14 @@ struct _GtkFileChooserDialogPrivate { GtkWidget *widget; - GtkFileSystem *file_system; + char *file_system; }; #define GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE(o) (GTK_FILE_CHOOSER_DIALOG (o)->priv) static void gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class); static void gtk_file_chooser_dialog_init (GtkFileChooserDialog *dialog); +static void gtk_file_chooser_dialog_finalize (GObject *object); static GObject* gtk_file_chooser_dialog_constructor (GType type, guint n_construct_properties, @@ -109,6 +110,7 @@ gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class) gobject_class->constructor = gtk_file_chooser_dialog_constructor; gobject_class->set_property = gtk_file_chooser_dialog_set_property; gobject_class->get_property = gtk_file_chooser_dialog_get_property; + gobject_class->finalize = gtk_file_chooser_dialog_finalize; widget_class->realize = gtk_file_chooser_dialog_realize; widget_class->style_set = gtk_file_chooser_dialog_style_set; @@ -130,6 +132,14 @@ gtk_file_chooser_dialog_init (GtkFileChooserDialog *dialog) gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); } +static void +gtk_file_chooser_dialog_finalize (GObject *object) +{ + GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (object); + + g_free (dialog->priv->file_system); +} + /* Callback used when the user activates a file in the file chooser widget */ static void file_chooser_widget_file_activated (GtkFileChooser *chooser, @@ -155,7 +165,7 @@ gtk_file_chooser_dialog_constructor (GType type, if (priv->file_system) priv->widget = g_object_new (GTK_TYPE_FILE_CHOOSER_WIDGET, - "file-system", priv->file_system, + "file-system-backend", priv->file_system, NULL); else priv->widget = g_object_new (GTK_TYPE_FILE_CHOOSER_WIDGET, NULL); @@ -185,18 +195,9 @@ gtk_file_chooser_dialog_set_property (GObject *object, switch (prop_id) { - case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM: - { - GtkFileSystem *file_system = g_value_get_object (value); - if (priv->file_system != file_system) - { - if (priv->file_system) - g_object_unref (priv->file_system); - priv->file_system = file_system; - if (priv->file_system) - g_object_ref (priv->file_system); - } - } + case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND: + g_free (priv->file_system); + priv->file_system = g_value_dup_string (value); break; default: g_object_set_property (G_OBJECT (priv->widget), pspec->name, value); @@ -308,6 +309,37 @@ gtk_file_chooser_dialog_screen_changed (GtkWidget *widget, set_default_size (GTK_FILE_CHOOSER_DIALOG (widget)); } +static GtkWidget * +gtk_file_chooser_dialog_new_valist (const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const gchar *backend, + const gchar *first_button_text, + va_list varargs) +{ + GtkWidget *result; + const char *button_text = first_button_text; + gint response_id; + + result = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG, + "title", title, + "action", action, + "file-system-backend", backend, + NULL); + + if (parent) + gtk_window_set_transient_for (GTK_WINDOW (result), parent); + + while (button_text) + { + response_id = va_arg (varargs, gint); + gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id); + button_text = va_arg (varargs, const gchar *); + } + + return result; +} + /** * gtk_file_chooser_dialog_new: * @title: Title of the dialog, or %NULL @@ -332,26 +364,49 @@ gtk_file_chooser_dialog_new (const gchar *title, { GtkWidget *result; va_list varargs; - const char *button_text = first_button_text; - gint response_id; - - result = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG, - "title", title, - "action", action, - NULL); - - if (parent) - gtk_window_set_transient_for (GTK_WINDOW (result), parent); - + va_start (varargs, first_button_text); - - while (button_text) - { - response_id = va_arg (varargs, gint); - gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id); - button_text = va_arg (varargs, const gchar *); - } - + result = gtk_file_chooser_dialog_new_valist (title, parent, action, + NULL, first_button_text, + varargs); + va_end (varargs); + + return result; +} + +/** + * gtk_file_chooser_dialog_new_with_backend: + * @title: Title of the dialog, or %NULL + * @parent: Transient parent of the dialog, or %NULL + * @backend: The name of the specific filesystem backend to use. + * @action: Open or save mode for the dialog + * @first_button_text: stock ID or text to go in the first button, or %NULL + * @Varargs: response ID for the first button, then additional (button, id) pairs, ending with %NULL + * + * Creates a new #GtkFileChooserDialog with a specified backend. This is + * especially useful if you use gtk_file_chooser_set_local_only() to allow + * non-local files and you use a more expressive vfs, such as gnome-vfs, + * to load files. + * + * Return value: a new #GtkFileChooserDialog + * + * Since: 2.4 + **/ +GtkWidget * +gtk_file_chooser_dialog_new_with_backend (const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const gchar *backend, + const gchar *first_button_text, + ...) +{ + GtkWidget *result; + va_list varargs; + + va_start (varargs, first_button_text); + result = gtk_file_chooser_dialog_new_valist (title, parent, action, + backend, first_button_text, + varargs); va_end (varargs); return result; diff --git a/gtk/gtkfilechooserdialog.h b/gtk/gtkfilechooserdialog.h index 0e19fe4a9..803085cba 100644 --- a/gtk/gtkfilechooserdialog.h +++ b/gtk/gtkfilechooserdialog.h @@ -50,12 +50,18 @@ struct _GtkFileChooserDialog GtkFileChooserDialogPrivate *priv; }; -GType gtk_file_chooser_dialog_get_type (void); -GtkWidget *gtk_file_chooser_dialog_new (const gchar *title, - GtkWindow *parent, - GtkFileChooserAction action, - const gchar *first_button_text, - ...); +GType gtk_file_chooser_dialog_get_type (void); +GtkWidget *gtk_file_chooser_dialog_new (const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const gchar *first_button_text, + ...); +GtkWidget *gtk_file_chooser_dialog_new_with_backend (const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const gchar *backend, + const gchar *first_button_text, + ...); G_END_DECLS diff --git a/gtk/gtkfilechooserutils.c b/gtk/gtkfilechooserutils.c index 6cce6fee2..d9ca91e7c 100644 --- a/gtk/gtkfilechooserutils.c +++ b/gtk/gtkfilechooserutils.c @@ -83,8 +83,8 @@ _gtk_file_chooser_install_properties (GObjectClass *klass) GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET, "extra-widget"); g_object_class_override_property (klass, - GTK_FILE_CHOOSER_PROP_FILE_SYSTEM, - "file-system"); + GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND, + "file-system-backend"); g_object_class_override_property (klass, GTK_FILE_CHOOSER_PROP_FILTER, "filter"); diff --git a/gtk/gtkfilechooserutils.h b/gtk/gtkfilechooserutils.h index 038114140..16c0f09de 100644 --- a/gtk/gtkfilechooserutils.h +++ b/gtk/gtkfilechooserutils.h @@ -29,7 +29,7 @@ G_BEGIN_DECLS typedef enum { GTK_FILE_CHOOSER_PROP_FIRST = 0x1000, GTK_FILE_CHOOSER_PROP_ACTION = GTK_FILE_CHOOSER_PROP_FIRST, - GTK_FILE_CHOOSER_PROP_FILE_SYSTEM, + GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND, GTK_FILE_CHOOSER_PROP_FILTER, GTK_FILE_CHOOSER_PROP_FOLDER_MODE, GTK_FILE_CHOOSER_PROP_LOCAL_ONLY, diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c index f0cd8e818..2e9d3bef4 100644 --- a/gtk/gtkfilechooserwidget.c +++ b/gtk/gtkfilechooserwidget.c @@ -23,23 +23,18 @@ #include "gtkfilechooserutils.h" #include "gtktypebuiltins.h" -#if defined (G_OS_UNIX) -#include "gtkfilesystemunix.h" -#elif defined (G_OS_WIN32) -#include "gtkfilesystemwin32.h" -#endif - struct _GtkFileChooserWidgetPrivate { GtkWidget *impl; - GtkFileSystem *file_system; + char *file_system; }; #define GTK_FILE_CHOOSER_WIDGET_GET_PRIVATE(o) (GTK_FILE_CHOOSER_WIDGET (o)->priv) static void gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class); static void gtk_file_chooser_widget_init (GtkFileChooserWidget *chooser_widget); +static void gtk_file_chooser_widget_finalize (GObject *object); static GObject* gtk_file_chooser_widget_constructor (GType type, guint n_construct_properties, @@ -102,6 +97,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class) gobject_class->constructor = gtk_file_chooser_widget_constructor; gobject_class->set_property = gtk_file_chooser_widget_set_property; gobject_class->get_property = gtk_file_chooser_widget_get_property; + gobject_class->finalize = gtk_file_chooser_widget_finalize; _gtk_file_chooser_install_properties (gobject_class); @@ -117,6 +113,14 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *chooser_widget) chooser_widget->priv = priv; } +static void +gtk_file_chooser_widget_finalize (GObject *object) +{ + GtkFileChooserWidget *chooser = GTK_FILE_CHOOSER_WIDGET (object); + + g_free (chooser->priv->file_system); +} + static GObject* gtk_file_chooser_widget_constructor (GType type, guint n_construct_properties, @@ -134,16 +138,8 @@ gtk_file_chooser_widget_constructor (GType type, gtk_widget_push_composite_child (); - if (!priv->file_system) - { -#if defined (G_OS_UNIX) - priv->file_system = gtk_file_system_unix_new (); -#elif defined (G_OS_WIN32) - priv->file_system = gtk_file_system_win32_new (); -#endif - } - priv->impl = _gtk_file_chooser_default_new (priv->file_system); + gtk_box_pack_start (GTK_BOX (object), priv->impl, TRUE, TRUE, 0); gtk_widget_show (priv->impl); @@ -174,18 +170,9 @@ gtk_file_chooser_widget_set_property (GObject *object, switch (prop_id) { - case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM: - { - GtkFileSystem *file_system = g_value_get_object (value); - if (priv->file_system != file_system) - { - if (priv->file_system) - g_object_unref (priv->file_system); - priv->file_system = file_system; - if (priv->file_system) - g_object_ref (priv->file_system); - } - } + case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND: + g_free (priv->file_system); + priv->file_system = g_value_dup_string (value); break; default: g_object_set_property (G_OBJECT (priv->impl), pspec->name, value); diff --git a/gtk/gtkfilesystem.c b/gtk/gtkfilesystem.c index de1cb6e8c..9f2f653f3 100644 --- a/gtk/gtkfilesystem.c +++ b/gtk/gtkfilesystem.c @@ -18,9 +18,10 @@ * Boston, MA 02111-1307, USA. */ - +#include #include "gtkfilesystem.h" #include "gtkicontheme.h" +#include "gtkmain.h" #include @@ -886,3 +887,170 @@ gtk_file_paths_free (GSList *paths) g_slist_free (paths); } + +/***************************************** + * GtkFileSystem modules * + *****************************************/ + +typedef struct _GtkFileSystemModule GtkFileSystemModule; +typedef struct _GtkFileSystemModuleClass GtkFileSystemModuleClass; + +struct _GtkFileSystemModule +{ + GTypeModule parent_instance; + + GModule *library; + + void (*init) (GTypeModule *module); + void (*exit) (void); + GtkFileSystem * (*create) (void); + + gchar *path; +}; + +struct _GtkFileSystemModuleClass +{ + GTypeModuleClass parent_class; +}; + +G_DEFINE_TYPE (GtkFileSystemModule, gtk_file_system_module, G_TYPE_TYPE_MODULE); +#define GTK_TYPE_FILE_SYSTEM_MODULE (gtk_file_system_module_get_type ()) +#define GTK_FILE_SYSTEM_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), GTK_TYPE_FILE_SYSTEM_MODULE, GtkFileSystemModule)) + + +static GSList *loaded_file_systems; + +static gboolean +gtk_file_system_module_load (GTypeModule *module) +{ + GtkFileSystemModule *fs_module = GTK_FILE_SYSTEM_MODULE (module); + + fs_module->library = g_module_open (fs_module->path, 0); + if (!fs_module->library) + { + g_warning (g_module_error()); + return FALSE; + } + + /* extract symbols from the lib */ + if (!g_module_symbol (fs_module->library, "fs_module_init", + (gpointer *)&fs_module->init) || + !g_module_symbol (fs_module->library, "fs_module_exit", + (gpointer *)&fs_module->exit) || + !g_module_symbol (fs_module->library, "fs_module_create", + (gpointer *)&fs_module->create)) + { + g_warning (g_module_error()); + g_module_close (fs_module->library); + + return FALSE; + } + + /* call the filesystems's init function to let it */ + /* setup anything it needs to set up. */ + fs_module->init (module); + + return TRUE; +} + +static void +gtk_file_system_module_unload (GTypeModule *module) +{ + GtkFileSystemModule *fs_module = GTK_FILE_SYSTEM_MODULE (module); + + fs_module->exit(); + + g_module_close (fs_module->library); + fs_module->library = NULL; + + fs_module->init = NULL; + fs_module->exit = NULL; + fs_module->create = NULL; +} + +/* This only will ever be called if an error occurs during + * initialization + */ +static void +gtk_file_system_module_finalize (GObject *object) +{ + GtkFileSystemModule *module = GTK_FILE_SYSTEM_MODULE (object); + + g_free (module->path); + + G_OBJECT_CLASS (gtk_file_system_module_parent_class)->finalize (object); +} + +static void +gtk_file_system_module_class_init (GtkFileSystemModuleClass *class) +{ + GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class); + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + module_class->load = gtk_file_system_module_load; + module_class->unload = gtk_file_system_module_unload; + + gobject_class->finalize = gtk_file_system_module_finalize; +} + +static void +gtk_file_system_module_init (GtkFileSystemModule *fs_module) +{ +} + + +static GtkFileSystem * +_gtk_file_system_module_create (GtkFileSystemModule *fs_module) +{ + GtkFileSystem *fs; + + if (g_type_module_use (G_TYPE_MODULE (fs_module))) + { + fs = fs_module->create (); + g_type_module_unuse (G_TYPE_MODULE (fs_module)); + return fs; + } + return NULL; +} + + +GtkFileSystem * +_gtk_file_system_create (const char *file_system_name) +{ + struct FileSystemInfo *file_system_info; + GSList *l; + char *module_path; + GtkFileSystemModule *fs_module; + GtkFileSystem *fs; + + for (l = loaded_file_systems; l != NULL; l = l->next) + { + fs_module = l->data; + + if (strcmp (G_TYPE_MODULE (fs_module)->name, file_system_name) == 0) + return _gtk_file_system_module_create (fs_module); + } + + fs = NULL; + if (g_module_supported ()) + { + module_path = _gtk_find_module (file_system_name, "filesystems"); + + if (module_path) + { + fs_module = g_object_new (GTK_TYPE_FILE_SYSTEM_MODULE, NULL); + + g_type_module_set_name (G_TYPE_MODULE (fs_module), file_system_name); + fs_module->path = g_strdup (module_path); + + loaded_file_systems = g_slist_prepend (loaded_file_systems, + fs_module); + + fs = _gtk_file_system_module_create (fs_module); + } + + g_free (module_path); + } + + return fs; +} diff --git a/gtk/gtkfilesystem.h b/gtk/gtkfilesystem.h index 99e726886..3dc914b2c 100644 --- a/gtk/gtkfilesystem.h +++ b/gtk/gtkfilesystem.h @@ -335,6 +335,10 @@ GSList *gtk_file_paths_sort (GSList *paths); GSList *gtk_file_paths_copy (GSList *paths); void gtk_file_paths_free (GSList *paths); +/* GtkFileSystem modules support */ + +GtkFileSystem *_gtk_file_system_create (const char *file_system_name); + G_END_DECLS #endif /* __GTK_FILE_SYSTEM_H__ */