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/CommandAPIHowTo


Ignore:
Timestamp:
Nov 13, 2009, 5:31:25 AM (14 years ago)
Author:
hamiltont
Comment:

initial version to be improved upon

Legend:

Unmodified
Added
Removed
Modified
  • CHowTo/CommandAPIHowTo

    v1 v2  
    11= Command API How-To =
    22
    3 The command API is a method by which you can add commands to libpurple clients.  Pidgin and Finch use the / character to denote a command, much like many IRC clients.  This document will explain how to make your plugin add commands.
     3The command API is a method by which you can add commands to libpurple clients.  Pidgin and Finch use the / character to denote a command, much like many IRC clients.  This document will explain how to make your plugin add commands. Again we will assume that you have completed the [wiki:CHowTo/BasicPluginHowto Basic C Plugin Howto].  We'll also continue to assume that you're using Pidgin 2.0.2 for these How-To documents as described there.
     4
    45
    56''This document is incomplete.  It has been saved to the wiki to ensure the current work is not lost.  It should be finished soon.''
     7
     8== About the Command API ==
     9The full command API documentation can be found at [http://developer.pidgin.im/doxygen/2.5.2/html/cmds_8h.html cmds.h]. The API allows commands to specify priority, to allow proper handling of chained commands (aka, to create an order of operations). The API allows for flexible command arguments, from a single argument to multiple complex arguments.
     10
     11== Writing the Example Plugin ==
     12
     13{{{
     14#!c
     15/*
     16 * Command Example Plugin
     17 *
     18 * Copyright (C) 2009, Hamilton Turner <hamiltont@gmail.com>
     19 *
     20 * This program is free software; you can redistribute it and/or
     21 * modify it under the terms of the GNU General Public License as
     22 * published by the Free Software Foundation; either version 2 of the
     23 * License, or (at your option) any later version.
     24 *
     25 * This program is distributed in the hope that it will be useful, but
     26 * WITHOUT ANY WARRANTY; without even the implied warranty of
     27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     28 * General Public License for more details.
     29 *
     30 * You should have received a copy of the GNU General Public License
     31 * along with this program; if not, write to the Free Software
     32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     33 * 02111-1301, USA.
     34 *
     35 */
     36
     37#ifdef HAVE_CONFIG_H
     38# include <config.h>
     39#endif
     40
     41/* Include glib.h for various types */
     42#include <glib.h>
     43
     44/* This will prevent compiler errors in some instances and is better explained in the
     45 * how-to documents on the wiki */
     46#ifndef G_GNUC_NULL_TERMINATED
     47# if __GNUC__ >= 4
     48#  define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
     49# else
     50#  define G_GNUC_NULL_TERMINATED
     51# endif
     52#endif
     53
     54/* This is the required definition of PURPLE_PLUGINS as required for a plugin,
     55 * but we protect it with an #ifndef because config.h may define it for us
     56 * already and this would cause an unneeded compiler warning. */
     57#ifndef PURPLE_PLUGINS
     58# define PURPLE_PLUGINS
     59#endif
     60
     61/* Here we're including the necessary libpurple headers for this plugin.  Note
     62 * that we're including them in alphabetical order.  This isn't necessary but
     63 * we do this throughout our source for consistency. */
     64#include "cmds.h"
     65#include "debug.h"
     66#include "plugin.h"
     67#include "notify.h"
     68#include "version.h"
     69
     70/* It's more convenient to type PLUGIN_ID all the time than it is to type
     71 * "core-commandexample", so define this convenience macro. */
     72#define PLUGIN_ID "core-commandexample"
     73
     74/* Common practice in third-party plugins is to define convenience macros for
     75 * many of the fields of the plugin info struct, so we'll do that for the
     76 * purposes of demonstration. */
     77#define PLUGIN_AUTHOR "Hamilton Turner <hamiltont@gmail.com>"
     78
     79/* Initialized in the plugin_load() method, this allows us to keep a handle to
     80 * ourself */
     81static PurplePlugin *command_example = NULL;
     82
     83
     84/* The callback function for our /debug command. This function simply prints
     85 * whatever was entered as the argument to the debug command into the debug
     86 * log. */
     87static PurpleCmdRet
     88debug_cb(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data)
     89{
     90  purple_debug_misc(PLUGIN_ID, "debug_cb called\n");
     91  purple_debug_misc(PLUGIN_ID, "message = %s\n", args[0]);
     92
     93  return PURPLE_CMD_RET_OK;
     94
     95}
     96
     97/* The callback function for our /notify command. This function simply pops up
     98 * a notification with the word entered as the argument to the command */
     99static PurpleCmdRet
     100notify_cb(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data)
     101{
     102
     103  purple_notify_info(command_example,
     104                     "Notify Notification Title",
     105                     "Notify Notification Primary Text",
     106                     args[0]);   /* Secondary text is the word entered */
     107
     108  return PURPLE_CMD_RET_OK;
     109
     110}
     111
     112
     113
     114
     115/* As we've covered before, libpurple calls this function, if present, when it
     116 * loads the plugin.  Here we're using it to show off the capabilities of the
     117 * debug API and just blindly returning TRUE to tell libpurple it's safe to
     118 * continue loading. */
     119static gboolean
     120plugin_load(PurplePlugin *plugin)
     121{
     122  /* Declare all vars up front. Avoids warnings on some compilers */
     123  gchar *debug_help = NULL;
     124  gchar *notify_help = NULL;
     125 
     126  /* Save a handle to ourself for later */
     127  command_example = plugin;
     128
     129  /* Help message for debug command, in the correct format */
     130  debug_help = "debug &lt;debug message here&gt;:  Prints a message to the debug log.";
     131
     132  /* Register a command to allow a user to enter /debug some message and have
     133   * that message stored to the log. This command runs with default priority,
     134   * can only be used in a standard chat message, not while in group chat
     135   * mode */
     136  purple_cmd_register
     137    ("debug",                       /* command name */
     138     "s",                           /* command arguments */
     139     PURPLE_CMD_P_DEFAULT,          /* command priority */ 
     140     PURPLE_CMD_FLAG_IM,            /* flags saying where
     141                                       command can be used */
     142     
     143     NULL,                          /* We do not need to pass
     144                                       plugin ID */
     145     
     146     debug_cb,                      /* Name of the callback
     147                                       function */
     148     debug_help,
     149
     150     NULL                           /* We do not need any special
     151                                       user defined data here */
     152     );
     153       
     154
     155  /* Help message for debug command, in the correct format */
     156  notify_help = "notify &lt;notify word here&gt;:  Pops up a notification with the word you enter.";
     157
     158
     159  /* Register a command to allow a user to enter /notify some word and have
     160   * that word notified back to them. This command runs with high priority,
     161   * can only be used both in group and standard chat messages */
     162  purple_cmd_register
     163    ("notify",                      /* command name */
     164     "w",                           /* command arguments */
     165     PURPLE_CMD_P_HIGH,             /* command priority */ 
     166     PURPLE_CMD_FLAG_IM |
     167       PURPLE_CMD_FLAG_CHAT,        /* flags saying where
     168                                       command can be used */
     169     
     170     NULL,                          /* We do not need to pass
     171                                       plugin ID */
     172     
     173     notify_cb,                     /* Name of the callback
     174                                       function */
     175     notify_help,
     176
     177     NULL                           /* We do not need any special
     178                                       user defined data here */
     179     );
     180 
     181
     182  /* Just return true to tell libpurple to finish loading. */
     183  return TRUE;
     184}
     185
     186static PurplePluginInfo info = {
     187        PURPLE_PLUGIN_MAGIC,        /* magic number */
     188        PURPLE_MAJOR_VERSION,       /* purple major */
     189        PURPLE_MINOR_VERSION,       /* purple minor */
     190        PURPLE_PLUGIN_STANDARD,     /* plugin type */
     191        NULL,                       /* UI requirement */
     192        0,                          /* flags */
     193        NULL,                       /* dependencies */
     194        PURPLE_PRIORITY_DEFAULT,    /* priority */
     195
     196        PLUGIN_ID,                  /* id */
     197        "Command API Example",      /* name */
     198        DISPLAY_VERSION,            /* version */
     199        "Command API Example",      /* summary */
     200        "Command API Example",      /* description */
     201        PLUGIN_AUTHOR,              /* author */
     202        "http://pidgin.im",         /* homepage */
     203
     204        plugin_load,                /* load */
     205        NULL,                       /* unload */
     206        NULL,                       /* destroy */
     207
     208        NULL,                       /* ui info */
     209        NULL,                       /* extra info */
     210        NULL,                       /* prefs info */
     211        NULL,                       /* actions */
     212        NULL,                       /* reserved */
     213        NULL,                       /* reserved */
     214        NULL,                       /* reserved */
     215        NULL                        /* reserved */
     216};
     217
     218static void
     219init_plugin(PurplePlugin *plugin)
     220{
     221}
     222
     223PURPLE_INIT_PLUGIN(debugexample, init_plugin, info)
     224
     225}}}
     226
     227
     228== Compiling, Installing, and Testing the Plugin ==
     229As before, run make command_example.so (make -f Makefile.mingw command_example.dll for you Windows types) to build the plugin. Copy the resulting command_example.so to ~/.purple/plugins, or copy the resulting command_example.dll to %APPDATA%\.purple\plugins.
     230
     231To test (we will assume you are using Pidgin), go to Tools->Plugins and enable the Command API Example plugin. Also, go to Help->Debug Window to show the Debug Window. Open an IM chat session, and type ''/debug my debug message here''. Your message should show up in the debug window. Then type ''/notify Hello!''. You should receive a notification box saying Hello! Also, be sure to try ''/notify Hello World!'' and not that the command fails, because you input multiple arguments (2) when it was only expecting a single value.
     232
     233== Beyond the Command API ==
     234The command API provides a basic command framework for plugins, which can be an extremely valuable resource to plugin authors.  The other areas we didn't cover here include much of the true power of the command API, but we will leave those as an area for your exploration at least for now.  This document is done, but there are still others in the [wiki:CHowTo C Plugin How-To] for you to explore!
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!