diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2009-07-14 20:19:59 +0100 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2009-08-08 17:31:52 +0100 |
commit | ca8812c646c744604ffbafe4dfe6230424671c0e (patch) | |
tree | 95a89af658bfb4bc40d774fc3f949bc31b88f036 /docs | |
parent | 8b051630fb7472d21a5d632d206a00366cf2337e (diff) | |
download | totem-ca8812c646c744604ffbafe4dfe6230424671c0e.tar.gz |
Bug 588569 – Add plugin authoring tutorial
Diffstat (limited to 'docs')
-rw-r--r-- | docs/reference/Makefile.am | 2 | ||||
-rw-r--r-- | docs/reference/totem-docs.xml | 5 | ||||
-rw-r--r-- | docs/reference/totem-plugins.xml | 147 |
3 files changed, 153 insertions, 1 deletions
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index 46ad5599d..ac428792d 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -116,7 +116,7 @@ HTML_IMAGES= # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files = version.xml +content_files = version.xml totem-plugins.xml # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # These files must be listed here *and* in content_files diff --git a/docs/reference/totem-docs.xml b/docs/reference/totem-docs.xml index 792059b43..cef7eca66 100644 --- a/docs/reference/totem-docs.xml +++ b/docs/reference/totem-docs.xml @@ -13,6 +13,11 @@ </releaseinfo> </bookinfo> + <chapter id="tutorials"> + <title>Tutorials</title> + <xi:include href="xml/totem-plugins.xml"/> + </chapter> + <chapter id="core-api"> <title>Core API</title> <xi:include href="xml/totem-object.xml"/> diff --git a/docs/reference/totem-plugins.xml b/docs/reference/totem-plugins.xml new file mode 100644 index 000000000..5f10bae94 --- /dev/null +++ b/docs/reference/totem-plugins.xml @@ -0,0 +1,147 @@ +<refentry id="totem-plugins"> + <refmeta> + <refentrytitle role="top_of_page" id="totem-plugins.top_of_page">Writing Totem Plugins</refentrytitle> + <manvolnum>3</manvolnum> + <refmiscinfo>Totem</refmiscinfo> + </refmeta> + <refnamediv> + <refname>Writing Totem Plugins</refname> + <refpurpose>brief tutorial on writing Totem plugins</refpurpose> + </refnamediv> + + <refsect1> + <title>Introduction</title> + <para>Totem is extensible by means of small, dynamically-loadable plugins, which add functionality wanted by some but not others.</para> + + <refsect2> + <title>Locations</title> + <para>Totem plugins can either be installed in the system path + (e.g. <filename class="directory">/usr/lib/totem/plugins/</filename>), or in a user's home directory + (e.g. <filename class="directory">~/.local/share/totem/plugins/</filename>). In either case, each plugin resides in a + subdirectory named after the plugin itself.</para> + <para>In addition, each plugin needs a <filename class="extension">.totem-plugin</filename> index file, residing inside the plugin + directory. This gives the code name of the plugin, as well as some metadata about the plugin such as its human-readable + name, description and author.</para> + <example> + <title>Example Plugin Directory</title> + <para>A system-installed plugin called <literal>subtitle-downloader</literal> would reside in + <filename class="directory">/usr/lib/totem/plugins/subtitle-downloader</filename>, and would (at a + minimum) have the following files: + <itemizedlist> + <listitem><filename>subtitle-downloader.totem-plugin</filename></listitem> + <listitem><filename>libsubtitle-downloader.so</filename></listitem> + </itemizedlist> + </para> + <para>If installed in a user's home directory, it would reside in + <filename class="extension">~/.local/share/totem/plugins/subtitle-downloader</filename> and have the same + files.</para> + </example> + </refsect2> + + <refsect2> + <title>The <filename class="extension">.totem-plugin</filename> File</title> + <para>The file should use the following template: + <programlisting>[Totem Plugin] + Module=<replaceable>plugin-name</replaceable> + IAge=<replaceable>plugin interface age (starting at 1)</replaceable> + Builtin=<replaceable><literal>true</literal> or <literal>false</literal></replaceable> + Name=<replaceable>Human-Readable Plugin Name</replaceable> + Description=<replaceable>Simple sentence describing the plugin's functionality.</replaceable> + Authors=<replaceable>Plugin Author Name</replaceable> + Copyright=Copyright © <replaceable>year</replaceable> <replaceable>Copyright Holder</replaceable> + Website=<replaceable>http://plugin/website/</replaceable></programlisting> + Most of the values in the template are fairly self-explanatory. One thing to note is that the plugin name should be + in lowercase, and contain no spaces. The plugin interface age should start at <literal>1</literal>, and only be + incremented when the binary interface of the plugin (as used by Totem) changes. If the plugin does not have its own + website, Totem's website (<literal>http://projects.gnome.org/totem/</literal>) can be used.</para> + <para>The library file containing the plugin's code should be named + <filename>lib<replaceable>plugin-name</replaceable>.so</filename> (for C, or other compiled-language, plugins) or + <filename><replaceable>plugin-name</replaceable>.py</filename> (for Python plugins).</para> + </refsect2> + + <refsect2> + <title>Writing a Plugin</title> + <para>Writing a plugin in C is a matter of creating a new <type><link linkend="GObject">GObject</link></type> which inherits + from <type><link linkend="TotemPlugin">TotemPlugin</link></type>. The following code will create a simple plugin + called <literal>foobar</literal>: + <example> + <title>Example Plugin Code</title> + <programlisting> +#define TOTEM_TYPE_FOOBAR_PLUGIN (totem_foobar_plugin_get_type ()) +#define TOTEM_FOOBAR_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TOTEM_TYPE_FOOBAR_PLUGIN, TotemFoobarPlugin)) +#define TOTEM_FOOBAR_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TOTEM_TYPE_FOOBAR_PLUGIN, TotemFoobarPluginClass)) +#define TOTEM_IS_FOOBAR_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TOTEM_TYPE_FOOBAR_PLUGIN)) +#define TOTEM_IS_FOOBAR_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TOTEM_TYPE_FOOBAR_PLUGIN)) +#define TOTEM_FOOBAR_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TOTEM_TYPE_FOOBAR_PLUGIN, TotemFoobarPluginClass)) + +typedef struct { + TotemPlugin parent; + /* plugin object members */ +} TotemFoobarPlugin; + +typedef struct { + TotemPluginClass parent_class; +} TotemFoobarPluginClass; + +G_MODULE_EXPORT GType register_totem_plugin (GTypeModule *module); +GType totem_foobar_plugin_get_type (void) G_GNUC_CONST; + +static gboolean impl_activate (TotemPlugin *plugin, TotemObject *totem, GError **error); +static void impl_deactivate (TotemPlugin *plugin, TotemObject *totem); + +TOTEM_PLUGIN_REGISTER (TotemFoobarPlugin, totem_foobar_plugin) + +static void +totem_foobar_plugin_class_init (TotemFoobarPluginClass *klass) +{ + TotemPluginClass *plugin_class = TOTEM_PLUGIN_CLASS (klass); + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; +} + +static void +totem_foobar_plugin_init (TotemFoobarPlugin *plugin) +{ + /* Initialise resources, but only ones which should exist for the entire lifetime of Totem; + * those which should only exist for the lifetime of the plugin (which may be short, and may + * occur several times during one Totem session) should be created in impl_activate, and destroyed + * in impl_deactivate. */ +} + +static gboolean +impl_activate (TotemPlugin *plugin, TotemObject *totem, GError **error) +{ + TotemFoobarPlugin *self = TOTEM_FOOBAR_PLUGIN (plugin); + + /* Initialise resources, connect to events, create menu items and UI, etc., here. + * Note that impl_activate and impl_deactivate can be called multiple times in one + * Totem instance, though impl_activate will always be followed by impl_deactivate before + * it is called again. Similarly, impl_deactivate cannot be called twice in succession. */ + + return TRUE; +} + +static void +impl_deactivate (TotemPlugin *plugin, TotemObject *totem) +{ + TotemFoobarPlugin *self = TOTEM_FOOBAR_PLUGIN (plugin); + + /* Destroy resources created in impl_activate here. e.g. Disconnect from signals + * and remove menu entries and UI. */ +}</programlisting> + </example></para> + <para>Once resources have been created, and the plugin has been connected to Totem's UI in the <function>impl_activate</function> + function, the plugin is free to go about its tasks as appropriate. If the user deactivates the plugin, or Totem decides + to deactivate it, the <function>impl_deactivate</function> will be called. The plugin should free any resources + grabbed or allocated in the <function>impl_activate</function> function, and remove itself from the Totem + interface.</para> + <para>Note that plugins can be activated and deactivated (e.g. from Totem's plugin manager) many times during one Totem session, + so the <function>impl_activate</function> and <function>impl_deactivate</function> functions must be able to cope with + this.</para> + <para>Any of the API documented in the rest of the Totem API reference can be used by plugins, though the bindings for Python + plugins are incomplete. Otherwise, Python plugins are written in the same way as C plugins, and are similarly implemented + as classes derived from <type><link linkend="TotemPlugin">TotemPlugin</link></type>.</para> + </refsect2> + </refsect1> +</refentry> |