Git Repositories

2005-11-21 Benedikt Meurer <benny@xfce.org>
authorBenedikt Meurer <benny@xfce.org>
Mon, 21 Nov 2005 20:58:54 +0000 (20:58 +0000)
committerBenedikt Meurer <benny@xfce.org>
Mon, 21 Nov 2005 20:58:54 +0000 (20:58 +0000)
* thunarx/thunarx-provider-plugin.{c,h}, thunarx/Makefile.am,
  thunarx/thunarx.h, thunarx/thunarx.symbols: Add ThunarxProviderPlugin
  interface, which abstracts from the details of the dynamic type
  registration, and is accessible to the extensions.
* thunarx/thunarx-provider-module.{c,h}, thunarx/Makefile.am: Add
  implementation for the ThunarxProviderPlugin interface, based on
  GTypeModule, which is used on the file manager's side to manage the
  type plugins.
* thunarx/thunarx-provider-factory.{c,h}, thunarx/Makefile.am,
  thunarx/thunarx.h, thunarx/thunarx.symbols: Add ThunarxProviderFactory
  based on the ThunarExtensionManager as public interface to the
  provider plugin mechanism. This may also be used by other applications
  in the future.
* thunarx/thunarx.h: Provide convenience macros ala G_DEFINE_TYPE() to
  ease type registration for plugin writers.
* examples/, configure.in.in: Update the "Open Terminal Here" example.
* docs/reference/thunarx/: Update the thunarx reference manual to
  include the new classes and interfaces.
* thunar/thunar-extension-manager.{c,h}: Drop the old extension manager
  class in favour of the new provider factory class.
* thunar/thunar-properties-dialog.c, thunar/thunar-standard-view.c: Use
  ThunarxProviderFactory to load the providers from the installed
  extensions.
* po/POTFILES.in: Update with new file list.
* thunar/thunar-file.{c,h}: Implement thunar_file_list_copy() using
  thunarx_file_info_list_copy() and thunar_file_list_free() using
  thunarx_file_info_list_free().
* docs/reference/thunar-vfs/thunar-vfs-overrides.txt,
  docs/reference/thunarx/thunarx-overrides.txt: Fix build error with
  older gtk-doc versions.

(Old svn revision: 18919)

34 files changed:
ChangeLog
configure.in.in
docs/reference/thunar-vfs/thunar-vfs-overrides.txt [new file with mode: 0644]
docs/reference/thunarx/thunarx-docs.sgml
docs/reference/thunarx/thunarx-overrides.txt [new file with mode: 0644]
docs/reference/thunarx/thunarx-sections.txt
docs/reference/thunarx/thunarx.types
docs/reference/thunarx/tmpl/thunarx-menu-provider.sgml
docs/reference/thunarx/tmpl/thunarx-provider-factory.sgml [new file with mode: 0644]
docs/reference/thunarx/tmpl/thunarx-provider-plugin.sgml [new file with mode: 0644]
examples/Makefile.am
examples/open-terminal-here/open-terminal-here.c [deleted file]
examples/tex-open-terminal/Makefile.am [moved from examples/open-terminal-here/Makefile.am with 62% similarity]
examples/tex-open-terminal/README [moved from examples/open-terminal-here/README with 100% similarity]
examples/tex-open-terminal/tex-open-terminal-plugin.c [new file with mode: 0644]
examples/tex-open-terminal/tex-open-terminal.c [new file with mode: 0644]
examples/tex-open-terminal/tex-open-terminal.h [new file with mode: 0644]
po/POTFILES.in
thunar/Makefile.am
thunar/thunar-extension-manager.c [deleted file]
thunar/thunar-extension-manager.h [deleted file]
thunar/thunar-file.c
thunar/thunar-file.h
thunar/thunar-properties-dialog.c
thunar/thunar-standard-view.c
thunarx/Makefile.am
thunarx/thunarx-provider-factory.c [new file with mode: 0644]
thunarx/thunarx-provider-factory.h [new file with mode: 0644]
thunarx/thunarx-provider-module.c [new file with mode: 0644]
thunarx/thunarx-provider-module.h [new file with mode: 0644]
thunarx/thunarx-provider-plugin.c [new file with mode: 0644]
thunarx/thunarx-provider-plugin.h [new file with mode: 0644]
thunarx/thunarx.h
thunarx/thunarx.symbols

index da895f6..78922ab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2005-11-21     Benedikt Meurer <benny@xfce.org>
+
+       * thunarx/thunarx-provider-plugin.{c,h}, thunarx/Makefile.am,
+         thunarx/thunarx.h, thunarx/thunarx.symbols: Add ThunarxProviderPlugin
+         interface, which abstracts from the details of the dynamic type
+         registration, and is accessible to the extensions.
+       * thunarx/thunarx-provider-module.{c,h}, thunarx/Makefile.am: Add
+         implementation for the ThunarxProviderPlugin interface, based on
+         GTypeModule, which is used on the file manager's side to manage the
+         type plugins.
+       * thunarx/thunarx-provider-factory.{c,h}, thunarx/Makefile.am,
+         thunarx/thunarx.h, thunarx/thunarx.symbols: Add ThunarxProviderFactory
+         based on the ThunarExtensionManager as public interface to the
+         provider plugin mechanism. This may also be used by other applications
+         in the future.
+       * thunarx/thunarx.h: Provide convenience macros ala G_DEFINE_TYPE() to
+         ease type registration for plugin writers.
+       * examples/, configure.in.in: Update the "Open Terminal Here" example.
+       * docs/reference/thunarx/: Update the thunarx reference manual to
+         include the new classes and interfaces.
+       * thunar/thunar-extension-manager.{c,h}: Drop the old extension manager
+         class in favour of the new provider factory class.
+       * thunar/thunar-properties-dialog.c, thunar/thunar-standard-view.c: Use
+         ThunarxProviderFactory to load the providers from the installed
+         extensions.
+       * po/POTFILES.in: Update with new file list.
+       * thunar/thunar-file.{c,h}: Implement thunar_file_list_copy() using
+         thunarx_file_info_list_copy() and thunar_file_list_free() using
+         thunarx_file_info_list_free().
+       * docs/reference/thunar-vfs/thunar-vfs-overrides.txt,
+         docs/reference/thunarx/thunarx-overrides.txt: Fix build error with
+         older gtk-doc versions.
+
 2005-11-16     Benedikt Meurer <benny@xfce.org>
 
        * thunar-vfs/thunar-vfs-mime-application.{c,h},
index 5f014c4..5f064d8 100644 (file)
@@ -328,7 +328,7 @@ docs/reference/thunar-vfs/version.xml
 docs/reference/thunarx/Makefile
 docs/reference/thunarx/version.xml
 examples/Makefile
-examples/open-terminal-here/Makefile
+examples/tex-open-terminal/Makefile
 icons/Makefile
 icons/24x24/Makefile
 icons/48x48/Makefile
diff --git a/docs/reference/thunar-vfs/thunar-vfs-overrides.txt b/docs/reference/thunar-vfs/thunar-vfs-overrides.txt
new file mode 100644 (file)
index 0000000..e69de29
index 9170769..f30b561 100644 (file)
@@ -6,6 +6,8 @@
 <!ENTITY ThunarxMenuProvider SYSTEM "xml/thunarx-menu-provider.xml">
 <!ENTITY ThunarxPropertyPage SYSTEM "xml/thunarx-property-page.xml">
 <!ENTITY ThunarxPropertyPageProvider SYSTEM "xml/thunarx-property-page-provider.xml">
+<!ENTITY ThunarxProviderFactory SYSTEM "xml/thunarx-provider-factory.xml">
+<!ENTITY ThunarxProviderPlugin SYSTEM "xml/thunarx-provider-plugin.xml">
 <!ENTITY thunarx-version-information SYSTEM "xml/thunarx-version-information.xml">
 
 <!ENTITY version SYSTEM "version.xml">
         <para>
           <emphasis>Thunar Extensions</emphasis> are shared libraries that extend the basic functionality
           provided by the Thunar File Manager. An extension exports one or more <link
-          linkend="GObject"><type>GObject</type></link>s, called <emphasis>providers</emphasis> to Thunar.
+          linkend="GObject"><type>GObject</type></link>s, called <emphasis>providers</emphasis>, to Thunar.
         </para>
 
         <para>
           Thunar passes file references to the provider using <link linkend="ThunarxFileInfo"><type>ThunarxFileInfo</type></link>
           objects. The <link linkend="ThunarxFileInfo"><type>ThunarxFileInfo</type></link> interface provides access to the file
           information that Thunar has already read - mime type, URI, name, etc. Extensions should use the data from
-          from the <link linkend="ThunarxFileInfo"><type>ThunarxFileInfo</type></link> rather than reading it themselves, to
+          the <link linkend="ThunarxFileInfo"><type>ThunarxFileInfo</type></link> rather than reading it themselves, to
           prevent excessive I/O.
         </para>
 
           Most objects created by the extensions need names, e.g. the <link linkend="GtkAction"><type>GtkAction</type></link>s
           returned from the <link linkend="ThunarxMenuProvider"><type>ThunarxMenuProvider</type></link>s. These names must be
           namespaced with the name of the extension. For example the main action returned from the
-          <application>OpenTerminal</application> extension should be called <literal>OpenTerminal::open-terminal</literal>.
-          The namespace must be global among the providers exported by a certain extension.
+          <application>TexOpenTerminal</application> extension (which can be found in the <filename
+          role="directory">examples/tex-open-terminal</filename> subdirectory of the Thunar distribution) should be called
+          <literal>TexOpenTerminal::open-terminal</literal>. The namespace must be global among the providers exported by
+          a certain extension.
         </para>
       </sect2>
 
         <para>
           Thunar extensions are loaded as <link linkend="GTypeModule"><type>GTypeModule</type></link>s. This means that all GTypes
           created by the extension must be registered with the <link linkend="GTypeModule"><type>GTypeModule</type></link>, using
-          <link linkend="g-type-module-register-type"><function>g_type_module_register_type()</function></link> function rather
-          than <link linked="g-type-register-static"><function>g_type_register_static()</function></link>. All types exported by
-          an extension must be registered in
+          <link linkend="thunarx-provider-plugin-register-type"><function>thunarx_provider_plugin_register_type()</function></link>
+          function (or one of the convenience macros like <link linkend="THUNARX-DEFINE-TYPE:CAPS"><function>THUNARX_DEFINE_TYPE()</function></link>)
+          rather than <link linked="g-type-register-static"><function>g_type_register_static()</function></link>. All types
+          exported by an extension must be registered in
           <link linkend="thunar-extension-initialize"><function>thunar_extension_initialize()</function></link>.
         </para>
       </sect2>
       <title>Getting Started</title>
 
       <para>
-        Providers are <link linkend="GTypeModule"><type>GTypeModule</type></link>s loaded from shared libraries installed in
-        <filename role="directory">$libdir/thunarx-1/</filename>. The shared libraries are linked against the
+        Providers are <link linkend="ThunarxProviderPlugin"><type>ThunarxProviderPlugin</type></link>s loaded from shared libraries
+        installed in <filename role="directory">$libdir/thunarx-1/</filename>. The shared libraries are linked against the
         <systemitem class="library">thunarx-1</systemitem> library.
       </para>
 
       </para>
 
       <para>
-        <function>thunar_extension_initialize()</function> is passed a <link linkend="GTypeModule"><type>GTypeModule</type></link>
-        object, and must register all GTypes that the extension needs. <function>thunar_extension_shutdown()</function> should
+        <function>thunar_extension_initialize()</function> is passed a <link linkend="ThunarxProviderPlugin"><type>ThunarxProviderPlugin</type></link>
+        object, and is responsible to register all GTypes required by the extension. <function>thunar_extension_shutdown()</function> should
         perform any extension-specific shutdown required prior to unloading the extension. <function>thunar_extension_list_types()</function>
         returns an array of GTypes that represent the types of the providers exported by the extension. Thunar will instantiate
         objects of those types when needed.
 static GType type_list[1];
 
 static void
-foo_extension_register_type (GTypeModule *module)
+foo_extension_register_type (ThunarxProviderPlugin *plugin)
 {
   static const GTypeInfo info =
   {
@@ -239,10 +244,10 @@ foo_extension_register_type (GTypeModule *module)
     NULL,
   };
 
-  type_list[0] = g_type_module_register_type (module,
-                                              G_TYPE_OBJECT,
-                                              "FooExtension",
-                                              &amp;info, 0);
+  type_list[0] = thunarx_provider_plugin_register_type (plugin,
+                                                        G_TYPE_OBJECT,
+                                                        "FooExtension",
+                                                        &amp;info, 0);
 
   /* implement the desired provider interfaces */
 }
@@ -254,7 +259,7 @@ foo_extension_get_type (void)
 }
 
 G_MODULE_EXPORT void
-thunar_extension_initialize (GTypeModule *module)
+thunar_extension_initialize (ThunarxProviderPlugin *plugin)
 {
   const gchar *mismatch;
 
@@ -268,7 +273,7 @@ thunar_extension_initialize (GTypeModule *module)
       return;
     }
 
-  foo_extension_register_type (module);
+  foo_extension_register_type (plugin);
 }
 
 G_MODULE_EXPORT void
@@ -286,6 +291,12 @@ thunar_extension_list_types (const GType **types,
 }</programlisting>
       </example>
 
+      <para>
+        You should check the <application>TexOpenTerminal</application> extension, which is included in the Thunar
+        distribution in the <filename role="directory">examples/tex-open-terminal</filename> directory, for a more
+        complete example of how to write a Thunar extension.
+      </para>
+
       <sect2 id="thunarx-writing-extensions-compiling-thunar-extensions">
         <title>Compiling Thunar Extensions</title>
 
@@ -362,24 +373,23 @@ $ install -c -m 0755 foo.so `pkg-config --variable=extensionsdir thunarx-1`/foo.
         </para>
 
         <para>
-          Such extensions must set the <literal>resident</literal> property of the type
-          module in its <function>thunar_extension_initialize()</function> function to
-          <literal>TRUE</literal>.
+          Such extensions must set the <literal>resident</literal> property of the provider plugin in its
+          <function>thunar_extension_initialize()</function> function to <literal>TRUE</literal>, using the <link
+          linkend="thunarx-provider-plugin-set-resident"><function>thunarx_provider_plugin_set_resident()</function></link>
+          method.
         </para>
 
         <example>
           <title>Making an extension memory resident</title>
           <programlisting>
 G_MODULE_EXPORT void
-thunar_extension_initialize (GTypeModule *module)
+thunar_extension_initialize (ThunarxProviderPlugin *plugin)
 {
   /* setup the types for the extension */
   ...
 
   /* ensure that the extension will never be unloaded */
-  g_object_set (G_OBJECT (module),
-                "resident", TRUE,
-                NULL);
+  thunarx_provider_plugin_set_resident (plugin, TRUE);
 }</programlisting>
         </example>
       </sect2>
@@ -397,8 +407,8 @@ thunar_extension_initialize (GTypeModule *module)
 
     <para>
       In order to hide the internals of the file manager from the extensions, the <systemitem
-      class="library">thunarx</systemitem> provides an abstraction layer, which includes interfaces
-      accessible to the extension, that are implemented by the file manager at runtime.
+      class="library">thunarx</systemitem> library provides an abstraction layer, which includes
+      interfaces accessible to the extension, that are implemented by the file manager at runtime.
     </para>
 
     <para>
@@ -409,14 +419,17 @@ thunar_extension_initialize (GTypeModule *module)
       Currently the abstraction layer consists of the interface <link
       linkend="ThunarxFileInfo"><type>ThunarxFileInfo</type></link>, which provides
       extensions with a way to access information about a file handled within
-      the file manager, and the class <link
+      the file manager, the class <link
       linkend="ThunarxPropertyPage"><type>ThunarxPropertyPage</type></link>, which
       is the base class for widgets that can be added to the properties dialog by
-      extensions.
+      extensions, and the interface <link
+      linkend="ThunarxProviderPlugin"><type>ThunarxProviderPlugin</type></link>, which
+      hides the details of dynamic type registration from the extensions.
     </para>
 
     &ThunarxFileInfo;
     &ThunarxPropertyPage;
+    &ThunarxProviderPlugin;
   </part>
 
   <part id="thunarx-providers">
@@ -444,6 +457,12 @@ thunar_extension_initialize (GTypeModule *module)
     &ThunarxPropertyPageProvider;
   </part>
 
+  <part id="thunarx-using-extensions">
+    <title>Using Thunar extensions in applications</title>
+
+    &ThunarxProviderFactory;
+  </part>
+
   <index>
     <title>Index</title>
   </index>
diff --git a/docs/reference/thunarx/thunarx-overrides.txt b/docs/reference/thunarx/thunarx-overrides.txt
new file mode 100644 (file)
index 0000000..e69de29
index 1511a2e..019b327 100644 (file)
@@ -78,6 +78,50 @@ thunarx_property_page_provider_get_type
 </SECTION>
 
 <SECTION>
+<FILE>thunarx-provider-factory</FILE>
+<TITLE>ThunarxProviderFactory</TITLE>
+ThunarxProviderFactory
+thunarx_provider_factory_get_default
+thunarx_provider_factory_list_providers
+<SUBSECTION Standard>
+ThunarxProviderFactoryClass
+THUNARX_TYPE_PROVIDER_FACTORY
+THUNARX_PROVIDER_FACTORY
+THUNARX_PROVIDER_FACTORY_CLASS
+THUNARX_IS_PROVIDER_FACTORY
+THUNARX_IS_PROVIDER_FACTORY_CLASS
+THUNARX_PROVIDER_FACTORY_GET_CLASS
+<SUBSECTION Private>
+thunarx_provider_factory_get_type
+</SECTION>
+
+<SECTION>
+<FILE>thunarx-provider-plugin</FILE>
+<TITLE>ThunarxProviderPlugin</TITLE>
+ThunarxProviderPlugin
+ThunarxProviderPluginIface
+thunarx_provider_plugin_get_resident
+thunarx_provider_plugin_set_resident
+thunarx_provider_plugin_register_type
+thunarx_provider_plugin_add_interface
+thunarx_provider_plugin_register_enum
+thunarx_provider_plugin_register_flags
+THUNARX_DEFINE_TYPE
+THUNARX_DEFINE_TYPE_WITH_CODE
+THUNARX_DEFINE_ABSTRACT_TYPE
+THUNARX_DEFINE_ABSTRACT_TYPE_WITH_CODE
+THUNARX_DEFINE_TYPE_EXTENDED
+THUNARX_IMPLEMENT_INTERFACE
+<SUBSECTION Standard>
+THUNARX_TYPE_PROVIDER_PLUGIN
+THUNARX_PROVIDER_PLUGIN
+THUNARX_IS_PROVIDER_PLUGIN
+THUNARX_PROVIDER_PLUGIN_GET_IFACE
+<SUBSECTION Private>
+thunarx_provider_plugin_get_type
+</SECTION>
+
+<SECTION>
 <FILE>thunarx-version-information</FILE>
 <TITLE>Variables and functions to check the library version</TITLE>
 thunarx_major_version
index 604cc03..8dd576c 100644 (file)
@@ -4,3 +4,5 @@ thunarx_file_info_get_type
 thunarx_menu_provider_get_type
 thunarx_property_page_get_type
 thunarx_property_page_provider_get_type
+thunarx_provider_factory_get_type
+thunarx_provider_plugin_get_type
index c50d9f8..d424e6b 100644 (file)
@@ -35,43 +35,14 @@ The interface to extensions that provide additional menu items
   <title>Menu provider example</title>
 
   <programlisting>
-static GType hello_type;
-
 static void   hello_menu_provider_init (ThunarxMenuProviderIface *iface);
 static GList *hello_get_file_actions   (ThunarxMenuProvider      *provider,
                                         GtkWidget                *window,
                                         GList                    *files);
 
-static void
-hello_register_type (GTypeModule *module)
-{
-  static const GTypeInfo info =
-  {
-    sizeof (HelloClass),
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    sizeof (Hello),
-    0,
-    NULL,
-    NULL,
-  };
-
-  static const GInterfaceInfo menu_provider_info =
-  {
-    (GInterfaceInitFunc) hello_menu_provider_init,
-    NULL,
-    NULL,
-  };
-
-  hello_type = g_type_module_register_type (module, G_TYPE_OBJECT,
-                                            "Hello", &amp;info, 0);
-  g_type_module_add_interface (module, hello_type,
-                               THUNARX_TYPE_MENU_PROVIDER,
-                               &amp;menu_provider_info);
-}
+THUNARX_DEFINE_TYPE_WITH_CODE (Hello, hello, G_TYPE_OBJECT,
+                               THUNARX_IMPLEMENT_INTERFACE (THUNARX_TYPE_MENU_PROVIDER,
+                                                            hello_menu_provider_init));
 
 static void
 hello_menu_provider_init (ThunarxMenuProviderIface *iface)
diff --git a/docs/reference/thunarx/tmpl/thunarx-provider-factory.sgml b/docs/reference/thunarx/tmpl/thunarx-provider-factory.sgml
new file mode 100644 (file)
index 0000000..2372fae
--- /dev/null
@@ -0,0 +1,43 @@
+<!-- ##### SECTION Title ##### -->
+ThunarxProviderFactory
+
+<!-- ##### SECTION Short_Description ##### -->
+Provider factory support
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+  #ThunarxMenuProvider, #ThunarxPropertyPageProvider
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT ThunarxProviderFactory ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION thunarx_provider_factory_get_default ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
+
+<!-- ##### FUNCTION thunarx_provider_factory_list_providers ##### -->
+<para>
+
+</para>
+
+@factory: 
+@type: 
+@Returns: 
+
+
diff --git a/docs/reference/thunarx/tmpl/thunarx-provider-plugin.sgml b/docs/reference/thunarx/tmpl/thunarx-provider-plugin.sgml
new file mode 100644 (file)
index 0000000..7ef467f
--- /dev/null
@@ -0,0 +1,258 @@
+<!-- ##### SECTION Title ##### -->
+ThunarxProviderPlugin
+
+<!-- ##### SECTION Short_Description ##### -->
+Plugin type registration
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+  #ThunarxProviderPlugin is the interface to the file manager's type plugin loader implementation. It
+  provides methods to extensions - also called <emphasis>provider plugins</emphasis> - to register dynamic
+  types and control certain aspects of the plugin (see thunarx_provider_plugin_set_resident()).
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+       #ThunarxProviderFactory
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+Stable
+
+<!-- ##### STRUCT ThunarxProviderPlugin ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG ThunarxProviderPlugin:resident ##### -->
+<para>
+
+</para>
+
+<!-- ##### STRUCT ThunarxProviderPluginIface ##### -->
+<para>
+  Interface with virtual methods implemented by the file manager and
+  accessible from the extensions.
+</para>
+
+@get_resident: see thunarx_provider_plugin_get_resident().
+@set_resident: see thunarx_provider_plugin_set_resident().
+@register_type: see thunarx_provider_plugin_register_type().
+@add_interface: see thunarx_provider_plugin_add_interface().
+@register_enum: see thunarx_provider_plugin_register_enum().
+@register_flags: see thunarx_provider_plugin_register_flags().
+
+<!-- ##### FUNCTION thunarx_provider_plugin_get_resident ##### -->
+<para>
+
+</para>
+
+@plugin: 
+@Returns: 
+
+
+<!-- ##### FUNCTION thunarx_provider_plugin_set_resident ##### -->
+<para>
+
+</para>
+
+@plugin: 
+@resident: 
+
+
+<!-- ##### FUNCTION thunarx_provider_plugin_register_type ##### -->
+<para>
+
+</para>
+
+@plugin: 
+@type_parent: 
+@type_name: 
+@type_info: 
+@type_flags: 
+@Returns: 
+
+
+<!-- ##### FUNCTION thunarx_provider_plugin_add_interface ##### -->
+<para>
+
+</para>
+
+@plugin: 
+@instance_type: 
+@interface_type: 
+@interface_info: 
+
+
+<!-- ##### FUNCTION thunarx_provider_plugin_register_enum ##### -->
+<para>
+
+</para>
+
+@plugin: 
+@name: 
+@const_static_values: 
+@Returns: 
+
+
+<!-- ##### FUNCTION thunarx_provider_plugin_register_flags ##### -->
+<para>
+
+</para>
+
+@plugin: 
+@name: 
+@const_static_values: 
+@Returns: 
+
+
+<!-- ##### MACRO THUNARX_DEFINE_TYPE ##### -->
+<para>
+  A convenience macro for plugin type implementations, which declares a class
+  initialization function, a static variable named @t_n<!---->_parent_class
+  pointing to the parent and a static variable named @t_n<!---->_type containing
+  the #GType of the type to define. Furthermore, it defines a @t_n<!---->_get_type()
+  function and a @t_n<!---->_register_type() function. See THUNARX_DEFINE_TYPE_EXTENDED()
+  for an example.
+</para>
+
+@TN: the name of the new type, in Camel case.
+@t_n: the name of the new type, in lowercase, with words separated by '_'.
+@T_P: the #GType of the parent type.
+
+
+<!-- ##### MACRO THUNARX_DEFINE_TYPE_WITH_CODE ##### -->
+<para>
+  A convenience macro for plugin type implementations. Similar to THUNARX_DEFINE_TYPE(), but
+  allows to insert custom code into the <code>*_get_type()</code> function, e.g. interface
+  implemenations via THUNARX_IMPLEMENT_INTERFACE(). See THUNARX_DEFINE_TYPE_EXTENDED() for
+  an example.
+</para>
+
+@TN: the name of the new type, in Camel case.
+@t_n: the name of the new type, in lowercase, with words separated by '_'.
+@T_P: the #GType of the parent type.
+@_C_: custom code that gets inserted in the <code>*_get_type()</code> function.
+
+
+<!-- ##### MACRO THUNARX_DEFINE_ABSTRACT_TYPE ##### -->
+<para>
+  A convenience macro for plugin type implementations. Similar to THUNARX_DEFINE_TYPE(), but defines
+  an abstract type. See THUNARX_DEFINE_TYPE_EXTENDED() for an example.
+</para>
+
+@TN: the name of the new type, in Camel case.
+@t_n: the name of the new type, in lowercase, with words separated by '_'.
+@T_P: the #GType of the parent type.
+
+
+<!-- ##### MACRO THUNARX_DEFINE_ABSTRACT_TYPE_WITH_CODE ##### -->
+<para>
+  A convenience macro for plugin type implementations. Similar to THUNARX_DEFINE_TYPE_WITH_CODE(), but defines
+  an abstract type and allows to insert custom code into the <code>*_get_type()</code> function, e.g. interface
+  implementations via THUNARX_IMPLEMENT_INTERFACE(). See THUNARX_DEFINE_TYPE_EXTENDED() for an example.
+</para>
+
+@TN: the name of the new type, in Camel case.
+@t_n: the name of the new type, in lowercase, with words separated by '_'.
+@T_P: the #GType of the parent type.
+@_C_: custom code that gets inserted in the <code>*_get_type()</code> function.
+
+
+<!-- ##### MACRO THUNARX_DEFINE_TYPE_EXTENDED ##### -->
+<para>
+  The most general convenience macro for plugin type implementations, on which THUNARX_DEFINE_TYPE(), THUNARX_DEFINE_TYPE_WITH_CODE(),
+  THUNARX_DEFINE_ABSTRACT_TYPE() and THUNARX_DEFINE_ABSTRACT_TYPE_WITH_CODE() are based.
+
+</para>
+
+<informalexample><programlisting>
+THUNARX_DEFINE_TYPE_EXTENDED (FooExtension,
+                              foo_extension,
+                              G_TYPE_OBJECT,
+                              0,
+                              THUNARX_IMPLEMENT_INTERFACE (TYPE_BAR,
+                                                           foo_extension_bar_init));
+</programlisting></informalexample>
+
+<para>
+  expands to
+</para>
+
+<informalexample><programlisting>
+static gpointer foo_extension_parent_class = NULL;
+static GType    foo_extension_type = G_TYPE_INVALID;
+
+static void     foo_extension_init              (FooExtension *self);
+static void     foo_extension_class_init        (FooExtensionClass *klass);
+static void     foo_extension_class_intern_init (FooExtensionClass *klass)
+{
+  foo_extension_parent_class = g_type_class_peek_parent (klass);
+  foo_extension_class_init (klass);
+}
+
+GType
+foo_extension_get_type (void)
+{
+  return foo_extension_type;
+}
+
+void
+foo_extension_register_type (ThunarxProviderPlugin *plugin)
+{
+  GType thunarx_define_type_id;
+  static const thunarx_define_type_info =
+  {
+    sizeof (FooExtensionClass),
+    NULL,
+    NULL,
+    (GClassInitFunc) foo_extension_class_intern_init,
+    NULL,
+    NULL,
+    sizeof (FooExtension),
+    0,
+    (GInstanceInitFunc) foo_extension_init,
+    NULL,
+  };
+  thunarx_define_type_id = thunarx_provider_plugin_register_type (thunarx_define_type_plugin, G_TYPE_OBJECT,
+                                                                  "FooExtension", &amp;thunarx_define_type_info, 0);
+  {
+    static const GInterfaceInfo thunarx_implement_interface_info =
+    {
+      (GInterfaceInitFunc) foo_extension_bar_init,
+    };
+    thunarx_provider_plugin_add_interface (thunarx_define_type_plugin, thunarx_define_type_id,
+                                           TYPE_BAR, &amp;thunarx_implement_interface_info);
+  };
+  foo_extension_type = thunarx_define_type_id;
+}
+</programlisting></informalexample>
+
+<para>
+  The only pieces which have to be manually provided are the definitions of the instance and
+  class structure and the definitions of the instance and class init functions.
+</para>
+
+@TypeName:    The name of the new type, in Camel case.
+@type_name:   The name of the new type, in lowercase, with words separated by '_'.
+@TYPE_PARENT: The #GType of the parent type.
+@flags:       #GTypeFlags to pass to thunarx_provider_plugin_register_type().
+@CODE:        Custom code that gets inserted in the <code>*_register_type()</code> function.
+
+
+<!-- ##### MACRO THUNARX_IMPLEMENT_INTERFACE ##### -->
+<para>
+  A convenience macro to ease interface addition in the @_C_ section of THUNARX_DEFINE_TYPE_WITH_CODE()
+  or THUNARX_DEFINE_ABSTRACT_TYPE_WITH_CODE(). See THUNARX_DEFINE_TYPE_EXTENDED() for an example.
+</para>
+
+<para>
+  Note that this macro can only be used together with the <code>THUNARX_DEFINE_*</code> macros, since
+  it depends on variable names used by those macros.
+</para>
+
+@TYPE_IFACE: the #GType of the interface to add.
+@iface_init: the interface init function.
+
+
index 0811c7e..38697d1 100644 (file)
@@ -1,6 +1,6 @@
 # $Id$
 
 SUBDIRS =                                                              \
-       open-terminal-here
+       tex-open-terminal
 
 # vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/examples/open-terminal-here/open-terminal-here.c b/examples/open-terminal-here/open-terminal-here.c
deleted file mode 100644 (file)
index 55b4198..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include <thunarx/thunarx.h>
-
-
-
-/* make sure to export the required public functions */
-#ifdef HAVE_GNUC_VISIBILITY
-extern void thunar_extension_initialize (GTypeModule *module) __attribute__((visibility("default")));
-extern void thunar_extension_shutdown (void) __attribute__((visibility("default")));
-extern void thunar_extension_list_types (const GType **types, gint *n_types) __attribute__((visibility("default")));
-#else
-extern G_MODULE_EXPORT void thunar_extension_initialize (GTypeModule *module);
-extern G_MODULE_EXPORT void thunar_extension_shutdown (void);
-extern G_MODULE_EXPORT void thunar_extension_list_types (const GType **types, gint *n_types);
-#endif
-
-
-
-static GType type_list[1];
-
-
-
-typedef struct _OpenTerminalHereClass OpenTerminalHereClass;
-typedef struct _OpenTerminalHere      OpenTerminalHere;
-
-
-
-static void   open_terminal_here_register_type      (GTypeModule              *module);
-static void   open_terminal_here_menu_provider_init (ThunarxMenuProviderIface *iface);
-static GList *open_terminal_here_get_file_actions   (ThunarxMenuProvider      *provider,
-                                                     GtkWidget                *window,
-                                                     GList                    *files);
-static GList *open_terminal_here_get_folder_actions (ThunarxMenuProvider      *provider,
-                                                     GtkWidget                *window,
-                                                     ThunarxFileInfo          *folder);
-static void   open_terminal_here_activated          (GtkAction                *action,
-                                                     GtkWidget                *window);
-
-
-
-struct _OpenTerminalHereClass
-{
-  GObjectClass __parent__;
-};
-
-struct _OpenTerminalHere
-{
-  GObject __parent__;
-};
-
-
-
-static void
-open_terminal_here_register_type (GTypeModule *module)
-{
-  static const GTypeInfo info =
-  {
-    sizeof (OpenTerminalHereClass),
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    sizeof (OpenTerminalHere),
-    0,
-    NULL,
-    NULL,
-  };
-
-  static const GInterfaceInfo menu_provider_info =
-  {
-    (GInterfaceInitFunc) open_terminal_here_menu_provider_init,
-    NULL,
-    NULL,
-  };
-
-  type_list[0] = g_type_module_register_type (module, G_TYPE_OBJECT, "OpenTerminalHere", &info, 0);
-  g_type_module_add_interface (module, type_list[0], THUNARX_TYPE_MENU_PROVIDER, &menu_provider_info);
-}
-
-
-
-static void
-open_terminal_here_menu_provider_init (ThunarxMenuProviderIface *iface)
-{
-  iface->get_file_actions = open_terminal_here_get_file_actions;
-  iface->get_folder_actions = open_terminal_here_get_folder_actions;
-}
-
-
-
-static GList*
-open_terminal_here_get_file_actions (ThunarxMenuProvider *provider,
-                                     GtkWidget           *window,
-                                     GList               *files)
-{
-  /* check if we have a directory here */
-  if (G_LIKELY (files != NULL && files->next == NULL && thunarx_file_info_is_directory (files->data)))
-    return open_terminal_here_get_folder_actions (provider, window, files->data);
-
-  return NULL;
-}
-
-
-
-static GList*
-open_terminal_here_get_folder_actions (ThunarxMenuProvider *provider,
-                                       GtkWidget           *window,
-                                       ThunarxFileInfo     *folder)
-{
-  GtkAction *action = NULL;
-  gchar     *scheme;
-  gchar     *path;
-  gchar     *uri;
-
-  /* determine the uri scheme of the folder and check if we support it */
-  scheme = thunarx_file_info_get_uri_scheme (folder);
-  if (G_LIKELY (strcmp (scheme, "file") == 0))
-    {
-      /* determine the local path to the folder */
-      uri = thunarx_file_info_get_uri (folder);
-      path = g_filename_from_uri (uri, NULL, NULL);
-      g_free (uri);
-
-      /* check if we have a valid path here */
-      if (G_LIKELY (path != NULL))
-        {
-          action = gtk_action_new ("OpenTerminalHere::open-terminal-here", "Open Terminal Here", "Open Terminal in this folder", NULL);
-          g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (open_terminal_here_activated), window);
-          g_object_set_data_full (G_OBJECT (action), "open-terminal-here-path", path, g_free);
-        }
-    }
-  g_free (scheme);
-
-  return (action != NULL) ? g_list_prepend (NULL, action) : NULL;
-}
-
-
-
-static void
-open_terminal_here_activated (GtkAction *action,
-                              GtkWidget *window)
-{
-  const gchar *path;
-  GtkWidget   *dialog;
-  GError      *error = NULL;
-  gchar       *command;
-
-  /* determine the folder path */
-  path = g_object_get_data (G_OBJECT (action), "open-terminal-here-path");
-  if (G_UNLIKELY (path == NULL))
-    return;
-  
-  /* build up the command line for the terminal */
-  command = g_strdup_printf ("Terminal --working-directory \"%s\"", path);
-
-  /* try to run the terminal command */
-  if (!gdk_spawn_command_line_on_screen (gtk_widget_get_screen (window), command, &error))
-    {
-      /* display an error dialog */
-      dialog = gtk_message_dialog_new (GTK_WINDOW (window),
-                                       GTK_DIALOG_DESTROY_WITH_PARENT,
-                                       GTK_MESSAGE_ERROR,
-                                       GTK_BUTTONS_CLOSE,
-                                       "Failed to open terminal in folder %s.",
-                                       path);
-      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s.", error->message);
-      gtk_dialog_run (GTK_DIALOG (dialog));
-      gtk_widget_destroy (dialog);
-      g_error_free (error);
-    }
-
-  /* cleanup */
-  g_free (command);
-}
-
-
-
-void
-thunar_extension_initialize (GTypeModule *module)
-{
-  const gchar *mismatch;
-
-  /* verify that the thunarx versions are compatible */
-  mismatch = thunarx_check_version (THUNARX_MAJOR_VERSION, THUNARX_MINOR_VERSION, THUNARX_MICRO_VERSION);
-  if (G_UNLIKELY (mismatch != NULL))
-    {
-      g_warning ("Version mismatch: %s", mismatch);
-      return;
-    }
-
-  g_message ("Initializing OpenTerminalHere extension");
-
-  open_terminal_here_register_type (module);
-}
-
-
-
-void
-thunar_extension_shutdown (void)
-{
-  g_message ("Shutting down OpenTerminalHere extension");
-}
-
-
-
-void
-thunar_extension_list_types (const GType **types,
-                             gint         *n_types)
-{
-  *types = type_list;
-  *n_types = G_N_ELEMENTS (type_list);
-}
-
similarity index 62%
rename from examples/open-terminal-here/Makefile.am
rename to examples/tex-open-terminal/Makefile.am
index fc50b8f..01ab1b0 100644 (file)
@@ -3,28 +3,31 @@
 INCLUDES =                                                             \
        -I$(top_builddir)                                               \
        -I$(top_srcdir)                                                 \
-       -DG_LOG_DOMAIN=\"OpenTerminalHere\"                             \
+       -I$(top_srcdir)/examples                                        \
+       -DG_LOG_DOMAIN=\"TexOpenTerminal\"                              \
        $(PLATFORM_CPPFLAGS)
 
 extensionsdir = $(libdir)/thunarx-$(THUNAR_VERSION_API)
 extensions_LTLIBRARIES =                                               \
-       open-terminal-here.la
+       tex-open-terminal.la
 
-open_terminal_here_la_SOURCES =                                                \
-       open-terminal-here.c
+tex_open_terminal_la_SOURCES =                                         \
+       tex-open-terminal-plugin.c                                      \
+       tex-open-terminal.c                                             \
+       tex-open-terminal.h
 
-open_terminal_here_la_CFLAGS =                                         \
+tex_open_terminal_la_CFLAGS =                                          \
        $(GTK_CFLAGS)                                                   \
        $(PLATFORM_CFLAGS)
 
-open_terminal_here_la_DEPENDENCIES =                                   \
+tex_open_terminal_la_DEPENDENCIES =                                    \
        $(top_builddir)/thunarx/libthunarx-$(THUNAR_VERSION_API).la
 
-open_terminal_here_la_LIBADD =                                         \
+tex_open_terminal_la_LIBADD =                                          \
        $(top_builddir)/thunarx/libthunarx-$(THUNAR_VERSION_API).la     \
        $(GTK_LIBS)
 
-open_terminal_here_la_LDFLAGS =                                                \
+tex_open_terminal_la_LDFLAGS =                                         \
        -avoid-version                                                  \
        -export-dynamic                                                 \
        -module                                                         \
diff --git a/examples/tex-open-terminal/tex-open-terminal-plugin.c b/examples/tex-open-terminal/tex-open-terminal-plugin.c
new file mode 100644 (file)
index 0000000..aa8525f
--- /dev/null
@@ -0,0 +1,72 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <tex-open-terminal/tex-open-terminal.h>
+
+
+
+static GType type_list[1];
+
+
+
+G_MODULE_EXPORT void
+thunar_extension_initialize (ThunarxProviderPlugin *plugin)
+{
+  const gchar *mismatch;
+
+  /* verify that the thunarx versions are compatible */
+  mismatch = thunarx_check_version (THUNARX_MAJOR_VERSION, THUNARX_MINOR_VERSION, THUNARX_MICRO_VERSION);
+  if (G_UNLIKELY (mismatch != NULL))
+    {
+      g_warning ("Version mismatch: %s", mismatch);
+      return;
+    }
+
+  g_message ("Initializing TexOpenTerminal extension");
+
+  /* register the types provided by this plugin */
+  tex_open_terminal_register_type (plugin);
+
+  /* setup the plugin type list */
+  type_list[0] = TEX_TYPE_OPEN_TERMINAL;
+}
+
+
+
+G_MODULE_EXPORT void
+thunar_extension_shutdown (void)
+{
+  g_message ("Shutting down TexOpenTerminal extension");
+}
+
+
+
+G_MODULE_EXPORT void
+thunar_extension_list_types (const GType **types,
+                             gint         *n_types)
+{
+  *types = type_list;
+  *n_types = G_N_ELEMENTS (type_list);
+}
+
diff --git a/examples/tex-open-terminal/tex-open-terminal.c b/examples/tex-open-terminal/tex-open-terminal.c
new file mode 100644 (file)
index 0000000..950614b
--- /dev/null
@@ -0,0 +1,180 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <tex-open-terminal/tex-open-terminal.h>
+
+
+
+static void   tex_open_terminal_class_init         (TexOpenTerminalClass     *klass);
+static void   tex_open_terminal_menu_provider_init (ThunarxMenuProviderIface *iface);
+static void   tex_open_terminal_init               (TexOpenTerminal          *open_terminal);
+static GList *tex_open_terminal_get_file_actions   (ThunarxMenuProvider      *provider,
+                                                    GtkWidget                *window,
+                                                    GList                    *files);
+static GList *tex_open_terminal_get_folder_actions (ThunarxMenuProvider      *provider,
+                                                    GtkWidget                *window,
+                                                    ThunarxFileInfo          *folder);
+static void   tex_open_terminal_activated          (GtkAction                *action,
+                                                    GtkWidget                *window);
+
+
+
+struct _TexOpenTerminalClass
+{
+  GObjectClass __parent__;
+};
+
+struct _TexOpenTerminal
+{
+  GObject __parent__;
+};
+
+
+
+THUNARX_DEFINE_TYPE_WITH_CODE (TexOpenTerminal,
+                               tex_open_terminal,
+                               G_TYPE_OBJECT,
+                               THUNARX_IMPLEMENT_INTERFACE (THUNARX_TYPE_MENU_PROVIDER,
+                                                            tex_open_terminal_menu_provider_init));
+
+
+
+static void
+tex_open_terminal_class_init (TexOpenTerminalClass *klass)
+{
+  /* nothing to do here */
+}
+
+
+
+static void
+tex_open_terminal_init (TexOpenTerminal *open_terminal)
+{
+  /* nothing to do here */
+}
+
+
+
+static void
+tex_open_terminal_menu_provider_init (ThunarxMenuProviderIface *iface)
+{
+  iface->get_file_actions = tex_open_terminal_get_file_actions;
+  iface->get_folder_actions = tex_open_terminal_get_folder_actions;
+}
+
+
+
+static GList*
+tex_open_terminal_get_file_actions (ThunarxMenuProvider *provider,
+                                    GtkWidget           *window,
+                                    GList               *files)
+{
+  /* check if we have a directory here */
+  if (G_LIKELY (files != NULL && files->next == NULL && thunarx_file_info_is_directory (files->data)))
+    return tex_open_terminal_get_folder_actions (provider, window, files->data);
+
+  return NULL;
+}
+
+
+
+static GList*
+tex_open_terminal_get_folder_actions (ThunarxMenuProvider *provider,
+                                      GtkWidget           *window,
+                                      ThunarxFileInfo     *folder)
+{
+  GtkAction *action = NULL;
+  gchar     *scheme;
+  gchar     *path;
+  gchar     *uri;
+
+  /* determine the uri scheme of the folder and check if we support it */
+  scheme = thunarx_file_info_get_uri_scheme (folder);
+  if (G_LIKELY (strcmp (scheme, "file") == 0))
+    {
+      /* determine the local path to the folder */
+      uri = thunarx_file_info_get_uri (folder);
+      path = g_filename_from_uri (uri, NULL, NULL);
+      g_free (uri);
+
+      /* check if we have a valid path here */
+      if (G_LIKELY (path != NULL))
+        {
+          action = gtk_action_new ("TexOpenTerminal::open-terminal-here", "Open Terminal Here", "Open Terminal in this folder", NULL);
+          g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (tex_open_terminal_activated), window);
+          g_object_set_data_full (G_OBJECT (action), "open-terminal-here-path", path, g_free);
+        }
+    }
+  g_free (scheme);
+
+  return (action != NULL) ? g_list_prepend (NULL, action) : NULL;
+}
+
+
+
+static void
+tex_open_terminal_activated (GtkAction *action,
+                             GtkWidget *window)
+{
+  const gchar *path;
+  GtkWidget   *dialog;
+  GError      *error = NULL;
+  gchar       *command;
+
+  /* determine the folder path */
+  path = g_object_get_data (G_OBJECT (action), "open-terminal-here-path");
+  if (G_UNLIKELY (path == NULL))
+    return;
+  
+  /* build up the command line for the terminal */
+  command = g_strdup_printf ("Terminal --working-directory \"%s\"", path);
+
+  /* try to run the terminal command */
+  if (!gdk_spawn_command_line_on_screen (gtk_widget_get_screen (window), command, &error))
+    {
+      /* display an error dialog */
+      dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                       GTK_DIALOG_DESTROY_WITH_PARENT,
+                                       GTK_MESSAGE_ERROR,
+                                       GTK_BUTTONS_CLOSE,
+                                       "Failed to open terminal in folder %s.",
+                                       path);
+      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s.", error->message);
+      gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_widget_destroy (dialog);
+      g_error_free (error);
+    }
+
+  /* cleanup */
+  g_free (command);
+}
+
+
diff --git a/examples/tex-open-terminal/tex-open-terminal.h b/examples/tex-open-terminal/tex-open-terminal.h
new file mode 100644 (file)
index 0000000..0d630a3
--- /dev/null
@@ -0,0 +1,43 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __TEX_OPEN_TERMINAL_H__
+#define __TEX_OPEN_TERMINAL_H__
+
+#include <thunarx/thunarx.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _TexOpenTerminalClass TexOpenTerminalClass;
+typedef struct _TexOpenTerminal      TexOpenTerminal;
+
+#define TEX_TYPE_OPEN_TERMINAL            (tex_open_terminal_get_type ())
+#define TEX_OPEN_TERMINAL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEX_TYPE_OPEN_TERMINAL, TexOpenTerminal))
+#define TEX_OPEN_TERMINAL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TEX_TYPE_OPEN_TERMINAL, TexOpenTerminalClass))
+#define TEX_IS_OPEN_TERMINAL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEX_TYPE_OPEN_TERMINAL))
+#define TEX_IS_OPEN_TERMINAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEX_TYPE_OPEN_TERMINAL))
+#define TEX_OPEN_TERMINAL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TEX_TYPE_OPEN_TERMINAL, TexOpenTerminalClass))
+
+GType tex_open_terminal_get_type      (void) G_GNUC_CONST G_GNUC_INTERNAL;
+void  tex_open_terminal_register_type (ThunarxProviderPlugin *plugin) G_GNUC_INTERNAL;
+
+G_END_DECLS;
+
+#endif /* !__TEX_OPEN_TERMINAL_H__ */
index b514dfe..72ef6df 100644 (file)
@@ -38,7 +38,6 @@ thunar/thunar-details-view.c
 thunar/thunar-dialogs.c
 thunar/thunar-dnd.c
 thunar/thunar-emblem-chooser.c
-thunar/thunar-extension-manager.c
 thunar/thunar-favourites-model.c
 thunar/thunar-favourites-pane.c
 thunar/thunar-favourites-view.c
@@ -73,5 +72,6 @@ thunar/thunar-view.c
 thunar/thunar-window.c
 
 thunarx/thunarx-property-page.c
+thunarx/thunarx-provider-plugin.c
 
 Thunar.desktop.in
index e8dd6eb..83d3329 100644 (file)
@@ -42,8 +42,6 @@ Thunar_SOURCES =                                                      \
        thunar-dnd.h                                                    \
        thunar-emblem-chooser.c                                         \
        thunar-emblem-chooser.h                                         \
-       thunar-extension-manager.c                                      \
-       thunar-extension-manager.h                                      \
        thunar-fallback-icon.c                                          \
        thunar-fallback-icon.h                                          \
        thunar-favourites-model.c                                       \
diff --git a/thunar/thunar-extension-manager.c b/thunar/thunar-extension-manager.c
deleted file mode 100644 (file)
index 573bb19..0000000
+++ /dev/null
@@ -1,488 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gmodule.h>
-
-#include <exo/exo.h>
-
-#include <thunar/thunar-extension-manager.h>
-
-
-
-#define THUNAR_EXTENSIONS_DIRECTORY (LIBDIR G_DIR_SEPARATOR_S "thunarx-" THUNAR_VERSION_API)
-
-
-
-enum
-{
-  PROP_0,
-  PROP_RESIDENT,
-};
-
-
-
-typedef struct _ThunarExtensionClass ThunarExtensionClass;
-typedef struct _ThunarExtension      ThunarExtension;
-
-
-
-#define THUNAR_TYPE_EXTENSION             (thunar_extension_get_type ())
-#define THUNAR_EXTENSION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_EXTENSION, ThunarExtension))
-#define THUNAR_EXTENSION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_EXTENSION, ThunarExtensionClass))
-#define THUNAR_IS_EXTENSION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_EXTENSION))
-#define THUNAR_IS_EXTENSION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_EXTENSION))
-#define THUNAR_EXTENSION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_EXTENSION, ThunarExtensionClass))
-
-
-
-static GType    thunar_extension_get_type     (void) G_GNUC_CONST;
-static void     thunar_extension_class_init   (ThunarExtensionClass *klass);
-static void     thunar_extension_finalize     (GObject              *object);
-static void     thunar_extension_get_property (GObject              *object,
-                                               guint                 prop_id,
-                                               GValue               *value,
-                                               GParamSpec           *pspec);
-static void     thunar_extension_set_property (GObject              *object,
-                                               guint                 prop_id,
-                                               const GValue         *value,
-                                               GParamSpec           *pspec);
-static gboolean thunar_extension_load         (GTypeModule          *module);
-static void     thunar_extension_unload       (GTypeModule          *module);
-static void     thunar_extension_list_types   (ThunarExtension      *extension,
-                                               const GType         **types,
-                                               gint                 *n_types);
-
-
-
-struct _ThunarExtensionClass
-{
-  GTypeModuleClass __parent__;
-};
-
-struct _ThunarExtension
-{
-  GTypeModule __parent__;
-
-  gchar   *path;
-  GModule *module;
-  gboolean resident;
-
-  void (*initialize)  (GTypeModule  *module);
-  void (*shutdown)    (void);
-  void (*list_types)  (const GType **types,
-                       gint         *n_types);
-};
-
-
-
-static GObjectClass *thunar_extension_parent_class;
-
-
-
-static GType
-thunar_extension_get_type (void)
-{
-  static GType type = G_TYPE_INVALID;
-
-  if (G_UNLIKELY (type == G_TYPE_INVALID))
-    {
-      static const GTypeInfo info =
-      {
-        sizeof (ThunarExtensionClass),
-        NULL,
-        NULL,
-        (GClassInitFunc) thunar_extension_class_init,
-        NULL,
-        NULL,
-        sizeof (ThunarExtension),
-        0,
-        NULL,
-        NULL,
-      };
-
-      type = g_type_register_static (G_TYPE_TYPE_MODULE, "ThunarExtension", &info, 0);
-    }
-
-  return type;
-}
-
-
-
-static void
-thunar_extension_class_init (ThunarExtensionClass *klass)
-{
-  GTypeModuleClass *gtype_module_class;
-  GObjectClass     *gobject_class;
-
-  /* determine the parent class */
-  thunar_extension_parent_class = g_type_class_peek_parent (klass);
-
-  gobject_class = G_OBJECT_CLASS (klass);
-  gobject_class->finalize = thunar_extension_finalize;
-  gobject_class->get_property = thunar_extension_get_property;
-  gobject_class->set_property = thunar_extension_set_property;
-
-  gtype_module_class = G_TYPE_MODULE_CLASS (klass);
-  gtype_module_class->load = thunar_extension_load;
-  gtype_module_class->unload = thunar_extension_unload;
-
-  /**
-   * ThunarExtension::resident:
-   *
-   * Tells whether the extension must reside in memory once loaded
-   * for the first time.
-   **/
-  g_object_class_install_property (gobject_class,
-                                   PROP_RESIDENT,
-                                   g_param_spec_boolean ("resident",
-                                                         _("Resident"),
-                                                         _("Ensures that an extension will never be unloaded."),
-                                                         FALSE,
-                                                         EXO_PARAM_READWRITE));
-}
-
-
-
-static void
-thunar_extension_finalize (GObject *object)
-{
-  ThunarExtension *extension = THUNAR_EXTENSION (object);
-
-  /* free the path to the extension */
-  g_free (extension->path);
-
-  (*G_OBJECT_CLASS (thunar_extension_parent_class)->finalize) (object);
-}
-
-
-
-static void
-thunar_extension_get_property (GObject    *object,
-                               guint       prop_id,
-                               GValue     *value,
-                               GParamSpec *pspec)
-{
-  ThunarExtension *extension = THUNAR_EXTENSION (object);
-
-  switch (prop_id)
-    {
-    case PROP_RESIDENT:
-      g_value_set_boolean (value, extension->resident);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
-
-
-
-static void
-thunar_extension_set_property (GObject      *object,
-                               guint         prop_id,
-                               const GValue *value,
-                               GParamSpec   *pspec)
-{
-  ThunarExtension *extension = THUNAR_EXTENSION (object);
-
-  switch (prop_id)
-    {
-    case PROP_RESIDENT:
-      extension->resident = g_value_get_boolean (value);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
-
-
-
-static gboolean
-thunar_extension_load (GTypeModule *module)
-{
-  ThunarExtension *extension = THUNAR_EXTENSION (module);
-
-  /* load the extension using the runtime link editor */
-  extension->module = g_module_open (extension->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
-
-  /* check if the load operation was successful */
-  if (G_UNLIKELY (extension->module == NULL))
-    {
-      g_warning ("Failed to load file manager extension from %s: %s", extension->path, g_module_error ());
-      return FALSE;
-    }
-
-  /* verify that all required public symbols are present in the extension's symbol table */
-  if (!g_module_symbol (extension->module, "thunar_extension_shutdown", (gpointer) &extension->shutdown)
-      || !g_module_symbol (extension->module, "thunar_extension_initialize", (gpointer) &extension->initialize)
-      || !g_module_symbol (extension->module, "thunar_extension_list_types", (gpointer) &extension->list_types))
-    {
-      g_warning ("File manager extension loaded from %s lacks required symbols.", extension->path);
-      g_module_close (extension->module);
-      return FALSE;
-    }
-
-  /* initialize the extension */
-  (*extension->initialize) (module);
-
-  /* ensure that the module will never be unloaded
-   * if the extension requests to be kept in memory
-   */
-  if (G_UNLIKELY (extension->resident))
-    g_module_make_resident (extension->module);
-
-  return TRUE;
-}
-
-
-
-static void
-thunar_extension_unload (GTypeModule *module)
-{
-  ThunarExtension *extension = THUNAR_EXTENSION (module);
-
-  /* shutdown the extension */
-  (*extension->shutdown) ();
-
-  /* unload the extension from memory */
-  g_module_close (extension->module);
-
-  /* reset extension state */
-  extension->module = NULL;
-  extension->shutdown = NULL;
-  extension->initialize = NULL;
-  extension->list_types = NULL;
-}
-
-
-
-static void
-thunar_extension_list_types (ThunarExtension *extension,
-                             const GType    **types,
-                             gint            *n_types)
-{
-  g_return_if_fail (THUNAR_IS_EXTENSION (extension));
-  g_return_if_fail (n_types != NULL);
-  g_return_if_fail (types != NULL);
-
-  (*extension->list_types) (types, n_types);
-}
-
-
-
-
-static void thunar_extension_manager_class_init (ThunarExtensionManagerClass *klass);
-static void thunar_extension_manager_init       (ThunarExtensionManager      *manager);
-static void thunar_extension_manager_finalize   (GObject                     *object);
-static void thunar_extension_manager_add        (ThunarExtensionManager      *manager,
-                                                 ThunarExtension             *extension);
-
-
-
-struct _ThunarExtensionManagerClass
-{
-  GObjectClass __parent__;
-};
-
-struct _ThunarExtensionManager
-{
-  GObject __parent__;
-
-  GList *extensions;
-
-  GType *types;
-  gint   n_types;
-};
-
-
-
-G_DEFINE_TYPE (ThunarExtensionManager, thunar_extension_manager, G_TYPE_OBJECT);
-
-
-
-static void
-thunar_extension_manager_class_init (ThunarExtensionManagerClass *klass)
-{
-  GObjectClass *gobject_class;
-
-  gobject_class = G_OBJECT_CLASS (klass);
-  gobject_class->finalize = thunar_extension_manager_finalize;
-}
-
-
-
-static void
-thunar_extension_manager_init (ThunarExtensionManager *manager)
-{
-  ThunarExtension *extension;
-  const gchar     *name;
-  GDir            *dp;
-
-  // FIXME: Perform this in a timer as the extensions aren't required to
-  // be available instantly, maybe even load the files in a separate thread!
-  dp = g_dir_open (THUNAR_EXTENSIONS_DIRECTORY, 0, NULL);
-  if (G_LIKELY (dp != NULL))
-    {
-      /* determine the types for all existing extensions */
-      for (;;)
-        {
-          /* read the next entry from the directory */
-          name = g_dir_read_name (dp);
-          if (G_UNLIKELY (name == NULL))
-            break;
-
-          /* check if this is a valid extension file */
-          if (g_str_has_suffix (name, "." G_MODULE_SUFFIX))
-            {
-              /* generate an extension object for the file */
-              extension = g_object_new (THUNAR_TYPE_EXTENSION, NULL);
-              extension->path = g_build_filename (THUNAR_EXTENSIONS_DIRECTORY, name, NULL);
-
-              /* try to load the extension */
-              if (g_type_module_use (G_TYPE_MODULE (extension)))
-                {
-                  /* add the extension to our list of managed extensions */
-                  thunar_extension_manager_add (manager, extension);
-
-                  /* don't unuse the type plugin if it should be resident in memory */
-                  if (G_LIKELY (!extension->resident))
-                    g_type_module_unuse (G_TYPE_MODULE (extension));
-                }
-
-              /* drop the reference on the extension */
-              g_object_unref (G_OBJECT (extension));
-            }
-        }
-
-      g_dir_close (dp);
-    }
-}
-
-
-
-static void
-thunar_extension_manager_finalize (GObject *object)
-{
-  ThunarExtensionManager *manager = THUNAR_EXTENSION_MANAGER (object);
-
-  /* release the extensions */
-  g_list_foreach (manager->extensions, (GFunc) g_object_unref, NULL);
-  g_list_free (manager->extensions);
-
-  /* free the types list */
-  g_free (manager->types);
-
-  (*G_OBJECT_CLASS (thunar_extension_manager_parent_class)->finalize) (object);
-}
-
-
-
-static void
-thunar_extension_manager_add (ThunarExtensionManager *manager,
-                              ThunarExtension        *extension)
-{
-  const GType *types;
-  gint         n_types;
-
-  /* add the extension to our internal list */
-  manager->extensions = g_list_prepend (manager->extensions, g_object_ref (G_OBJECT (extension)));
-
-  /* determines the types provided by the extension */
-  thunar_extension_list_types (extension, &types, &n_types);
-
-  /* add the types provided by the extension */
-  manager->types = g_realloc (manager->types, sizeof (GType) * (manager->n_types + n_types));
-  for (; n_types-- > 0; ++types)
-    manager->types[manager->n_types++] = *types;
-}
-
-
-
-/**
- * thunar_extension_manager_get_default:
- *
- * Returns a reference to the default #ThunarExtensionManager
- * instance.
- *
- * The caller is responsible to free the returned object
- * using g_object_unref() when no longer needed.
- *
- * Return value: a reference to the default
- *               #ThunarExtensionManager instance.
- **/
-ThunarExtensionManager*
-thunar_extension_manager_get_default (void)
-{
-  static ThunarExtensionManager *manager = NULL;
-
-  if (G_UNLIKELY (manager == NULL))
-    manager = g_object_new (THUNAR_TYPE_EXTENSION_MANAGER, NULL);
-
-  g_object_ref (G_OBJECT (manager));
-
-  return manager;
-}
-
-
-
-/**
- * thunar_extension_manager_list_providers:
- * @manager : a #ThunarExtensionManager instance.
- * @type    : the provider #GType.
- *
- * Returns all providers of the given @type.
- *
- * The caller is responsible to release the returned
- * list of providers using code like this:
- * <informalexample><programlisting>
- * g_list_foreach (list, (GFunc) g_object_unref, NULL);
- * g_list_free (list);
- * </programlisting></informalexample>
- *
- * Return value: the of providers for @type.
- **/
-GList*
-thunar_extension_manager_list_providers (ThunarExtensionManager *manager,
-                                         GType                   type)
-{
-  GObject *provider;
-  GList   *providers = NULL;
-  GType   *types;
-  gint     n;
-
-  for (n = manager->n_types, types = manager->types; n > 0; --n, ++types)
-    if (G_LIKELY (g_type_is_a (*types, type)))
-      {
-        provider = g_object_new (*types, NULL);
-        if (G_LIKELY (provider != NULL))
-          providers = g_list_append (providers, provider);
-      }
-
-  return providers;
-}
-
-
-
diff --git a/thunar/thunar-extension-manager.h b/thunar/thunar-extension-manager.h
deleted file mode 100644 (file)
index c8edef8..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __THUNAR_EXTENSION_MANAGER_H__
-#define __THUNAR_EXTENSION_MANAGER_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS;
-
-typedef struct _ThunarExtensionManagerClass ThunarExtensionManagerClass;
-typedef struct _ThunarExtensionManager      ThunarExtensionManager;
-
-#define THUNAR_TYPE_EXTENSION_MANAGER             (thunar_extension_manager_get_type ())
-#define THUNAR_EXTENSION_MANAGER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_EXTENSION_MANAGER, ThunarExtensionManager))
-#define THUNAR_EXTENSION_MANAGER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_EXTENSION_MANAGER, ThunarExtensionManagerClass))
-#define THUNAR_IS_EXTENSION_MANAGER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_EXTENSION_MANAGER))
-#define THUNAR_IS_EXTENSION_MANAGER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_EXTENSION_MANAGER))
-#define THUNAR_EXTENSION_MANAGER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_EXTENSION_MANAGER, ThunarExtensionManagerClass))
-
-GType                   thunar_extension_manager_get_type       (void) G_GNUC_CONST;
-
-ThunarExtensionManager *thunar_extension_manager_get_default    (void);
-
-GList                  *thunar_extension_manager_list_providers (ThunarExtensionManager *manager,
-                                                                 GType                   type);
-
-G_END_DECLS;
-
-#endif /* !__THUNAR_EXTENSION_MANAGER_H__ */
index fd16ce3..292ac54 100644 (file)
@@ -36,8 +36,6 @@
 
 #include <thunar/thunar-file.h>
 
-#include <thunarx/thunarx.h>
-
 
 
 /* Additional flags associated with a ThunarFile */
@@ -1703,37 +1701,4 @@ thunar_file_cache_lookup (const ThunarVfsPath *path)
 
 
 
-/**
- * thunar_file_list_copy:
- * @file_list : a list of #ThunarFile<!---->s.
- *
- * Returns a deep-copy of @file_list, which must be
- * freed using thunar_file_list_free().
- *
- * Return value: a deep copy of @file_list.
- **/
-GList*
-thunar_file_list_copy (const GList *file_list)
-{
-  GList *list = g_list_copy ((GList *) file_list);
-  g_list_foreach (list, (GFunc) g_object_ref, NULL);
-  return list;
-}
-
-
-
-/**
- * thunar_file_list_free:
- * @file_list : a list of #ThunarFile<!---->s.
- *
- * Unrefs the #ThunarFile<!---->s contained in @file_list
- * and frees the list itself.
- **/
-void
-thunar_file_list_free (GList *file_list)
-{
-  g_list_foreach (file_list, (GFunc) g_object_unref, NULL);
-  g_list_free (file_list);
-}
-
 
index 2b7063d..3d8912f 100644 (file)
@@ -21,6 +21,7 @@
 #define __THUNAR_FILE_H__
 
 #include <thunar/thunar-metafile.h>
+#include <thunarx/thunarx.h>
 
 G_BEGIN_DECLS;
 
@@ -211,8 +212,8 @@ static inline void                 thunar_file_set_thumb_state (ThunarFile
                                                                 ThunarFileThumbState thumb_state);
 
 
-GList *thunar_file_list_copy (const GList *file_list);
-void   thunar_file_list_free (GList       *file_list);
+static inline GList *thunar_file_list_copy (GList *file_list);
+static inline void   thunar_file_list_free (GList *file_list);
 
 
 /**
@@ -515,6 +516,36 @@ thunar_file_set_thumb_state (ThunarFile          *file,
 }
 
 
+
+/**
+ * thunar_file_list_copy:
+ * @file_list : a list of #ThunarFile<!---->s.
+ *
+ * Returns a deep-copy of @file_list, which must be
+ * freed using thunar_file_list_free().
+ *
+ * Return value: a deep copy of @file_list.
+ **/
+static inline GList*
+thunar_file_list_copy (GList *file_list)
+{
+  return thunarx_file_info_list_copy (file_list);
+}
+
+/**
+ * thunar_file_list_free:
+ * @file_list : a list of #ThunarFile<!---->s.
+ *
+ * Unrefs the #ThunarFile<!---->s contained in @file_list
+ * and frees the list itself.
+ **/
+static inline void
+thunar_file_list_free (GList *file_list)
+{
+  thunarx_file_info_list_free (file_list);
+}
+
+
 G_END_DECLS;
 
 #endif /* !__THUNAR_FILE_H__ */
index b2e2221..7a0f73f 100644 (file)
 
 #include <thunar/thunar-dialogs.h>
 #include <thunar/thunar-emblem-chooser.h>
-#include <thunar/thunar-extension-manager.h>
 #include <thunar/thunar-icon-factory.h>
 #include <thunar/thunar-properties-dialog.h>
 
-#include <thunarx/thunarx.h>
-
 
 
 enum
@@ -70,7 +67,7 @@ static gboolean thunar_properties_dialog_focus_out_event      (GtkWidget
                                                                GdkEventFocus               *event,
                                                                ThunarPropertiesDialog      *dialog);
 static void     thunar_properties_dialog_update               (ThunarPropertiesDialog      *dialog);
-static void     thunar_properties_dialog_update_extensions    (ThunarPropertiesDialog      *dialog);
+static void     thunar_properties_dialog_update_providers     (ThunarPropertiesDialog      *dialog);
 static gboolean thunar_properties_dialog_rename_idle          (gpointer                     user_data);
 static void     thunar_properties_dialog_rename_idle_destroy  (gpointer                     user_data);
 
@@ -85,8 +82,8 @@ struct _ThunarPropertiesDialog
 {
   GtkDialog __parent__;
 
-  ThunarExtensionManager *extension_manager;
-  GList                  *extension_pages;
+  ThunarxProviderFactory *provider_factory;
+  GList                  *provider_pages;
 
   ThunarVfsVolumeManager *volume_manager;
   ThunarFile             *file;
@@ -158,7 +155,7 @@ thunar_properties_dialog_init (ThunarPropertiesDialog *dialog)
   gchar     *text;
   gint       row = 0;
 
-  dialog->extension_manager = thunar_extension_manager_get_default ();
+  dialog->provider_factory = thunarx_provider_factory_get_default ();
   dialog->volume_manager = thunar_vfs_volume_manager_get_default ();
   dialog->rename_idle_id = -1;
 
@@ -356,12 +353,12 @@ thunar_properties_dialog_finalize (GObject *object)
 {
   ThunarPropertiesDialog *dialog = THUNAR_PROPERTIES_DIALOG (object);
 
-  /* release the extension property pages */
-  g_list_foreach (dialog->extension_pages, (GFunc) g_object_unref, NULL);
-  g_list_free (dialog->extension_pages);
+  /* release the provider property pages */
+  g_list_foreach (dialog->provider_pages, (GFunc) g_object_unref, NULL);
+  g_list_free (dialog->provider_pages);
 
-  /* drop the reference on the extension manager */
-  g_object_unref (G_OBJECT (dialog->extension_manager));
+  /* drop the reference on the provider factory */
+  g_object_unref (G_OBJECT (dialog->provider_factory));
 
   /* drop the reference on the volume manager */
   g_object_unref (G_OBJECT (dialog->volume_manager));
@@ -480,7 +477,7 @@ thunar_properties_dialog_focus_out_event (GtkWidget              *entry,
 
 
 static void
-thunar_properties_dialog_update_extensions (ThunarPropertiesDialog *dialog)
+thunar_properties_dialog_update_providers (ThunarPropertiesDialog *dialog)
 {
   GtkWidget *label_widget;
   GList     *providers;
@@ -489,8 +486,8 @@ thunar_properties_dialog_update_extensions (ThunarPropertiesDialog *dialog)
   GList     *tmp;
   GList     *lp;
 
-  /* load the property page providers from the extension manager */
-  providers = thunar_extension_manager_list_providers (dialog->extension_manager, THUNARX_TYPE_PROPERTY_PAGE_PROVIDER);
+  /* load the property page providers from the provider factory */
+  providers = thunarx_provider_factory_list_providers (dialog->provider_factory, THUNARX_TYPE_PROPERTY_PAGE_PROVIDER);
   if (G_LIKELY (providers != NULL))
     {
       /* determine the (one-element) file list */
@@ -507,15 +504,15 @@ thunar_properties_dialog_update_extensions (ThunarPropertiesDialog *dialog)
     }
 
   /* destroy any previous set pages */
-  for (lp = dialog->extension_pages; lp != NULL; lp = lp->next)
+  for (lp = dialog->provider_pages; lp != NULL; lp = lp->next)
     {
       gtk_widget_destroy (GTK_WIDGET (lp->data));
       g_object_unref (G_OBJECT (lp->data));
     }
-  g_list_free (dialog->extension_pages);
+  g_list_free (dialog->provider_pages);
 
   /* apply the new set of pages */
-  dialog->extension_pages = pages;
+  dialog->provider_pages = pages;
   for (lp = pages; lp != NULL; lp = lp->next)
     {
       label_widget = thunarx_property_page_get_label_widget (THUNARX_PROPERTY_PAGE (lp->data));
@@ -652,8 +649,8 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog)
       gtk_widget_hide (dialog->size_label);
     }
 
-  /* update the extension property pages */
-  thunar_properties_dialog_update_extensions (dialog);
+  /* update the provider property pages */
+  thunar_properties_dialog_update_providers (dialog);
 
   /* cleanup */
   g_object_unref (G_OBJECT (icon_factory));
index 6efcc53..148c13f 100644 (file)
@@ -34,7 +34,6 @@
 #include <thunar/thunar-create-dialog.h>
 #include <thunar/thunar-dialogs.h>
 #include <thunar/thunar-dnd.h>
-#include <thunar/thunar-extension-manager.h>
 #include <thunar/thunar-icon-renderer.h>
 #include <thunar/thunar-launcher.h>
 #include <thunar/thunar-marshal.h>
@@ -43,8 +42,6 @@
 #include <thunar/thunar-standard-view-ui.h>
 #include <thunar/thunar-text-renderer.h>
 
-#include <thunarx/thunarx.h>
-
 
 
 #define THUNAR_STANDARD_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_TYPE_STANDARD_VIEW, ThunarStandardViewPrivate))
@@ -225,7 +222,7 @@ struct _ThunarStandardViewPrivate
   GtkAction              *action_rename;
 
   /* support for file manager extensions */
-  ThunarExtensionManager *extension_manager;
+  ThunarxProviderFactory *provider_factory;
 
   /* custom menu actions support */
   GtkActionGroup         *custom_actions;
@@ -437,8 +434,8 @@ thunar_standard_view_init (ThunarStandardView *standard_view)
   /* grab a reference on the preferences */
   standard_view->preferences = thunar_preferences_get ();
 
-  /* grab a reference on the extension manager */
-  standard_view->priv->extension_manager = thunar_extension_manager_get_default ();
+  /* grab a reference on the provider factory */
+  standard_view->priv->provider_factory = thunarx_provider_factory_get_default ();
 
   /* initialize the scrolled window */
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (standard_view),
@@ -578,8 +575,8 @@ thunar_standard_view_finalize (GObject *object)
   g_assert (standard_view->ui_manager == NULL);
   g_assert (standard_view->clipboard == NULL);
 
-  /* release our reference on the extension manager */
-  g_object_unref (G_OBJECT (standard_view->priv->extension_manager));
+  /* release our reference on the provider factory */
+  g_object_unref (G_OBJECT (standard_view->priv->provider_factory));
 
   /* release the drag path list (just in case the drag-end wasn't fired before) */
   thunar_vfs_path_list_free (standard_view->priv->drag_path_list);
@@ -1184,8 +1181,8 @@ thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view,
   /* determine the toplevel window we belong to */
   window = gtk_widget_get_toplevel (GTK_WIDGET (standard_view));
 
-  /* load the menu providers from the extension manager */
-  providers = thunar_extension_manager_list_providers (standard_view->priv->extension_manager, THUNARX_TYPE_MENU_PROVIDER);
+  /* load the menu providers from the provider factory */
+  providers = thunarx_provider_factory_list_providers (standard_view->priv->provider_factory, THUNARX_TYPE_MENU_PROVIDER);
   if (G_LIKELY (providers != NULL))
     {
       /* determine the list of selected files or the current folder */
index 56dbb18..1c1bad2 100644 (file)
@@ -4,6 +4,7 @@ INCLUDES =                                                              \
        -I$(top_srcdir)                                                 \
        -DG_LOG_DOMAIN=\"thunarx\"                                      \
        -DTHUNARX_COMPILATION                                           \
+       -DTHUNARX_DIRECTORY=\"$(libdir)/thunarx-$(THUNAR_VERSION_API)\" \
        $(PLATFORM_CPPFLAGS)
 
 libthunarx_built_sources =                                             \
@@ -16,7 +17,9 @@ libthunarx_headers =                                                  \
        thunarx-file-info.h                                             \
        thunarx-menu-provider.h                                         \
        thunarx-property-page.h                                         \
-       thunarx-property-page-provider.h
+       thunarx-property-page-provider.h                                \
+       thunarx-provider-factory.h                                      \
+       thunarx-provider-plugin.h
 
 libthunarx_includedir =                                                        \
        $(includedir)/thunarx-$(THUNAR_VERSION_API)/thunarx
@@ -34,7 +37,11 @@ libthunarx_1_la_SOURCES =                                            \
        thunarx-file-info.c                                             \
        thunarx-menu-provider.c                                         \
        thunarx-property-page.c                                         \
-       thunarx-property-page-provider.c
+       thunarx-property-page-provider.c                                \
+       thunarx-provider-factory.c                                      \
+       thunarx-provider-module.c                                       \
+       thunarx-provider-module.h                                       \
+       thunarx-provider-plugin.c
 
 libthunarx_1_la_CFLAGS =                                               \
        $(GTK_CFLAGS)                                                   \
diff --git a/thunarx/thunarx-provider-factory.c b/thunarx/thunarx-provider-factory.c
new file mode 100644 (file)
index 0000000..a9105d0
--- /dev/null
@@ -0,0 +1,302 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gdk/gdk.h>
+
+#include <thunarx/thunarx-provider-factory.h>
+#include <thunarx/thunarx-provider-module.h>
+#include <thunarx/thunarx-provider-plugin.h>
+#include <thunarx/thunarx-alias.h>
+
+
+
+/* "provider cache" cleanup interval (in ms) */
+#define THUNARX_PROVIDER_FACTORY_INTERVAL (60 * 1000)
+
+
+
+static void     thunarx_provider_factory_class_init     (ThunarxProviderFactoryClass *klass);
+static void     thunarx_provider_factory_init           (ThunarxProviderFactory      *manager);
+static void     thunarx_provider_factory_finalize       (GObject                     *object);
+static void     thunarx_provider_factory_add            (ThunarxProviderFactory      *manager,
+                                                         ThunarxProviderModule       *module);
+static gboolean thunarx_provider_factory_timer          (gpointer                     user_data);
+static void     thunarx_provider_factory_timer_destroy  (gpointer                     user_data);
+
+
+
+typedef struct
+{
+  GObject *provider;  /* cached provider reference or %NULL */
+  GType    type;      /* provider GType */
+} ThunarxProviderInfo;
+
+struct _ThunarxProviderFactoryClass
+{
+  GObjectClass __parent__;
+};
+
+struct _ThunarxProviderFactory
+{
+  GObject __parent__;
+
+  GList               *modules;   /* the list of provider modules */
+
+  ThunarxProviderInfo *infos;     /* provider types and cached provider references */
+  gint                 n_infos;   /* number of items in the infos array */
+
+  gint                 timer_id;  /* GSource timer to cleanup cached providers */
+};
+
+
+
+G_DEFINE_TYPE (ThunarxProviderFactory, thunarx_provider_factory, G_TYPE_OBJECT);
+
+
+
+static void
+thunarx_provider_factory_class_init (ThunarxProviderFactoryClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunarx_provider_factory_finalize;
+}
+
+
+
+static void
+thunarx_provider_factory_init (ThunarxProviderFactory *factory)
+{
+  ThunarxProviderModule *module;
+  const gchar           *name;
+  GDir                  *dp;
+
+  dp = g_dir_open (THUNARX_DIRECTORY, 0, NULL);
+  if (G_LIKELY (dp != NULL))
+    {
+      /* determine the types for all existing plugins */
+      for (;;)
+        {
+          /* read the next entry from the directory */
+          name = g_dir_read_name (dp);
+          if (G_UNLIKELY (name == NULL))
+            break;
+
+          /* check if this is a valid plugin file */
+          if (g_str_has_suffix (name, "." G_MODULE_SUFFIX))
+            {
+              /* allocate a new module for the file */
+              module = thunarx_provider_module_new (name);
+
+              /* try to load the module */
+              if (g_type_module_use (G_TYPE_MODULE (module)))
+                {
+                  /* add the module to our list of managed modules */
+                  thunarx_provider_factory_add (factory, module);
+
+                  /* don't unuse the type plugin if it should be resident in memory */
+                  if (G_LIKELY (!thunarx_provider_plugin_get_resident (THUNARX_PROVIDER_PLUGIN (module))))
+                    g_type_module_unuse (G_TYPE_MODULE (module));
+                }
+              else
+                {
+                  /* drop the reference on the module */
+                  g_object_unref (G_OBJECT (module));
+                }
+            }
+        }
+
+      g_dir_close (dp);
+    }
+
+  /* start the "provider cache" cleanup timer */
+  factory->timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNARX_PROVIDER_FACTORY_INTERVAL,
+                                          thunarx_provider_factory_timer, factory,
+                                          thunarx_provider_factory_timer_destroy);
+}
+
+
+
+static void
+thunarx_provider_factory_finalize (GObject *object)
+{
+  ThunarxProviderFactory *factory = THUNARX_PROVIDER_FACTORY (object);
+  gint                    n;
+
+  /* stop the "provider cache" cleanup timer */
+  if (G_LIKELY (factory->timer_id >= 0))
+    g_source_remove (factory->timer_id);
+
+  /* release provider infos */
+  for (n = 0; n < factory->n_infos; ++n)
+    if (factory->infos[n].provider != NULL)
+      g_object_unref (factory->infos[n].provider);
+  g_free (factory->infos);
+
+  /* release the modules */
+  g_list_foreach (factory->modules, (GFunc) g_object_unref, NULL);
+  g_list_free (factory->modules);
+
+  (*G_OBJECT_CLASS (thunarx_provider_factory_parent_class)->finalize) (object);
+}
+
+
+
+static void
+thunarx_provider_factory_add (ThunarxProviderFactory *factory,
+                              ThunarxProviderModule  *module)
+{
+  const GType *types;
+  gint         n_types;
+
+  /* add the module to our internal list */
+  factory->modules = g_list_prepend (factory->modules, module);
+
+  /* determines the types provided by the module */
+  thunarx_provider_module_list_types (module, &types, &n_types);
+
+  /* add the types provided by the extension */
+  factory->infos = g_realloc (factory->infos, sizeof (ThunarxProviderInfo) * (factory->n_infos + n_types));
+  for (; n_types-- > 0; ++types)
+    {
+      factory->infos[factory->n_infos].provider = NULL;
+      factory->infos[factory->n_infos].type = *types;
+      ++factory->n_infos;
+    }
+}
+
+
+
+static gboolean
+thunarx_provider_factory_timer (gpointer user_data)
+{
+  ThunarxProviderFactory *factory = THUNARX_PROVIDER_FACTORY (user_data);
+  ThunarxProviderInfo    *info;
+  gint                    n;
+
+  GDK_THREADS_ENTER ();
+
+  /* drop all providers for which only we keep a reference */
+  for (n = factory->n_infos; --n >= 0; )
+    {
+      info = factory->infos + n;
+      if (info->provider != NULL && info->provider->ref_count == 1)
+        {
+          g_object_unref (info->provider);
+          info->provider = NULL;
+        }
+    }
+
+  GDK_THREADS_LEAVE ();
+
+  return TRUE;
+}
+
+
+
+static void
+thunarx_provider_factory_timer_destroy (gpointer user_data)
+{
+  THUNARX_PROVIDER_FACTORY (user_data)->timer_id = -1;
+}
+
+
+
+/**
+ * thunarx_provider_factory_get_default:
+ *
+ * Returns a reference to the default #ThunarxProviderFactory
+ * instance.
+ *
+ * The caller is responsible to free the returned object
+ * using g_object_unref() when no longer needed.
+ *
+ * Return value: a reference to the default
+ *               #ThunarxProviderFactory instance.
+ **/
+ThunarxProviderFactory*
+thunarx_provider_factory_get_default (void)
+{
+  static ThunarxProviderFactory *default_factory = NULL;
+
+  /* allocate the default factory instance on-demand */
+  if (G_UNLIKELY (default_factory == NULL))
+    default_factory = g_object_new (THUNARX_TYPE_PROVIDER_FACTORY, NULL);
+
+  /* take a reference on the default factory for the caller */
+  return g_object_ref (G_OBJECT (default_factory));
+}
+
+
+
+/**
+ * thunarx_provider_factory_list_providers:
+ * @factory : a #ThunarxProviderFactory instance.
+ * @type    : the provider #GType.
+ *
+ * Returns all providers of the given @type.
+ *
+ * The caller is responsible to release the returned
+ * list of providers using code like this:
+ * <informalexample><programlisting>
+ * g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ * g_list_free (list);
+ * </programlisting></informalexample>
+ *
+ * Return value: the of providers for @type.
+ **/
+GList*
+thunarx_provider_factory_list_providers (ThunarxProviderFactory *factory,
+                                         GType                   type)
+{
+  ThunarxProviderInfo *info;
+  GList               *providers = NULL;
+  gint                 n;
+
+  for (info = factory->infos, n = factory->n_infos; --n >= 0; ++info)
+    if (G_LIKELY (g_type_is_a (info->type, type)))
+      {
+        /* allocate the provider on-demand */
+        if (G_UNLIKELY (info->provider == NULL))
+          {
+            info->provider = g_object_new (info->type, NULL);
+            if (G_UNLIKELY (info->provider == NULL))
+              continue;
+          }
+
+        /* take a reference for the caller */
+        g_object_ref (info->provider);
+
+        /* add the provider to the result list */
+        providers = g_list_append (providers, info->provider);
+      }
+
+  return providers;
+}
+
+
+
+#define __THUNARX_PROVIDER_FACTORY_C__
+#include <thunarx/thunarx-aliasdef.c>
diff --git a/thunarx/thunarx-provider-factory.h b/thunarx/thunarx-provider-factory.h
new file mode 100644 (file)
index 0000000..bc6fd26
--- /dev/null
@@ -0,0 +1,51 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined(THUNARX_INSIDE_THUNARX_H) && !defined(THUNARX_COMPILATION)
+#error "Only <thunarx/thunarx.h> can be included directly, this file may disappear or change contents"
+#endif
+
+#ifndef __THUNARX_PROVIDER_FACTORY_H__
+#define __THUNARX_PROVIDER_FACTORY_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _ThunarxProviderFactoryClass ThunarxProviderFactoryClass;
+typedef struct _ThunarxProviderFactory      ThunarxProviderFactory;
+
+#define THUNARX_TYPE_PROVIDER_FACTORY             (thunarx_provider_factory_get_type ())
+#define THUNARX_PROVIDER_FACTORY(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNARX_TYPE_PROVIDER_FACTORY, ThunarxProviderFactory))
+#define THUNARX_PROVIDER_FACTORY_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), THUNARX_TYPE_PROVIDER_FACTORY, ThunarxProviderFactoryClass))
+#define THUNARX_IS_PROVIDER_FACTORY(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNARX_TYPE_PROVIDER_FACTORY))
+#define THUNARX_IS_PROVIDER_FACTORY_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNARX_TYPE_PROVIDER_FACTORY))
+#define THUNARX_PROVIDER_FACTORY_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNARX_TYPE_PROVIDER_FACTORY, ThunarxProviderFactoryClass))
+
+GType                   thunarx_provider_factory_get_type       (void) G_GNUC_CONST;
+
+ThunarxProviderFactory *thunarx_provider_factory_get_default    (void);
+
+GList                  *thunarx_provider_factory_list_providers (ThunarxProviderFactory *factory,
+                                                                 GType                   type) G_GNUC_MALLOC;
+
+G_END_DECLS;
+
+#endif /* !__THUNARX_PROVIDER_FACTORY_H__ */
diff --git a/thunarx/thunarx-provider-module.c b/thunarx/thunarx-provider-module.c
new file mode 100644 (file)
index 0000000..73ea192
--- /dev/null
@@ -0,0 +1,337 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gmodule.h>
+
+#include <thunarx/thunarx-provider-module.h>
+#include <thunarx/thunarx-provider-plugin.h>
+#include <thunarx/thunarx-alias.h>
+
+
+
+/* Property identifiers */
+enum
+{
+  PROP_0,
+  PROP_RESIDENT,
+};
+
+
+
+static void     thunarx_provider_module_class_init    (ThunarxProviderModuleClass  *klass);
+static void     thunarx_provider_module_plugin_init   (ThunarxProviderPluginIface  *iface);
+static void     thunarx_provider_module_get_property  (GObject                     *object,
+                                                       guint                        prop_id,
+                                                       GValue                      *value,
+                                                       GParamSpec                  *pspec);
+static void     thunarx_provider_module_set_property  (GObject                     *object,
+                                                       guint                        prop_id,
+                                                       const GValue                *value,
+                                                       GParamSpec                  *pspec);
+static gboolean thunarx_provider_module_load          (GTypeModule                 *type_module);
+static void     thunarx_provider_module_unload        (GTypeModule                 *type_module);
+static gboolean thunarx_provider_module_get_resident  (const ThunarxProviderPlugin *plugin);
+static void     thunarx_provider_module_set_resident  (ThunarxProviderPlugin       *plugin,
+                                                       gboolean                     resident);
+
+
+
+struct _ThunarxProviderModuleClass
+{
+  GTypeModuleClass __parent__;
+};
+
+struct _ThunarxProviderModule
+{
+  GTypeModule __parent__;
+
+  GModule *library;
+  gboolean resident;
+
+  void (*initialize) (ThunarxProviderModule *module);
+  void (*shutdown)   (void);
+  void (*list_types) (const GType **types,
+                      gint         *n_types);
+};
+
+
+
+static GObjectClass *thunarx_provider_module_parent_class;
+
+
+
+GType
+thunarx_provider_module_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (ThunarxProviderModuleClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) thunarx_provider_module_class_init,
+        NULL,
+        NULL,
+        sizeof (ThunarxProviderModule),
+        0,
+        NULL,
+        NULL,
+      };
+
+      static const GInterfaceInfo plugin_info =
+      {
+        (GInterfaceInitFunc) thunarx_provider_module_plugin_init,
+        NULL,
+        NULL,
+      };
+
+      type = g_type_register_static (G_TYPE_TYPE_MODULE, "ThunarxProviderModule", &info, 0);
+      g_type_add_interface_static (type, THUNARX_TYPE_PROVIDER_PLUGIN, &plugin_info);
+    }
+
+  return type;
+}
+
+
+
+static void
+thunarx_provider_module_class_init (ThunarxProviderModuleClass *klass)
+{
+  GTypeModuleClass *gtype_module_class;
+  GObjectClass     *gobject_class;
+
+  /* determine the parent class */
+  thunarx_provider_module_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->get_property = thunarx_provider_module_get_property;
+  gobject_class->set_property = thunarx_provider_module_set_property;
+
+  gtype_module_class = G_TYPE_MODULE_CLASS (klass);
+  gtype_module_class->load = thunarx_provider_module_load;
+  gtype_module_class->unload = thunarx_provider_module_unload;
+
+  /* overload ThunarxProviderPlugin's properties */
+  g_object_class_override_property (gobject_class,
+                                    PROP_RESIDENT,
+                                    "resident");
+}
+
+
+
+static void
+thunarx_provider_module_plugin_init (ThunarxProviderPluginIface *iface)
+{
+  iface->get_resident = thunarx_provider_module_get_resident;
+  iface->set_resident = thunarx_provider_module_set_resident;
+
+  /* GTypeModule wrapper implementation */
+  iface->register_type = (gpointer) g_type_module_register_type;
+  iface->add_interface = (gpointer) g_type_module_add_interface;
+  iface->register_enum = (gpointer) g_type_module_register_enum;
+  iface->register_flags = (gpointer) g_type_module_register_flags;
+}
+
+
+
+static void
+thunarx_provider_module_get_property (GObject    *object,
+                                      guint       prop_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  ThunarxProviderPlugin *plugin = THUNARX_PROVIDER_PLUGIN (object);
+
+  switch (prop_id)
+    {
+    case PROP_RESIDENT:
+      g_value_set_boolean (value, thunarx_provider_plugin_get_resident (plugin));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+thunarx_provider_module_set_property (GObject      *object,
+                                      guint         prop_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  ThunarxProviderPlugin *plugin = THUNARX_PROVIDER_PLUGIN (object);
+
+  switch (prop_id)
+    {
+    case PROP_RESIDENT:
+      thunarx_provider_plugin_set_resident (plugin, g_value_get_boolean (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static gboolean
+thunarx_provider_module_load (GTypeModule *type_module)
+{
+  ThunarxProviderModule *module = THUNARX_PROVIDER_MODULE (type_module);
+  gchar                 *path;
+
+  /* load the module using the runtime link editor */
+  path = g_build_filename (THUNARX_DIRECTORY, type_module->name, NULL);
+  module->library = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+  g_free (path);
+
+  /* check if the load operation was successfull */
+  if (G_UNLIKELY (module->library == NULL))
+    {
+      g_warning ("Failed to load plugin `%s': %s", type_module->name, g_module_error ());
+      return FALSE;
+    }
+
+  /* verify that all required public symbols are present in the plugin's symbol table */
+  if (!g_module_symbol (module->library, "thunar_extension_shutdown", (gpointer) &module->shutdown)
+      || !g_module_symbol (module->library, "thunar_extension_initialize", (gpointer) &module->initialize)
+      || !g_module_symbol (module->library, "thunar_extension_list_types", (gpointer) &module->list_types))
+    {
+      g_warning ("Plugin `%s' lacks required symbols.", type_module->name);
+      g_module_close (module->library);
+      return FALSE;
+    }
+
+  /* initialize the plugin */
+  (*module->initialize) (module);
+
+  /* ensure that the module will never be unloaded if it requests to be kept in memory */
+  if (G_UNLIKELY (module->resident))
+    g_module_make_resident (module->library);
+
+  return TRUE;
+}
+
+
+
+static void
+thunarx_provider_module_unload (GTypeModule *type_module)
+{
+  ThunarxProviderModule *module = THUNARX_PROVIDER_MODULE (type_module);
+
+  /* shutdown the plugin */
+  (*module->shutdown) ();
+
+  /* unload the plugin from memory */
+  g_module_close (module->library);
+
+  /* reset module state */
+  module->library = NULL;
+  module->shutdown = NULL;
+  module->initialize = NULL;
+  module->list_types = NULL;
+}
+
+
+
+static gboolean
+thunarx_provider_module_get_resident (const ThunarxProviderPlugin *plugin)
+{
+  return THUNARX_PROVIDER_MODULE (plugin)->resident;
+}
+
+
+
+static void
+thunarx_provider_module_set_resident (ThunarxProviderPlugin *plugin,
+                                      gboolean               resident)
+{
+  ThunarxProviderModule *module = THUNARX_PROVIDER_MODULE (plugin);
+
+  if (G_LIKELY (module->resident != resident))
+    {
+      module->resident = resident;
+      g_object_notify (G_OBJECT (module), "resident");
+    }
+}
+
+
+
+/**
+ * thunarx_provider_module_new:
+ * @filename : the name of the library file.
+ *
+ * Allocates a new #ThunarxProviderModule for @filename.
+ *
+ * Return value: the newly allocated #ThunarxProviderModule.
+ **/
+ThunarxProviderModule*
+thunarx_provider_module_new (const gchar *filename)
+{
+  ThunarxProviderModule *module;
+
+  g_return_val_if_fail (filename != NULL, NULL);
+  g_return_val_if_fail (*filename != '\0', NULL);
+
+  module = g_object_new (THUNARX_TYPE_PROVIDER_MODULE, NULL);
+  g_type_module_set_name (G_TYPE_MODULE (module), filename);
+
+  return module;
+}
+
+
+
+/**
+ * thunarx_provider_module_list_types:
+ * @module  : a #ThunarxProviderModule.
+ * @types   : return location for the #GType array pointer.
+ * @n_types : return location for the number of types.
+ *
+ * Determines the #GType<!---->s provided by @module and returns
+ * them in @types and @n_types.
+ **/
+void
+thunarx_provider_module_list_types (const ThunarxProviderModule *module,
+                                    const GType                **types,
+                                    gint                        *n_types)
+{
+  g_return_if_fail (THUNARX_IS_PROVIDER_MODULE (module));
+  g_return_if_fail (module->list_types != NULL);
+  g_return_if_fail (n_types != NULL);
+  g_return_if_fail (types != NULL);
+
+  (*module->list_types) (types, n_types);
+}
+
+
+
+#define __THUNARX_PROVIDER_MODULE_C__
+#include <thunarx/thunarx-aliasdef.c>
diff --git a/thunarx/thunarx-provider-module.h b/thunarx/thunarx-provider-module.h
new file mode 100644 (file)
index 0000000..512c2d4
--- /dev/null
@@ -0,0 +1,48 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined(THUNARX_INSIDE_THUNARX_H) && !defined(THUNARX_COMPILATION)
+#error "Only <thunarx/thunarx.h> can be included directly, this file may disappear or change contents"
+#endif
+
+#ifndef __THUNARX_PROVIDER_MODULE_H__
+#define __THUNARX_PROVIDER_MODULE_H__
+
+#include <glib-object.h>
+
+typedef struct _ThunarxProviderModuleClass ThunarxProviderModuleClass;
+typedef struct _ThunarxProviderModule      ThunarxProviderModule;
+
+#define THUNARX_TYPE_PROVIDER_MODULE            (thunarx_provider_module_get_type ())
+#define THUNARX_PROVIDER_MODULE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNARX_TYPE_PROVIDER_MODULE, ThunarxProviderModule))
+#define THUNARX_PROVIDER_MODULE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNARX_TYPE_PROVIDER_MODULE, ThunarxProviderModuleClass))
+#define THUNARX_IS_PROVIDER_MODULE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNARX_TYPE_PROVIDER_MODULE))
+#define THUNARX_IS_PROVIDER_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNARX_TYPE_PROVIDER_MODULE))
+#define THUNARX_PROVIDER_MODULE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNARX_TYPE_PROVIDER_MODULE, ThunarxProviderModuleClass))
+
+GType                  thunarx_provider_module_get_type   (void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+ThunarxProviderModule *thunarx_provider_module_new        (const gchar                 *filename) G_GNUC_INTERNAL G_GNUC_MALLOC;
+
+void                   thunarx_provider_module_list_types (const ThunarxProviderModule *module,
+                                                           const GType                **types,
+                                                           gint                        *n_types) G_GNUC_INTERNAL;
+
+#endif /* !__THUNARX_PROVIDER_MODULE_H__ */
diff --git a/thunarx/thunarx-provider-plugin.c b/thunarx/thunarx-provider-plugin.c
new file mode 100644 (file)
index 0000000..b1facb0
--- /dev/null
@@ -0,0 +1,254 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+
+#include <thunarx/thunarx-provider-plugin.h>
+#include <thunarx/thunarx-alias.h>
+
+
+
+static void thunarx_provider_plugin_class_init (gpointer klass);
+
+
+
+GType
+thunarx_provider_plugin_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (ThunarxProviderPluginIface),
+        NULL,
+        NULL,
+        (GClassInitFunc) thunarx_provider_plugin_class_init,
+        NULL,
+        NULL,
+        0,
+        0,
+        NULL,
+        NULL,
+      };
+
+      /* register the provider plugin interface */
+      type = g_type_register_static (G_TYPE_INTERFACE, "ThunarxProviderPlugin", &info, 0);
+    }
+
+  return type;
+}
+
+
+
+static void
+thunarx_provider_plugin_class_init (gpointer klass)
+{
+  /**
+   * ThunarxProviderPlugin:resident:
+   *
+   * Tells whether a plugin must reside in memory once loaded for
+   * the first time. See thunarx_provider_plugin_get_resident() and
+   * thunarx_provider_plugin_set_resident() for more details.
+   **/
+  g_object_interface_install_property (klass,
+                                       g_param_spec_boolean ("resident",
+                                                             _("Resident"),
+                                                             _("Don't unload the plugin from memory"),
+                                                             FALSE,
+                                                             G_PARAM_READWRITE));
+}
+
+
+
+/**
+ * thunarx_provider_plugin_get_resident:
+ * @plugin : a #ThunarxProviderPlugin.
+ *
+ * Determines whether the application is allowed to unload @plugin
+ * from memory when no longer needed and reload it on demand. If
+ * %FALSE is returned, then the application may unload @plugin, else
+ * if %TRUE is returned the application will take care that @plugin
+ * is never unloaded from memory during the lifetime of the application.
+ *
+ * Return value: %TRUE if @plugin will be kept in memory once loaded
+ *               for the first time.
+ **/
+gboolean
+thunarx_provider_plugin_get_resident (const ThunarxProviderPlugin *plugin)
+{
+  g_return_val_if_fail (THUNARX_IS_PROVIDER_PLUGIN (plugin), FALSE);
+
+  return (*THUNARX_PROVIDER_PLUGIN_GET_IFACE (plugin)->get_resident) (plugin);
+}
+
+
+
+/**
+ * thunarx_provider_plugin_set_resident:
+ * @plugin   : a #ThunarxProviderPlugin.
+ * @resident : %TRUE to make @plugin resident in memory.
+ *
+ * This method is used to instruct the application that @plugin must be
+ * kept in memory during the lifetime of the application. The default
+ * is to allow the application to unload @plugin from the memory when
+ * no longer needed. If this method is invoked with a @resident value
+ * of %TRUE then the application will never try to unload @plugin.
+ *
+ * This method has no effect unless called from the 
+ * %thunar_extension_initialize method of the @plugin.
+ **/
+void
+thunarx_provider_plugin_set_resident (ThunarxProviderPlugin *plugin,
+                                      gboolean               resident)
+{
+  g_return_if_fail (THUNARX_IS_PROVIDER_PLUGIN (plugin));
+
+  (*THUNARX_PROVIDER_PLUGIN_GET_IFACE (plugin)->set_resident) (plugin, resident);
+}
+
+
+
+/**
+ * thunarx_provider_plugin_register_type:
+ * @plugin      : a #ThunarxProviderPlugin.
+ * @type_parent : the type for the parent class.
+ * @type_name   : name for the type.
+ * @type_info   : type information structure.
+ * @type_flags  : flags field providing details about the type.
+ *
+ * Looks up or registers a type that is implemented with a particular type @plugin. If a type with name @type_name
+ * was previously registered, the #GType identifier for the type is returned, otherwise the type is newly registered,
+ * and the resulting #GType identifier returned.
+ *
+ * When reregistering a type (typically because a module is unloaded then reloaded, and reinitialized), module and
+ * @type_parent must be the same as they were previously. 
+ *
+ * Return value: the new or existing type id.
+ **/
+GType
+thunarx_provider_plugin_register_type (ThunarxProviderPlugin *plugin,
+                                       GType                  type_parent,
+                                       const gchar           *type_name,
+                                       const GTypeInfo       *type_info,
+                                       GTypeFlags             type_flags)
+{
+  g_return_val_if_fail (THUNARX_IS_PROVIDER_PLUGIN (plugin), G_TYPE_INVALID);
+  g_return_val_if_fail (G_TYPE_IS_DERIVABLE (type_parent), G_TYPE_INVALID);
+  g_return_val_if_fail (type_name != NULL && *type_name != '\0', G_TYPE_INVALID);
+  g_return_val_if_fail (type_info != NULL, G_TYPE_INVALID);
+
+  return (*THUNARX_PROVIDER_PLUGIN_GET_IFACE (plugin)->register_type) (plugin, type_parent, type_name, type_info, type_flags);
+}
+
+
+
+/**
+ * thunarx_provider_plugin_add_interface:
+ * @plugin         : a #ThunarxProviderPlugin.
+ * @instance_type  : type to which to add the interface.
+ * @interface_type : interface type to add.
+ * @interface_info : type information structure.
+ *
+ * Registers an additional interface for a type, whose interface lives in the given type @plugin.
+ * If the interface was already registered for the type in this @plugin, nothing will be done.
+ *
+ * As long as any instances of the type exist, the type @plugin will not be unloaded.
+ **/
+void
+thunarx_provider_plugin_add_interface (ThunarxProviderPlugin *plugin,
+                                       GType                  instance_type,
+                                       GType                  interface_type,
+                                       const GInterfaceInfo  *interface_info)
+{
+  g_return_if_fail (THUNARX_IS_PROVIDER_PLUGIN (plugin));
+  g_return_if_fail (G_TYPE_IS_INTERFACE (interface_type));
+  g_return_if_fail (interface_info != NULL);
+
+  (*THUNARX_PROVIDER_PLUGIN_GET_IFACE (plugin)->add_interface) (plugin, instance_type, interface_type, interface_info);
+}
+
+
+
+/**
+ * thunarx_provider_plugin_register_enum:
+ * @plugin              : a #ThunarxProviderPlugin.
+ * @name                : the name for the type.
+ * @const_static_values : an array of #GEnumValue structs for the possible enumeration values.
+ *                        The array is terminated by a struct with all members being %0.
+ *
+ * Looks up or registers an enumeration that is implemented with a particular type @plugin. If a type 
+ * with name @name was previously registered, the #GType identifier for the type is returned,
+ * otherwise the type is newly registered, and the resulting #GType identifier returned.
+ *
+ * As long as any instances of the type exist, the type @plugin will not be unloaded.
+ *
+ * Return value: the new or existing type id.
+ **/
+GType
+thunarx_provider_plugin_register_enum (ThunarxProviderPlugin *plugin,
+                                       const gchar           *name,
+                                       const GEnumValue      *const_static_values)
+{
+  g_return_val_if_fail (THUNARX_IS_PROVIDER_PLUGIN (plugin), G_TYPE_INVALID);
+  g_return_val_if_fail (name != NULL && *name != '\0', G_TYPE_INVALID);
+  g_return_val_if_fail (const_static_values != NULL, G_TYPE_INVALID);
+
+  return (*THUNARX_PROVIDER_PLUGIN_GET_IFACE (plugin)->register_enum) (plugin, name, const_static_values);
+}
+
+
+
+/**
+ * thunarx_provider_plugin_register_flags:
+ * @plugin              : a #ThunarxProviderPlugin.
+ * @name                : name for the type.
+ * @const_static_values : an array of #GFlagsValue structs for the possible flags values.
+ *                        The array is terminated by a struct with all members being %0.
+ *
+ * Looks up or registers a flags type that is implemented with a particular type @plugin. If a type with name
+ * qname was previously registered, the #GType identifier for the type is returned, otherwise the type is newly
+ * registered, and the resulting #GType identifier returned.
+ *
+ * As long as any instances of the type exist, the type @plugin will not be unloaded. 
+ *
+ * Return value: the new or existing type id.
+ **/
+GType
+thunarx_provider_plugin_register_flags (ThunarxProviderPlugin *plugin,
+                                        const gchar           *name,
+                                        const GFlagsValue     *const_static_values)
+{
+  g_return_val_if_fail (THUNARX_IS_PROVIDER_PLUGIN (plugin), G_TYPE_INVALID);
+  g_return_val_if_fail (name != NULL && *name != '\0', G_TYPE_INVALID);
+  g_return_val_if_fail (const_static_values != NULL, G_TYPE_INVALID);
+
+  return (*THUNARX_PROVIDER_PLUGIN_GET_IFACE (plugin)->register_flags) (plugin, name, const_static_values);
+}
+
+
+
+#define __THUNARX_PROVIDER_PLUGIN_C__
+#include <thunarx/thunarx-aliasdef.c>
diff --git a/thunarx/thunarx-provider-plugin.h b/thunarx/thunarx-provider-plugin.h
new file mode 100644 (file)
index 0000000..b6e821f
--- /dev/null
@@ -0,0 +1,93 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined(THUNARX_INSIDE_THUNARX_H) && !defined(THUNARX_COMPILATION)
+#error "Only <thunarx/thunarx.h> can be included directly, this file may disappear or change contents"
+#endif
+
+#ifndef __THUNARX_PROVIDER_PLUGIN_H__
+#define __THUNARX_PROVIDER_PLUGIN_H__
+
+#include <glib-object.h>
+
+typedef struct _ThunarxProviderPluginIface ThunarxProviderPluginIface;
+typedef struct _ThunarxProviderPlugin      ThunarxProviderPlugin;
+
+#define THUNARX_TYPE_PROVIDER_PLUGIN           (thunarx_provider_plugin_get_type ())
+#define THUNARX_PROVIDER_PLUGIN(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNARX_TYPE_PROVIDER_PLUGIN, ThunarxProviderPlugin))
+#define THUNARX_IS_PROVIDER_PLUGIN(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNARX_TYPE_PROVIDER_PLUGIN))
+#define THUNARX_PROVIDER_PLUGIN_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), THUNARX_TYPE_PROVIDER_PLUGIN, ThunarxProviderPluginIface))
+
+struct _ThunarxProviderPluginIface
+{
+  /*< private >*/
+  GTypeInterface __parent__;
+
+  /*< public >*/
+  gboolean (*get_resident)    (const ThunarxProviderPlugin *plugin);
+  void     (*set_resident)    (ThunarxProviderPlugin       *plugin,
+                               gboolean                     resident);
+
+  GType    (*register_type)   (ThunarxProviderPlugin       *plugin,
+                               GType                        type_parent,
+                               const gchar                 *type_name,
+                               const GTypeInfo             *type_info,
+                               GTypeFlags                   type_flags);
+  void     (*add_interface)   (ThunarxProviderPlugin       *plugin,
+                               GType                        instance_type,
+                               GType                        interface_type,
+                               const GInterfaceInfo        *interface_info);
+  GType    (*register_enum)   (ThunarxProviderPlugin       *plugin,
+                               const gchar                 *name,
+                               const GEnumValue            *const_static_values);
+  GType    (*register_flags)  (ThunarxProviderPlugin       *plugin,
+                               const gchar                 *name,
+                               const GFlagsValue           *const_static_values);
+
+  /*< private >*/
+  void (*reserved1) (void);
+  void (*reserved2) (void);
+  void (*reserved3) (void);
+  void (*reserved4) (void);
+};
+
+GType     thunarx_provider_plugin_get_type       (void) G_GNUC_CONST;
+
+gboolean  thunarx_provider_plugin_get_resident   (const ThunarxProviderPlugin *plugin);
+void      thunarx_provider_plugin_set_resident   (ThunarxProviderPlugin       *plugin,
+                                                  gboolean                     resident);
+
+GType     thunarx_provider_plugin_register_type  (ThunarxProviderPlugin *plugin,
+                                                  GType                  type_parent,
+                                                  const gchar           *type_name,
+                                                  const GTypeInfo       *type_info,
+                                                  GTypeFlags             type_flags);
+void      thunarx_provider_plugin_add_interface  (ThunarxProviderPlugin *plugin,
+                                                  GType                  instance_type,
+                                                  GType                  interface_type,
+                                                  const GInterfaceInfo  *interface_info);
+GType     thunarx_provider_plugin_register_enum  (ThunarxProviderPlugin *plugin,
+                                                  const gchar           *name,
+                                                  const GEnumValue      *const_static_values);
+GType     thunarx_provider_plugin_register_flags (ThunarxProviderPlugin *plugin,
+                                                  const gchar           *name,
+                                                  const GFlagsValue     *const_static_values);
+
+#endif /* !__THUNARX_PROVIDER_PLUGIN_H__ */
index b773342..9557585 100644 (file)
 #include <thunarx/thunarx-menu-provider.h>
 #include <thunarx/thunarx-property-page.h>
 #include <thunarx/thunarx-property-page-provider.h>
+#include <thunarx/thunarx-provider-factory.h>
+#include <thunarx/thunarx-provider-plugin.h>
 
 #undef THUNARX_INSIDE_THUNARX_H
 
+#define THUNARX_DEFINE_TYPE(TN, t_n, T_P)                         THUNARX_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, {})
+#define THUNARX_DEFINE_TYPE_WITH_CODE(TN, t_n, T_P, _C_)          THUNARX_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, _C_)
+#define THUNARX_DEFINE_ABSTRACT_TYPE(TN, t_n, T_P)                THUNARX_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_ABSTRACT, {})
+#define THUNARX_DEFINE_ABSTRACT_TYPE_WITH_CODE(TN, t_n, T_P, _C_) THUNARX_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_ABSTRACT, _C_)
+
+#define THUNARX_DEFINE_TYPE_EXTENDED(TypeName, type_name, TYPE_PARENT, flags, CODE) \
+static gpointer type_name##_parent_class = NULL; \
+static GType    type_name##_type = G_TYPE_INVALID; \
+\
+static void     type_name##_init              (TypeName        *self); \
+static void     type_name##_class_init        (TypeName##Class *klass); \
+static void     type_name##_class_intern_init (TypeName##Class *klass) \
+{ \
+  type_name##_parent_class = g_type_class_peek_parent (klass); \
+  type_name##_class_init (klass); \
+} \
+\
+GType \
+type_name##_get_type (void) \
+{ \
+  return type_name##_type; \
+} \
+\
+void \
+type_name##_register_type (ThunarxProviderPlugin *thunarx_define_type_plugin) \
+{ \
+  GType thunarx_define_type_id; \
+  static const GTypeInfo thunarx_define_type_info = \
+  { \
+    sizeof (TypeName##Class), \
+    NULL, \
+    NULL, \
+    (GClassInitFunc) type_name##_class_intern_init, \
+    NULL, \
+    NULL, \
+    sizeof (TypeName), \
+    0, \
+    (GInstanceInitFunc) type_name##_init, \
+    NULL, \
+  }; \
+  thunarx_define_type_id = thunarx_provider_plugin_register_type (thunarx_define_type_plugin, TYPE_PARENT, \
+                                                                  #TypeName, &thunarx_define_type_info, flags); \
+  { CODE ; } \
+  type_name##_type = thunarx_define_type_id; \
+}
+
+#define THUNARX_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) \
+{ \
+  static const GInterfaceInfo thunarx_implement_interface_info = \
+  { \
+    (GInterfaceInitFunc) iface_init \
+  }; \
+  thunarx_provider_plugin_add_interface (thunarx_define_type_plugin, thunarx_define_type_id, TYPE_IFACE, &thunarx_implement_interface_info); \
+}
+
 #endif /* !__THUNARX_H__ */
index aaa7c58..90d1656 100644 (file)
@@ -90,3 +90,25 @@ thunarx_property_page_provider_get_pages
 #endif
 #endif
 
+/* ThunarxProviderFactory methods */
+#if IN_HEADER(__THUNARX_PROVIDER_FACTORY_H__)
+#if IN_SOURCE(__THUNARX_PROVIDER_FACTORY_C__)
+thunarx_provider_factory_get_type G_GNUC_CONST
+thunarx_provider_factory_get_default
+thunarx_provider_factory_list_providers G_GNUC_MALLOC
+#endif
+#endif
+
+/* ThunarxProviderPlugin methods */
+#if IN_HEADER(__THUNARX_PROVIDER_PLUGIN_H__)
+#if IN_SOURCE(__THUNARX_PROVIDER_PLUGIN_C__)
+thunarx_provider_plugin_get_type G_GNUC_CONST
+thunarx_provider_plugin_get_resident
+thunarx_provider_plugin_set_resident
+thunarx_provider_plugin_register_type
+thunarx_provider_plugin_add_interface
+thunarx_provider_plugin_register_enum
+thunarx_provider_plugin_register_flags
+#endif
+#endif
+