PLUGINS
=======

A plugin is a shared object that implements a set of callback functions.
To a user this essentially means that a plugin is a .so file that they
load inside of their golemrc file to add functionality to golem.  A few
plugins are included with this distribution; for instance, the root menus
are in a loaded plugin called simple_menus.

When loading a plugin from your rc file, it is convention that the plugin
be loaded from a seperate file that is included by the main rcfile.  For
instance, a plugin loading in a user's rcfile may look like this:

.include "plugins/box_iconify/rc"
.include "plugins/simple_menus/rc"

The included files can provide a tree-shaped data of name-value pairs to the
plugin it is going to load (which is the reason to seperate it from the main
golemrc). At any point in the load statement, you may either terminate it
with a semi-colon (;) or open a subparam block with { and }.  The following
examples should explain this better:

# example 1, just loading it
load "plugin_name";

# example 2, passing in two params
load "plugin_name" {
	param "text"  "heh";
	param "text2" "heh2";
	fileparam "test" "test.xpm";	# fileparam means to convert to a path
					# and is neccesary for any filename
					# parameter.
}

# example 3, passing in a tree of params
load "plugin_name" {
	param "text" "heh";
	param "tree" "tree" {
		param "asdf" "asdf";
		param "subtree" "subtree" { param "hehe" "haha"; }
	}
}

A good example of how this works in practice is too look at the sample
configuration file for the simple_menus plugin, which is included with this
distribution.

Plugins may also recieve parameters from forplug includes.  Forplug includes
are described in the file THEMES included with this distribution; and are
intended to allow themes to pass parameters such as pixmaps to plugins.

WRITING PLUGINS
===============

Most people probably aren't going to write their own plugins, and as such
it's reasonable for most readers to stop here.  If, however, you are going
to make a plugin, or if you just want to know how this works, by all
means, keep reading.

Authoring a plugin requires a good knowledge of Xlib, and depending on the
type of plugin, it probably requires an amount of knowledge about the way
the golem internals work; most of this can be gained by looking at structure
definitions in the header files, for instance, client.h for the definition
of a client_t, which is the structure that represents a managed client.

Plugins can be authored to do a number of different things; it can create
managed or unmanged windows that will provide some sort of interface to the
user; it can draw animations when new clients arrive or when clients are
iconified, and so forth.

PLUGIN CALLBACKS
================

Plugins are given a chance to do stuff in various callback functions.  These
functions are exported by the plugin's shared object and dlsym()'d to make
them available from golem's space.  A list of callbacks and explainations of
them is at the bottom of this text.

PLUGIN WINDOWS
==============

There are two types of windows you may create in a plugin: managed and 
unmanaged.  A managed window will be decorated by golem; and will respond
to events like the other clients that golem is managing: i.e. clicking on
it's decor units will have the expected effects for resizing and moving, and
so forth.  An unmanaged window is generally what most plugins will prefer
to make: it is implemented as an override_redirect window that the plugin
calls plugin_setcontext() on.  The plugin_setcontext call tells the main
golem code that this plugin needs to recieve events for that window.

An example of where managed plugin windows are a good choice is the
simple_menus plugin, which is used for traditional hierarchial root window
menus.

PARAMETERS
==========

Plugins recieve parameters in a tree of name-value pairs.  The plugin is then
responsible for turning this data into whatever it needs during the init()
callback (see below); the params for a plugin will be freed after the init()
call.

Take a look at the plugutil.h included with this distribution for some handy
macros to aid in using plugin parameters, and at simple_menus for and example
of it in action.

CALLBACK REFERENCE
==================

I will attempt to keep this reasonably up to date: also look at plugin.h in
case I leave something out.

All callbacks except for shutdown() return either PLUGIN_OK, or
PLUGIN_UNLOAD.  PLUGIN_OK means that everything is fine, and the plugin wants
to continue to operate; PLUGIN_UNLOAD is used for fatal errors in the plugin,
and results in an immediate call to shutdown() before unloading the plugin.

----------------------------------------------------------------------
init(plugin_t *plugin)
	called immediatly upon plugin loading.  this is
 where you should parse any parameters passed to the plugin.
----------------------------------------------------------------------
shutdown()
	this is the only callback that doesn't return int, it returns
 void.  this function _must_ be prepared to clean up any and all
 memory allocated by the plugin, and do any neccesary shutdown in
 terms of window destruction for the plugin to safely unload.  This
 function must be able to be called at any time and satisfy these
 requirements in a properly written plugin.  additionally, and _very_
 important: you _must_ disassociate all of your unmanaged windows
 from the plugin by calling plugin_rmcontext() and by doing client_rm()
 on the managed ones.
----------------------------------------------------------------------
start(plugin_t *plugin)
	called after all initialization is complete; screen_init has
 been called, and so forth.  no plugin may create a managed window
 in any callback before start (the only callbacks that can happen
 before start are init, and of course shutdown can happen at any time)
----------------------------------------------------------------------
window_birth(plugin_t *plugin, client_t *client)
	called when a managed client first appears (transitions from
 WithdrawnState to NormalState)
----------------------------------------------------------------------
window_death(plugin_t *plugin, client_t *client)
	called when a managed client in NormalState goes away
----------------------------------------------------------------------
iconify_notify(plugin_t *plugin, client_t *client)
	called when a managed client is iconified
----------------------------------------------------------------------
restore_notify(plugin_t *plugin, client_t *client)
	called when a managed client that is iconified is uniconifed
----------------------------------------------------------------------
zoom_notify(plugin_t *plugin, client_t *client)
	called when a managed client is zoomed (maximized)
----------------------------------------------------------------------
unzoom_notify(plugin_t *plugin, client_t *client)
	called when a managed client is unzoomed
----------------------------------------------------------------------

For all of the following callbacks, the client_t argument is either a
pointer to the client_t for a managed plugin window that this plugin
created, or NULL, which indicates that the event is happening due to
an unmanaged window that this client called plugin_setcontext on.

<coming soon, for now look at plugin.h and the dist plugins>
