doc/reference/libpurple/tut_c_plugins.xml

Fri, 01 Oct 2021 17:49:31 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Fri, 01 Oct 2021 17:49:31 -0500
changeset 41061
94a357cfec6c
parent 40933
60f4b2a6d66a
permissions
-rw-r--r--

move the zephyr protocol plugins icons to a resource in the plugin

Testing Done:
Ran in devenv with a logo inverted (which was reverted before committing).

Reviewed at https://reviews.imfreedom.org/r/981/

<?xml version='1.0' encoding="ISO-8859-1"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
]>
<chapter id="chapter-tut-c-plugins">
  <title>C Plugins tutorial</title>

  <sect2 id="tut-c-plugins-introduction">
  <title>Introduction</title>
  <para>
  C plugins are native plugins.  They have complete access to all of the API,
  and can do basically whatever they want.  All of the protocol plugins are
  also written in C.
  </para>
  </sect2>

  <sect2 id="tut-c-plugins-getting-started">
  <title>Getting Started</title>
  <para>
  To develop a plugin you need to have the libpurple and (for UI plugins) the
  Pidgin/Finch source code or development headers.  It is generally a good idea
  to compile against the same version of Pidgin that you are running.  You may
  also want to develop against the code in our Mercurial repository if you need
  to use a new feature.  Please do not abuse our Mercurial repository, however.
  </para>
  </sect2>

  <sect2 id="tut-c-plugins-hello-world">
  <title>An Example</title>
  <para>
  I know every tutorial has a hello world, so why should libpurple be any
  different?

<example>
<title>Hello World!</title>
<programlisting>
#include &lt;purple.h&gt;

static GPluginPluginInfo *
hello_world_query(GError **error)
{
	const gchar * const authors[] = {
		"Author Name &lt;e@mail&gt;",
		NULL
	};

	/* For specific notes on the meanings of each of these members, consult the
	   C Plugin Howto on the website. */
	return purple_plugin_info_new (
		"name",         "Hello World!",
		"version",      VERSION,
		"category",     "Example",
		"summary",      "Hello World Plugin",
		"description",  "Hello World Plugin",
		"authors",      authors,
		"website",      "http://helloworld.tld",
		"abi-version",  PURPLE_ABI_VERSION,
		NULL
	);
}

static gboolean
hello_world_load(GPluginPlugin *plugin, GError **error)
{
	purple_notify_message(plugin, PURPLE_NOTIFY_MSG_INFO, "Hello World!",
						"This is the Hello World! plugin :)",
						NULL, NULL, NULL, NULL);

	return TRUE;
}

static gboolean
hello_world_unload(GPluginPlugin *plugin, GError **error)
{
	return TRUE;
}

GPLUGIN_NATIVE_PLUGIN_DECLARE(hello_world)
</programlisting>
</example>
  </para>

  <para>
  Okay, so what does all this mean?  We start off by including purple.h.  This
  file includes all the libpurple header files.
  </para>

  <para>
  <literal>hello_world_query</literal>, <literal>hello_world_load</literal> and
  <literal>hello_world_unload</literal> are functions that must be implemented
  in every plugin.  These functions are named according to the value passed
  to <literal>GPLUGIN_NATIVE_PLUGIN_DECLARE</literal> which is described below.
  </para>

  <para>
  <literal>hello_world_query</literal> is called when the plugin is queried by
  the plugin system, and returns various information about the plugin in form
  of a newly created instance of <literal>GPluginPluginInfo</literal> or a
  subclass.  For a list of all available properties, see
  <link linkend="purple-plugin-info-new"><function>purple_plugin_info_new()</function></link>.
  </para>

  <para>
  If anything should go wrong during the query you can return an error by using
  <function>g_set_error()</function> on the <literal>error</literal> argument.
  </para>

  <para>
  <literal>hello_world_load</literal> is called when the plugin is loaded. That
  is the user has enabled the plugin or libpurple is loading a plugin that was
  previously loaded.  You can initialize any variables, register dynamic types,
  and so on in this function.  Plugins may also want to add their preferences
  to the pref tree--more about that later.  In this plugin we'll just use it to
  display a message.  Just like
  <literal>hello_world_query</literal> if there are any errors that arise, you
  can call <function>g_set_error()</function> on the <literal>error</literal>
  agument and return <literal>FALSE</literal>.
  </para>

  <para>
  <literal>hello_world_unload</literal> is called when the plugin is unloaded.
  That is, when the user has manually unloaded the plugin or the program is
  shutting down.  We can use it to wrap up everything, and free our variables.
  Again, if there are any errors, you can call
  <function>g_set_error()</function> on the <literal>error</literal> argument
  and return <literal>FALSE</literal>.
  </para>

  <para>
  Finally we have
  <link linkend="GPLUGIN_NATIVE_PLUGIN_DECLARE:CAPS"><function>GPLUGIN_NATIVE_PLUGIN_DECLARE()</function></link>.
  It is a helper macro that makes creating plugins easier.  It has a single
  argument which is the prefix used for the <literal>_query</literal>,
  <literal>_load</literal>, and <literal>_unload</literal> functions.
  </para>
 </sect2>
</chapter>

mercurial