home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / include / libpurple / plugin.h < prev    next >
Encoding:
C/C++ Source or Header  |  2007-05-04  |  18.4 KB  |  676 lines

  1. /**
  2.  * @file plugin.h Plugin API
  3.  * @ingroup core
  4.  *
  5.  * purple
  6.  *
  7.  * Purple is the legal property of its developers, whose names are too numerous
  8.  * to list here.  Please refer to the COPYRIGHT file distributed with this
  9.  * source distribution.
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  */
  25. #ifndef _PURPLE_PLUGIN_H_
  26. #define _PURPLE_PLUGIN_H_
  27.  
  28. #include <glib/glist.h>
  29. #include <gmodule.h>
  30. #include "signals.h"
  31. #include "value.h"
  32.  
  33. typedef struct _PurplePlugin           PurplePlugin;
  34. typedef struct _PurplePluginInfo       PurplePluginInfo;
  35. typedef struct _PurplePluginUiInfo     PurplePluginUiInfo;
  36. typedef struct _PurplePluginLoaderInfo PurplePluginLoaderInfo;
  37.  
  38. typedef struct _PurplePluginAction     PurplePluginAction;
  39.  
  40. typedef int PurplePluginPriority; /**< Plugin priority. */
  41.  
  42. #include "pluginpref.h"
  43.  
  44. /**
  45.  * Plugin types.
  46.  */
  47. typedef enum
  48. {
  49.     PURPLE_PLUGIN_UNKNOWN  = -1,  /**< Unknown type.    */
  50.     PURPLE_PLUGIN_STANDARD = 0,   /**< Standard plugin. */
  51.     PURPLE_PLUGIN_LOADER,         /**< Loader plugin.   */
  52.     PURPLE_PLUGIN_PROTOCOL        /**< Protocol plugin. */
  53.  
  54. } PurplePluginType;
  55.  
  56. #define PURPLE_PRIORITY_DEFAULT     0
  57. #define PURPLE_PRIORITY_HIGHEST  9999
  58. #define PURPLE_PRIORITY_LOWEST  -9999
  59.  
  60. #define PURPLE_PLUGIN_FLAG_INVISIBLE 0x01
  61.  
  62. #define PURPLE_PLUGIN_MAGIC 5 /* once we hit 6.0.0 I think we can remove this */
  63.  
  64. /**
  65.  * Detailed information about a plugin.
  66.  *
  67.  * This is used in the version 2.0 API and up.
  68.  */
  69. /* TODO We need to figure out exactly what parts of this are required. The
  70.  * dependent plugin unloading stuff was causing crashes with perl and tcl
  71.  * plugins because they didn't set ids and the dependency code was requiring
  72.  * them. Then we need to actually make sure that plugins have all the right
  73.  * parts before loading them. */
  74. struct _PurplePluginInfo
  75. {
  76.     unsigned int magic;
  77.     unsigned int major_version;
  78.     unsigned int minor_version;
  79.     PurplePluginType type;
  80.     char *ui_requirement;
  81.     unsigned long flags;
  82.     GList *dependencies;
  83.     PurplePluginPriority priority;
  84.  
  85.     char *id;
  86.     char *name;
  87.     char *version;
  88.     char *summary;
  89.     char *description;
  90.     char *author;
  91.     char *homepage;
  92.  
  93.     /**
  94.      * If a plugin defines a 'load' function, and it returns FALSE,
  95.      * then the plugin will not be loaded.
  96.      */
  97.     gboolean (*load)(PurplePlugin *plugin);
  98.     gboolean (*unload)(PurplePlugin *plugin);
  99.     void (*destroy)(PurplePlugin *plugin);
  100.  
  101.     void *ui_info; /**< Used only by UI-specific plugins to build a preference screen with a custom UI */
  102.     void *extra_info;
  103.     PurplePluginUiInfo *prefs_info; /**< Used by any plugin to display preferences.  If #ui_info has been specified, this will be ignored. */
  104.     GList *(*actions)(PurplePlugin *plugin, gpointer context);
  105.  
  106.     void (*_purple_reserved1)(void);
  107.     void (*_purple_reserved2)(void);
  108.     void (*_purple_reserved3)(void);
  109.     void (*_purple_reserved4)(void);
  110. };
  111.  
  112. /**
  113.  * Extra information for loader plugins.
  114.  */
  115. struct _PurplePluginLoaderInfo
  116. {
  117.     GList *exts;
  118.  
  119.     gboolean (*probe)(PurplePlugin *plugin);
  120.     gboolean (*load)(PurplePlugin *plugin);
  121.     gboolean (*unload)(PurplePlugin *plugin);
  122.     void     (*destroy)(PurplePlugin *plugin);
  123.  
  124.     void (*_purple_reserved1)(void);
  125.     void (*_purple_reserved2)(void);
  126.     void (*_purple_reserved3)(void);
  127.     void (*_purple_reserved4)(void);
  128. };
  129.  
  130. /**
  131.  * A plugin handle.
  132.  */
  133. struct _PurplePlugin
  134. {
  135.     gboolean native_plugin;                /**< Native C plugin.          */
  136.     gboolean loaded;                       /**< The loaded state.         */
  137.     void *handle;                          /**< The module handle.        */
  138.     char *path;                            /**< The path to the plugin.   */
  139.     PurplePluginInfo *info;                  /**< The plugin information.   */
  140.     char *error;
  141.     void *ipc_data;                        /**< IPC data.                 */
  142.     void *extra;                           /**< Plugin-specific data.     */
  143.     gboolean unloadable;                   /**< Unloadable                */
  144.     GList *dependent_plugins;              /**< Plugins depending on this */
  145.  
  146.     void (*_purple_reserved1)(void);
  147.     void (*_purple_reserved2)(void);
  148.     void (*_purple_reserved3)(void);
  149.     void (*_purple_reserved4)(void);
  150. };
  151.  
  152. #define PURPLE_PLUGIN_LOADER_INFO(plugin) \
  153.     ((PurplePluginLoaderInfo *)(plugin)->info->extra_info)
  154.  
  155. struct _PurplePluginUiInfo {
  156.     PurplePluginPrefFrame *(*get_plugin_pref_frame)(PurplePlugin *plugin);
  157.  
  158.     int page_num;                                         /**< Reserved */
  159.     PurplePluginPrefFrame *frame;                           /**< Reserved */
  160.  
  161.     void (*_purple_reserved1)(void);
  162.     void (*_purple_reserved2)(void);
  163.     void (*_purple_reserved3)(void);
  164.     void (*_purple_reserved4)(void);
  165. };
  166.  
  167. #define PURPLE_PLUGIN_HAS_PREF_FRAME(plugin) \
  168.     ((plugin)->info != NULL && (plugin)->info->prefs_info != NULL)
  169.  
  170. #define PURPLE_PLUGIN_UI_INFO(plugin) \
  171.     ((PurplePluginUiInfo*)(plugin)->info->prefs_info)
  172.  
  173.  
  174. /**
  175.  * The structure used in the actions member of PurplePluginInfo
  176.  */
  177. struct _PurplePluginAction {
  178.     char *label;
  179.     void (*callback)(PurplePluginAction *);
  180.  
  181.     /** set to the owning plugin */
  182.     PurplePlugin *plugin;
  183.  
  184.     /** NULL for plugin actions menu, set to the PurpleConnection for
  185.         account actions menu */
  186.     gpointer context;
  187. };
  188.  
  189. #define PURPLE_PLUGIN_HAS_ACTIONS(plugin) \
  190.     ((plugin)->info != NULL && (plugin)->info->actions != NULL)
  191.  
  192. #define PURPLE_PLUGIN_ACTIONS(plugin, context) \
  193.     (PURPLE_PLUGIN_HAS_ACTIONS(plugin)? \
  194.     (plugin)->info->actions(plugin, context): NULL)
  195.  
  196.  
  197. /**
  198.  * Handles the initialization of modules.
  199.  */
  200. #if !defined(PURPLE_PLUGINS) || defined(PURPLE_STATIC_PRPL)
  201. # define PURPLE_INIT_PLUGIN(pluginname, initfunc, plugininfo) \
  202.     gboolean purple_init_##pluginname##_plugin(void);\
  203.     gboolean purple_init_##pluginname##_plugin(void) { \
  204.         PurplePlugin *plugin = purple_plugin_new(TRUE, NULL); \
  205.         plugin->info = &(plugininfo); \
  206.         initfunc((plugin)); \
  207.         purple_plugin_load((plugin)); \
  208.         return purple_plugin_register(plugin); \
  209.     }
  210. #else /* PURPLE_PLUGINS  && !PURPLE_STATIC_PRPL */
  211. # define PURPLE_INIT_PLUGIN(pluginname, initfunc, plugininfo) \
  212.     G_MODULE_EXPORT gboolean purple_init_plugin(PurplePlugin *plugin); \
  213.     G_MODULE_EXPORT gboolean purple_init_plugin(PurplePlugin *plugin) { \
  214.         plugin->info = &(plugininfo); \
  215.         initfunc((plugin)); \
  216.         return purple_plugin_register(plugin); \
  217.     }
  218. #endif
  219.  
  220.  
  221. #ifdef __cplusplus
  222. extern "C" {
  223. #endif
  224.  
  225. /**************************************************************************/
  226. /** @name Plugin API                                                      */
  227. /**************************************************************************/
  228. /*@{*/
  229.  
  230. /**
  231.  * Creates a new plugin structure.
  232.  *
  233.  * @param native Whether or not the plugin is native.
  234.  * @param path   The path to the plugin, or @c NULL if statically compiled.
  235.  *
  236.  * @return A new PurplePlugin structure.
  237.  */
  238. PurplePlugin *purple_plugin_new(gboolean native, const char *path);
  239.  
  240. /**
  241.  * Probes a plugin, retrieving the information on it and adding it to the
  242.  * list of available plugins.
  243.  *
  244.  * @param filename The plugin's filename.
  245.  *
  246.  * @return The plugin handle.
  247.  *
  248.  * @see purple_plugin_load()
  249.  * @see purple_plugin_destroy()
  250.  */
  251. PurplePlugin *purple_plugin_probe(const char *filename);
  252.  
  253. /**
  254.  * Registers a plugin and prepares it for loading.
  255.  *
  256.  * This shouldn't be called by anything but the internal module code.
  257.  * Plugins should use the PURPLE_INIT_PLUGIN() macro to register themselves
  258.  * with the core.
  259.  *
  260.  * @param plugin The plugin to register.
  261.  *
  262.  * @return @c TRUE if the plugin was registered successfully.  Otherwise
  263.  *         @c FALSE is returned (this happens if the plugin does not contain
  264.  *         the necessary information).
  265.  */
  266. gboolean purple_plugin_register(PurplePlugin *plugin);
  267.  
  268. /**
  269.  * Attempts to load a previously probed plugin.
  270.  *
  271.  * @param plugin The plugin to load.
  272.  *
  273.  * @return @c TRUE if successful, or @c FALSE otherwise.
  274.  *
  275.  * @see purple_plugin_reload()
  276.  * @see purple_plugin_unload()
  277.  */
  278. gboolean purple_plugin_load(PurplePlugin *plugin);
  279.  
  280. /**
  281.  * Unloads the specified plugin.
  282.  *
  283.  * @param plugin The plugin handle.
  284.  *
  285.  * @return @c TRUE if successful, or @c FALSE otherwise.
  286.  *
  287.  * @see purple_plugin_load()
  288.  * @see purple_plugin_reload()
  289.  */
  290. gboolean purple_plugin_unload(PurplePlugin *plugin);
  291.  
  292. /**
  293.  * Reloads a plugin.
  294.  *
  295.  * @param plugin The old plugin handle.
  296.  *
  297.  * @return @c TRUE if successful, or @c FALSE otherwise.
  298.  *
  299.  * @see purple_plugin_load()
  300.  * @see purple_plugin_unload()
  301.  */
  302. gboolean purple_plugin_reload(PurplePlugin *plugin);
  303.  
  304. /**
  305.  * Unloads a plugin and destroys the structure from memory.
  306.  *
  307.  * @param plugin The plugin handle.
  308.  */
  309. void purple_plugin_destroy(PurplePlugin *plugin);
  310.  
  311. /**
  312.  * Returns whether or not a plugin is currently loaded.
  313.  *
  314.  * @param plugin The plugin.
  315.  *
  316.  * @return @c TRUE if loaded, or @c FALSE otherwise.
  317.  */
  318. gboolean purple_plugin_is_loaded(const PurplePlugin *plugin);
  319.  
  320. /**
  321.  * Returns whether or not a plugin is unloadable.
  322.  *
  323.  * If this returns @c TRUE, the plugin is guaranteed to not
  324.  * be loadable. However, a return value of @c FALSE does not
  325.  * guarantee the plugin is loadable.
  326.  *
  327.  * @param plugin The plugin.
  328.  *
  329.  * @return @c TRUE if the plugin is known to be unloadable,\
  330.  *         @c FALSE otherwise
  331.  */
  332. gboolean purple_plugin_is_unloadable(const PurplePlugin *plugin);
  333.  
  334. /**
  335.  * Returns a plugin's id.
  336.  *
  337.  * @param plugin The plugin.
  338.  *
  339.  * @return The plugin's id.
  340.  */
  341. const gchar *purple_plugin_get_id(const PurplePlugin *plugin);
  342.  
  343. /**
  344.  * Returns a plugin's name.
  345.  *
  346.  * @param plugin The plugin.
  347.  * 
  348.  * @return THe name of the plugin, or @c NULL.
  349.  */
  350. const gchar *purple_plugin_get_name(const PurplePlugin *plugin);
  351.  
  352. /**
  353.  * Returns a plugin's version.
  354.  *
  355.  * @param plugin The plugin.
  356.  *
  357.  * @return The plugin's version or @c NULL.
  358.  */
  359. const gchar *purple_plugin_get_version(const PurplePlugin *plugin);
  360.  
  361. /**
  362.  * Returns a plugin's summary.
  363.  *
  364.  * @param plugin The plugin.
  365.  *
  366.  * @return The plugin's summary.
  367.  */
  368. const gchar *purple_plugin_get_summary(const PurplePlugin *plugin);
  369.  
  370. /**
  371.  * Returns a plugin's description.
  372.  *
  373.  * @param plugin The plugin.
  374.  *
  375.  * @return The plugin's description.
  376.  */
  377. const gchar *purple_plugin_get_description(const PurplePlugin *plugin);
  378.  
  379. /**
  380.  * Returns a plugin's author.
  381.  *
  382.  * @param plugin The plugin.
  383.  *
  384.  * @return The plugin's author.
  385.  */
  386. const gchar *purple_plugin_get_author(const PurplePlugin *plugin);
  387.  
  388. /**
  389.  * Returns a plugin's homepage.
  390.  *
  391.  * @param plugin The plugin.
  392.  *
  393.  * @return The plugin's homepage.
  394.  */
  395. const gchar *purple_plugin_get_homepage(const PurplePlugin *plugin);
  396.  
  397. /*@}*/
  398.  
  399. /**************************************************************************/
  400. /** @name Plugin IPC API                                                  */
  401. /**************************************************************************/
  402. /*@{*/
  403.  
  404. /**
  405.  * Registers an IPC command in a plugin.
  406.  *
  407.  * @param plugin     The plugin to register the command with.
  408.  * @param command    The name of the command.
  409.  * @param func       The function to execute.
  410.  * @param marshal    The marshalling function.
  411.  * @param ret_value  The return value type.
  412.  * @param num_params The number of parameters.
  413.  * @param ...        The parameter types.
  414.  *
  415.  * @return TRUE if the function was registered successfully, or
  416.  *         FALSE otherwise.
  417.  */
  418. gboolean purple_plugin_ipc_register(PurplePlugin *plugin, const char *command,
  419.                                   PurpleCallback func,
  420.                                   PurpleSignalMarshalFunc marshal,
  421.                                   PurpleValue *ret_value, int num_params, ...);
  422.  
  423. /**
  424.  * Unregisters an IPC command in a plugin.
  425.  *
  426.  * @param plugin  The plugin to unregister the command from.
  427.  * @param command The name of the command.
  428.  */
  429. void purple_plugin_ipc_unregister(PurplePlugin *plugin, const char *command);
  430.  
  431. /**
  432.  * Unregisters all IPC commands in a plugin.
  433.  *
  434.  * @param plugin The plugin to unregister the commands from.
  435.  */
  436. void purple_plugin_ipc_unregister_all(PurplePlugin *plugin);
  437.  
  438. /**
  439.  * Returns a list of value types used for an IPC command.
  440.  *
  441.  * @param plugin     The plugin.
  442.  * @param command    The name of the command.
  443.  * @param ret_value  The returned return value.
  444.  * @param num_params The returned number of parameters.
  445.  * @param params     The returned list of parameters.
  446.  *
  447.  * @return TRUE if the command was found, or FALSE otherwise.
  448.  */
  449. gboolean purple_plugin_ipc_get_params(PurplePlugin *plugin, const char *command,
  450.                                     PurpleValue **ret_value, int *num_params,
  451.                                     PurpleValue ***params);
  452.  
  453. /**
  454.  * Executes an IPC command.
  455.  *
  456.  * @param plugin  The plugin to execute the command on.
  457.  * @param command The name of the command.
  458.  * @param ok      TRUE if the call was successful, or FALSE otherwise.
  459.  * @param ...     The parameters to pass.
  460.  *
  461.  * @return The return value, which will be NULL if the command doesn't
  462.  *         return a value.
  463.  */
  464. void *purple_plugin_ipc_call(PurplePlugin *plugin, const char *command,
  465.                            gboolean *ok, ...);
  466.  
  467. /*@}*/
  468.  
  469. /**************************************************************************/
  470. /** @name Plugins API                                                     */
  471. /**************************************************************************/
  472. /*@{*/
  473.  
  474. /**
  475.  * Add a new directory to search for plugins
  476.  *
  477.  * @param path The new search path.
  478.  */
  479. void purple_plugins_add_search_path(const char *path);
  480.  
  481. /**
  482.  * Unloads all loaded plugins.
  483.  */
  484. void purple_plugins_unload_all(void);
  485.  
  486. /**
  487.  * Destroys all registered plugins.
  488.  */
  489. void purple_plugins_destroy_all(void);
  490.  
  491. /**
  492.  * Saves the list of loaded plugins to the specified preference key
  493.  *
  494.  * @param key The preference key to save the list of plugins to.
  495.  */
  496. void purple_plugins_save_loaded(const char *key);
  497.  
  498. /**
  499.  * Attempts to load all the plugins in the specified preference key
  500.  * that were loaded when purple last quit.
  501.  *
  502.  * @param key The preference key containing the list of plugins.
  503.  */
  504. void purple_plugins_load_saved(const char *key);
  505.  
  506. /**
  507.  * Probes for plugins in the registered module paths.
  508.  *
  509.  * @param ext The extension type to probe for, or @c NULL for all.
  510.  *
  511.  * @see purple_plugin_set_probe_path()
  512.  */
  513. void purple_plugins_probe(const char *ext);
  514.  
  515. /**
  516.  * Returns whether or not plugin support is enabled.
  517.  *
  518.  * @return TRUE if plugin support is enabled, or FALSE otherwise.
  519.  */
  520. gboolean purple_plugins_enabled(void);
  521.  
  522. /**
  523.  * Registers a function that will be called when probing is finished.
  524.  *
  525.  * @param func The callback function.
  526.  * @param data Data to pass to the callback.
  527.  */
  528. void purple_plugins_register_probe_notify_cb(void (*func)(void *), void *data);
  529.  
  530. /**
  531.  * Unregisters a function that would be called when probing is finished.
  532.  *
  533.  * @param func The callback function.
  534.  */
  535. void purple_plugins_unregister_probe_notify_cb(void (*func)(void *));
  536.  
  537. /**
  538.  * Registers a function that will be called when a plugin is loaded.
  539.  *
  540.  * @param func The callback function.
  541.  * @param data Data to pass to the callback.
  542.  */
  543. void purple_plugins_register_load_notify_cb(void (*func)(PurplePlugin *, void *),
  544.                                           void *data);
  545.  
  546. /**
  547.  * Unregisters a function that would be called when a plugin is loaded.
  548.  *
  549.  * @param func The callback function.
  550.  */
  551. void purple_plugins_unregister_load_notify_cb(void (*func)(PurplePlugin *, void *));
  552.  
  553. /**
  554.  * Registers a function that will be called when a plugin is unloaded.
  555.  *
  556.  * @param func The callback function.
  557.  * @param data Data to pass to the callback.
  558.  */
  559. void purple_plugins_register_unload_notify_cb(void (*func)(PurplePlugin *, void *),
  560.                                             void *data);
  561.  
  562. /**
  563.  * Unregisters a function that would be called when a plugin is unloaded.
  564.  *
  565.  * @param func The callback function.
  566.  */
  567. void purple_plugins_unregister_unload_notify_cb(void (*func)(PurplePlugin *,
  568.                                                            void *));
  569.  
  570. /**
  571.  * Finds a plugin with the specified name.
  572.  *
  573.  * @param name The plugin name.
  574.  *
  575.  * @return The plugin if found, or @c NULL if not found.
  576.  */
  577. PurplePlugin *purple_plugins_find_with_name(const char *name);
  578.  
  579. /**
  580.  * Finds a plugin with the specified filename (filename with a path).
  581.  *
  582.  * @param filename The plugin filename.
  583.  *
  584.  * @return The plugin if found, or @c NULL if not found.
  585.  */
  586. PurplePlugin *purple_plugins_find_with_filename(const char *filename);
  587.  
  588. /**
  589.  * Finds a plugin with the specified basename (filename without a path).
  590.  *
  591.  * @param basename The plugin basename.
  592.  *
  593.  * @return The plugin if found, or @c NULL if not found.
  594.  */
  595. PurplePlugin *purple_plugins_find_with_basename(const char *basename);
  596.  
  597. /**
  598.  * Finds a plugin with the specified plugin ID.
  599.  *
  600.  * @param id The plugin ID.
  601.  *
  602.  * @return The plugin if found, or @c NULL if not found.
  603.  */
  604. PurplePlugin *purple_plugins_find_with_id(const char *id);
  605.  
  606. /**
  607.  * Returns a list of all loaded plugins.
  608.  *
  609.  * @return A list of all loaded plugins.
  610.  */
  611. GList *purple_plugins_get_loaded(void);
  612.  
  613. /**
  614.  * Returns a list of all valid protocol plugins.  A protocol
  615.  * plugin is considered invalid if it does not contain the call
  616.  * to the PURPLE_INIT_PLUGIN() macro, or if it was compiled
  617.  * against an incompatable API version.
  618.  *
  619.  * @return A list of all protocol plugins.
  620.  */
  621. GList *purple_plugins_get_protocols(void);
  622.  
  623. /**
  624.  * Returns a list of all plugins, whether loaded or not.
  625.  *
  626.  * @return A list of all plugins.
  627.  */
  628. GList *purple_plugins_get_all(void);
  629.  
  630. /*@}*/
  631.  
  632. /**************************************************************************/
  633. /** @name Plugins SubSytem API                                            */
  634. /**************************************************************************/
  635. /*@{*/
  636.  
  637. /**
  638.  * Returns the plugin subsystem handle.
  639.  *
  640.  * @return The plugin sybsystem handle.
  641.  */
  642. void *purple_plugins_get_handle(void);
  643.  
  644. /**
  645.  * Initializes the plugin subsystem
  646.  */
  647. void purple_plugins_init(void);
  648.  
  649. /**
  650.  * Uninitializes the plugin subsystem
  651.  */
  652. void purple_plugins_uninit(void);
  653.  
  654. /*@}*/
  655.  
  656. /**
  657.  * Allocates and returns a new PurplePluginAction.
  658.  *
  659.  * @param label    The description of the action to show to the user.
  660.  * @param callback The callback to call when the user selects this action.
  661.  */
  662. PurplePluginAction *purple_plugin_action_new(const char* label, void (*callback)(PurplePluginAction *));
  663.  
  664. /**
  665.  * Frees a PurplePluginAction
  666.  *
  667.  * @param action The PurplePluginAction to free.
  668.  */
  669. void purple_plugin_action_free(PurplePluginAction *action);
  670.  
  671. #ifdef __cplusplus
  672. }
  673. #endif
  674.  
  675. #endif /* _PURPLE_PLUGIN_H_ */
  676.