Trac is being migrated to new services! Issues can be found in our new YouTrack instance and WIKI pages can be found on our website.

Changes between Version 1 and Version 2 of CHowTo/PluginActionsHowTo


Ignore:
Timestamp:
Jul 16, 2007, 4:44:38 PM (17 years ago)
Author:
John Bailey
Comment:

A basic plugin actions how-to document.

Legend:

Unmodified
Added
Removed
Modified
  • CHowTo/PluginActionsHowTo

    v1 v2  
    11= Plugin Actions How-To =
    2 This page is a placeholder pending the completion of this document.
     2This document will explain how to use Plugin Actions to enable your plugins to provide additional functionality to a libpurple client.  We will assume that you have completed the [wiki:CHowTo/BasicPluginHowto Basic C Plugin How-To] and have the `helloworld.c` file in `~/development/pidgin-2.0.2/libpurple/plugins`
     3
     4[[TOC(inline,noheading)]]
     5
     6== About Plugin Actions ==
     7a Plugin Action allows you to add additional functionality to a libpurple UI.  Where the functionality appears depends on the UI.  In Pidgin, for example, each plugin's actions appear as a submenu in the Tools menu of the Buddy List window, with the submenu's title being the plugin's name (as described in the initial Hello, World! plugin).
     8
     9Many plugins choose to use plugin actions to introduce their functionality.  The I'dle Mak'er plugin distributed with the Pidgin source code implements its functionality using a combination of plugin actions and the request API.  The List Handler plugin, a third-party plugin, does this as well.  Plugin actions are a flexible mechanism to introduce new functionality that isn't conversation-specific or may not exactly fit anywhere else.
     10
     11== Your First Plugin Action ==
     12Let's open up the `helloworld.c` file with your favorite editor again.  We're going to change it to add a couple new functions as well as a global variable.  The comments in the new additions explain what each addition is for.
     13 {{{
     14#!c
     15#define PURPLE_PLUGINS
     16
     17#include <glib.h>
     18
     19#include "notify.h"
     20#include "plugin.h"
     21#include "version.h"
     22
     23/* we're adding this here and assigning it in plugin_load because we need
     24 * a valid plugin handle for our call to purple_notify_message() in the
     25 * plugin_action_test_cb() callback function */
     26PurplePlugin *helloworld_plugin = NULL;
     27
     28/* This function is the callback for the plugin action we added. All we're
     29 * doing here is displaying a message. When the user selects the plugin
     30 * action, this function is called. */
     31static void
     32plugin_action_test_cb(PurplePluginAction *action)
     33{
     34    purple_notify_message(helloworld_plugin, PURPLE_NOTIFY_MSG_INFO,
     35            "Plugin Actions Test", "This is a plugin actions test :)",
     36            NULL, NULL, NULL);
     37}
     38
     39/* we tell libpurple in the PurplePluginInfo struct to call this function to
     40 * get a list of plugin actions to use for the plugin.  This function gives
     41 * libpurple that list of actions. */
     42static GList *
     43plugin_actions(PurplePlugin *plugin, gpointer context)
     44{
     45    /* some C89 (a.k.a. ANSI C) compilers will warn if any variable declaration
     46     * includes an initilization that calls a function.  To avoid that, we
     47     * generally initialize our variables first with constant values like NULL
     48     * or 0 and assign to them with function calls later */
     49    GList *list = NULL;
     50    PurplePluginAction *action = NULL;
     51
     52    /* The action gets created by specifying a name to show in the UI and a
     53     * callback function to call. */
     54    action = purple_plugin_action_new("Plugin Action Test", plugin_action_test_cb);
     55
     56    /* libpurple requires a GList of plugin actions, even if there is only one
     57     * action in the list.  We append the action to a GList here. */
     58    list = g_list_append(list, action);
     59
     60    /* Once the list is complete, we send it to libpurple. */
     61    return list;
     62}
     63
     64static gboolean
     65plugin_load(PurplePlugin *plugin) {
     66    purple_notify_message(plugin, PURPLE_NOTIFY_MSG_INFO, "Hello World!",
     67            "This is the Hello World! plugin :)", NULL, NULL, NULL);
     68
     69    helloworld_plugin = plugin; /* assign this here so we have a valid handle later */
     70
     71    return TRUE;
     72}
     73
     74static PurplePluginInfo info = {
     75    PURPLE_PLUGIN_MAGIC,
     76    PURPLE_MAJOR_VERSION,
     77    PURPLE_MINOR_VERSION,
     78    PURPLE_PLUGIN_STANDARD,
     79    NULL,
     80    0,
     81    NULL,
     82    PURPLE_PRIORITY_DEFAULT,
     83
     84    "core-hello_world",
     85    "Hello World!",
     86    "1.1",
     87
     88    "Hello World Plugin",
     89    "Hello World Plugin",
     90    "My Name <email@helloworld.tld>",
     91    "http://helloworld.tld",
     92
     93
     94    plugin_load,
     95    NULL,
     96    NULL,
     97
     98    NULL,
     99    NULL,
     100    NULL,
     101    plugin_actions, /* this tells libpurple the address of the function to call
     102                       to get the list of plugin actions. */
     103    NULL,
     104    NULL,
     105    NULL,
     106    NULL
     107};
     108
     109static void
     110init_plugin(PurplePlugin *plugin)
     111{
     112}
     113
     114PURPLE_INIT_PLUGIN(hello_world, init_plugin, info)
     115 }}}
     116
     117== Compile and Install the Plugin Again ==
     118Now that we've modified the source of the plugin, we need to compile it again.  Use `make helloworld.so` (or `make -f Makefile.mingw helloworld.dll` on Windows) to compile the plugin.  Again copy it to the appropriate plugins directory (`~/.purple/plugins` on UNIX-like systems or `%APPDATA%\.purple\plugins` on Windows).
     119
     120If you still have this plugin loaded from the last how-to document, unload it.  This step isn't strictly necessary, but will prevent an unwanted dialog from popping up when you start your libpurple client.  You will probably want to unload the plugin again after this test is complete.
     121
     122Now you need to restart your libpurple client, because libpurple doesn't detect ''updated'' C plugins when you open the Plugins dialog in your libpurple client; it detects only new ones.  Since Hello, World! probably already existed in the plugin list, you need to restart the application to force libpurple to recognize the updated version of the plugin.
     123
     124== Testing the Plugin Action ==
     125To test the new plugin action, load the plugin.  Now you'll see the familiar popup that appears when plugin_load is called.  You can dismiss this dialog.  Now go to where your libpurple client shows plugin actions.  For the purpose of this test we will assume you are using Pidgin.  This means our plugin action will be shown on the Tools menu of the buddy list window, with a submenu called "Hello World!".  The sole entry in this submenu is our action, "Plugin Action Test".
     126
     127Selecting "Plugin Action Test" will display a dialog similar to the one shown at plugin load.  If you got this, you have successfully written your first plugin action!
     128
     129== The Other Plugin Actions Function ==
     130Libpurple provides one other function to deal with plugin actions, `purple_plugin_action_free()`.  This function will deallocate the memory that was allocated when you created a plugin action.  You don't really need to worry about this function, however, because libpurple automatically calls it when appropriate.
     131
     132== Beyond Plugin Actions ==
     133Plugin actions are only the tip of the iceberg for plugin functionality.  Keep reading the other documents in the [wiki:CHowTo C Plugin How-To] to learn more about the facilities libpurple provides for plugins to extend its capabilities.
All information, including names and email addresses, entered onto this website or sent to mailing lists affiliated with this website will be public. Do not post confidential information, especially passwords!