/*-
* Copyright (c) 2001 Jordan DeLong
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PLUGIN_H
#define PLUGIN_H
/*
* return values for plugin callbacks. if any plugin callback
* returns PLUGIN_UNLOAD that plugin is immediatly unloaded.
* certain plugin callbacks can return plugin using, which means
* that they are using the event that caused the callback,
* and the main code shouldn't call any more plugin callbacks
* for it, or do any normal processing on it.
*/
#define PLUGIN_OK 0
#define PLUGIN_UNLOAD 1
#define PLUGIN_USING 2
/*
* callbacks that may be registered by plugins, and macros to
* call all the registered handlers for a callback. all callbacks
* take parameters that depend on the type of the callback; all
* plugin callback handlers also take a first parameter of the
* type of the callback; this allows using one handler for multiple
* callbacks who's handling is nearly identical.
*/
enum {
/*
* init_hints(int pcall, client_t *client, dgroup_t *dgroup);
*
* initialize windowmanager hints; the client passed in
* is a newly-arriving client. the plugin may modify client
* flags or set client->dgroup to affect how the client is
* initially created.
*/
PCALL_INIT_HINTS = 0,
#define plugin_init_hints(client) \
plugin_callback_all(PCALL_INIT_HINTS, 1, client)
/*
* window_birth(int pcall, client_t *client);
*
* signals arrival of a new client. this is called right
* after the client's window is mapped for the first time.
*/
PCALL_WINDOW_BIRTH,
#define plugin_window_birth(client) \
plugin_callback_all(PCALL_WINDOW_BIRTH, 1, client)
/*
* window_death(int pcall, client_t *client);
*
* signals the departure of a client. called immediatly
* before the client_rm call, allowing the plugin to reference
* client_t internals for one last time.
*/
PCALL_WINDOW_DEATH,
#define plugin_window_death(client) \
plugin_callback_all(PCALL_WINDOW_DEATH, 1, client)
/*
* focus_change(int pcall, client_t *client);
*
* the X focus was changed to a different managed client
* window; the client paramater is the client that just got
* focused (also accessable as the client_focused global).
*/
PCALL_FOCUS_CHANGE,
#define plugin_focus_change(client) \
plugin_callback_all(PCALL_FOCUS_CHANGE, 1, client)
/*
* geometry_change(int pcall, client_t *client);
*
* the client was resized or moved; a seperate callback
* is used for zooming.
*/
PCALL_GEOMETRY_CHANGE,
#define plugin_geometry_change(client) \
plugin_callback_all(PCALL_GEOMETRY_CHANGE, 1, client)
/*
* iconify_notify(int pcall, client_t *client);
*
* the client was iconified.
*/
PCALL_ICONIFY_NOTIFY,
#define plugin_iconify_notify(client) \
plugin_callback_all(PCALL_ICONIFY_NOTIFY, 1, client)
/*
* restore_notify(int pcall, client_t *client);
*
* the client was restored (uniconified).
*/
PCALL_RESTORE_NOTIFY,
#define plugin_restore_notify(client) \
plugin_callback_all(PCALL_RESTORE_NOTIFY, 1, client)
/*
* zoom_notify(int pcall, client_t *client);
*
* the client was zoomed (maximized).
*/
PCALL_ZOOM_NOTIFY,
#define plugin_zoom_notify(client) \
plugin_callback_all(PCALL_ZOOM_NOTIFY, 1, client)
/*
* unzoom_notify(int pcall, client_t *client);
*
* the client was unzoomed.
*/
PCALL_UNZOOM_NOTIFY,
#define plugin_unzoom_notify(client) \
plugin_callback_all(PCALL_UNZOOM_NOTIFY, 1, client)
/*
* raise_notify(int pcall, client_t *client, client_t *lowest);
*
* client was raised to the top of it's stacking layer. the
* lowest parameter is set to lowest client that is above the
* the one that was raised, or null if there is no such client.
*/
PCALL_RAISE_NOTIFY,
#define plugin_raise_notify(client, lowest) \
plugin_callback_all(PCALL_RAISE_NOTIFY, 2, client, lowest)
/*
* lower_notify(int pcall, client_t *client, client_t *lowest);
*
* client was lowered to the bottom of it's stacking layer.
* the lowest parameter is the same as in raise_notify().
*/
PCALL_LOWER_NOTIFY,
#define plugin_lower_notify(client, lowest) \
plugin_callback_all(PCALL_LOWER_NOTIFY, 2, client, lowest)
/*
* workspace_change(int pcall, screen_t *screen, desktop_t *desktop);
*
* the current workspace changed for desktop, on screen.
* desktop is not neccesarily the current desktop for the screen.
*/
PCALL_WORKSPACE_CHANGE,
#define plugin_workspace_change(screen, desktop) \
plugin_callback_all(PCALL_WORKSPACE_CHANGE, 2, screen, desktop)
/*
* desktop_change(int pcall, screen_t *screen, desktop_t *olddesk);
*
* the current desktop changed on screen. screen->desktop
* contains the new current desktop, and a pointer to the old
* desktop is given in olddesk.
*/
PCALL_DESKTOP_CHANGE,
#define plugin_desktop_change(screen, olddesk) \
plugin_callback_all(PCALL_DESKTOP_CHANGE, 2, screen, olddesk)
/*
* anim_birth(int pcall, client_t *client);
*
* somewhat hackish callback that occurs before the window
* gets mapped and signals new window arrival. the callback is
* located at an appropriate time to do animations for newly
* ariving windows.
*/
PCALL_ANIM_BIRTH,
#define plugin_anim_birth(client) \
plugin_callback_all(PCALL_ANIM_BIRTH, 1, client)
/*
* root_button(int pcall, screen_t *screen, XButtonEvent *e);
*
* because clients can't plugin_setcontext on the root window,
* this callback is provided to notify clients of root window
* button presses and releases. the X button event and the screen
* on which it occured are passed to the client.
*/
PCALL_ROOT_BUTTON,
#define plugin_root_button(screen, e) \
plugin_callback_all(PCALL_ROOT_BUTTON, 2, screen, e)
/*
* property_notify(int pcall, client_t *client, XPropertyEvent *e);
*
* plugins can't plugin_setcontext on a client window to
* handle window property changes because other plugins may
* be interested in those changes as well; this callback is
* provided to allow them to recieve property information without
* doing a setcontext.
*/
PCALL_PROPERTY_NOTIFY,
#define plugin_property_notify(client, e) \
plugin_callback_all(PCALL_PROPERTY_NOTIFY, 2, client, e)
/*
* map_request(int pcall, screen_t *screen, XMapRequestEvent *e);
*
* called when a new toplevel window attempts to map
* itself. screen is the screen on which the request occured,
* and e is the actual X event that cause the map request.
* if the callback returns PLUGIN_USING, no client_t will
* be created for this window.
*/
PCALL_MAP_REQUEST,
#define plugin_map_request(screen, e) \
plugin_callback_all(PCALL_MAP_REQUEST, 2, screen, e)
/* total number of plugin callback types */
PCALL_COUNT
};
/*
* an array of subparamaters; placed in the plugin structure
* and in each parameter structure.
*/
struct subparams {
int count; /* number of sub params */
param_t **params; /* the sub parameters */
};
/*
* a tree of plugin parameters that are passed in for use by the plugin from
* the user's rcfile. there is a pointer to one of these in the plugin_t
* structure who's varname will
*/
struct param {
char *name; /* name of the parameter */
char *value; /* value of the parameter */
subparams_t subparams;
};
/*
* plugin callout list entry structure; plugins register callbacks
* by passing in an address of a handler function. the handler
* is stored here as an (int *)(), but the handler routines do actually
* take arguments who's type depends on the callback. this entries
* are hung off the plugin structure, for calling callbacks for
* particular plugins, as well as being hung off internal lists
* based on callback type to save from traversing the full list
* of all plugins.
*
* plugins may add or remove callback handlers at any time during
* their operation; however most plugins are expected to add a few
* callbacks in their start() routine and leave them alone from
* then on.
*/
struct callback {
LIST_ENTRY(callback) cb_list; /* callback list entry */
LIST_ENTRY(callback) cb_plug; /* plugin registered callbacks list */
plugin_t *plugin; /* plugin requesting the callback */
int (*handler)(); /* address of handler function */
int pcall; /* callback type */
};
typedef LIST_HEAD(, callback) callbacklist_t;
/*
* plugin structure; plugins are dlopened shared objects that
* export set of routines that are called into by the main code.
* the plugin may, during the calls into those routines, organize
* other calls into the plugin text for notification or action on
* certain events. all callbacks a plugin adds are automatically
* removed for it when it is unloaded.
*/
struct plugin {
void *hnd; /* handle from dlopen */
char *name; /* name the plugin was loaded as */
/*
* these are functions that are called to alert
* the plugin of the stages during startup/shutdown.
* init is called during the rcfile parsing and
* as such it shouldn't use any internal structures.
* shutdown can be called at any time and should be
* prepared to release memory; it shouldn't use any
* of the internal structures unless it's sure that it
* is safe to do so (due to setting some global or
* some such in a handler for another callback).
* start gets called immediatly after rcfile parsing
* and indicates that it is time for the plugin to
* begin normal operation.
*/
int (*init)(); /* plugin initialization routine */
void (*shutdown)(); /* plugin death routine */
int (*start)(); /* post-init plugin starting */
/*
* all x events for windows that have a plugin_context
* with this plugin (set by plugin_setcontext) will call
* into the plugin for handling through this routine.
*/
int (*xevent_handler)(XEvent *);
/*
* list of callback handlers this plugin has
* registered.
*/
callbacklist_t callback_list;
/*
* parameters for the plugin; all plugins can recieve
* a tree of parameters from the rcfile. these parameters
* are freed after rcfile parsing, so they should not be
* used after (or during) the call to start.
*/
subparams_t params;
LIST_ENTRY(plugin) p_list;
};
typedef LIST_HEAD(, plugin) pluginlist_t;
extern pluginlist_t plugin_list;
extern plugin_t *plugin_this;
void plugin_init();
void plugin_shutdown();
plugin_t *plugin_load(char *name, subparams_t *params, int doinit);
void plugin_unload(plugin_t *plugin);
void plugin_start();
void plugin_handle_event(plugin_t *plugin, XEvent *e);
/* plugin callback management */
callback_t *plugin_callback_add(plugin_t *plugin, int pcall, void *handler);
void plugin_callback_rm(callback_t *callback);
int plugin_callback(plugin_t *plugin, int pcall, int argc, ...);
int plugin_callback_all(int pcall, int argc, ...);
/* parameter structure routines*/
param_t *plugin_param(char *name, char *value);
int plugin_subparams_add(subparams_t *subparams, param_t *param);
int plugin_subparams_merge(subparams_t *subparams, subparams_t *addition);
void plugin_subparams_free(subparams_t *subparams);
void plugin_param_free(param_t *param);
/*
* these are called from plugins to get param values. Some of
* them need to make memory for the returned values; i.e. string
* and color.
*/
param_t *plugin_find_param(subparams_t *subparams, char *name);
int plugin_string_param(subparams_t *subparams, char *name, char **ret);
int plugin_color_param(subparams_t *subparams, char *name, Pixel **ret);
int plugin_pixmap_param(subparams_t *subparams, char *name, pixmap_t **ret);
int plugin_dgroup_param(subparams_t *subparams, char *name, dgroup_t **ret);
int plugin_int_param(subparams_t *subparams, char *name, int *ret);
int plugin_double_param(subparams_t *subparams, char *name, double *ret);
int plugin_bool_param(subparams_t *subparams, char *name, int *ret);
int plugin_stacklayer_param(subparams_t *subparams, char *name, int *ret);
/*
* plugins call these to associate a non-managed window with it;
* the purpose being to cause the main event code to call out to
* the plugin to handle the event.
*/
void plugin_setcontext(plugin_t *plugin, Window wnd);
void plugin_rmcontext(Window wnd);
#endif
syntax highlighted by Code2HTML, v. 0.9.1