/pidgin/main: e61fe608aa81: Merged in dequisdequis/pidgin/releas...
Gary Kramlich
grim at reaperworld.com
Wed Jun 15 23:05:08 EDT 2016
Changeset: e61fe608aa817a547c989c01048788336822580a
Author: Gary Kramlich <grim at reaperworld.com>
Date: 2016-06-15 21:59 -0500
Branch: release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/e61fe608aa81
Description:
Merged in dequisdequis/pidgin/release-2.x.y (pull request #51)
Add PurpleCommandsUiOps API from instantbird
diffstat:
ChangeLog.API | 2 +
libpurple/cmds.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++-
libpurple/cmds.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 125 insertions(+), 4 deletions(-)
diffs (233 lines):
diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -5,6 +5,8 @@ version 2.11.0:
Added:
* account-status-changing signal (account signals)
* buddy-removed-from-group signal (blist signals)
+ * PurpleCommandsUiOps, to allow the UI to override the
+ built-in handling of commands.
version 2.10.12:
* No changes
diff --git a/libpurple/cmds.c b/libpurple/cmds.c
--- a/libpurple/cmds.c
+++ b/libpurple/cmds.c
@@ -27,10 +27,11 @@
#include "util.h"
#include "cmds.h"
+static PurpleCommandsUiOps *cmds_ui_ops = NULL;
static GList *cmds = NULL;
static guint next_id = 1;
-typedef struct _PurpleCmd {
+struct _PurpleCmd {
PurpleCmdId id;
gchar *cmd;
gchar *args;
@@ -40,7 +41,7 @@ typedef struct _PurpleCmd {
PurpleCmdFunc func;
gchar *help;
void *data;
-} PurpleCmd;
+};
static gint cmds_compare_func(const PurpleCmd *a, const PurpleCmd *b)
@@ -59,6 +60,7 @@ PurpleCmdId purple_cmd_register(const gc
{
PurpleCmdId id;
PurpleCmd *c;
+ PurpleCommandsUiOps *ops;
g_return_val_if_fail(cmd != NULL && *cmd != '\0', 0);
g_return_val_if_fail(args != NULL, 0);
@@ -79,6 +81,10 @@ PurpleCmdId purple_cmd_register(const gc
cmds = g_list_insert_sorted(cmds, c, (GCompareFunc)cmds_compare_func);
+ ops = purple_cmds_get_ui_ops();
+ if (ops && ops->register_command)
+ ops->register_command(cmd, p, f, prpl_id, helpstr, c);
+
purple_signal_emit(purple_cmds_get_handle(), "cmd-added", cmd, p, f);
return id;
@@ -102,6 +108,10 @@ void purple_cmd_unregister(PurpleCmdId i
c = l->data;
if (c->id == id) {
+ PurpleCommandsUiOps *ops = purple_cmds_get_ui_ops();
+ if (ops && ops->unregister_command)
+ ops->unregister_command(c->cmd, c->prpl_id);
+
cmds = g_list_remove(cmds, c);
purple_signal_emit(purple_cmds_get_handle(), "cmd-removed", c->cmd);
purple_cmd_free(c);
@@ -301,6 +311,39 @@ PurpleCmdStatus purple_cmd_do_command(Pu
}
+gboolean purple_cmd_execute(PurpleCmd *c, PurpleConversation *conv,
+ const gchar *cmdline)
+{
+ gchar *err = NULL;
+ gchar **args = NULL;
+ PurpleCmdRet ret = PURPLE_CMD_RET_CONTINUE;
+
+ if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ if (!(c->flags & PURPLE_CMD_FLAG_IM))
+ return FALSE;
+ }
+ else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+ if (!(c->flags & PURPLE_CMD_FLAG_CHAT))
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+ /* XXX: Don't worry much about the markup version of the command
+ line, there's not a single use case... */
+ /* this checks the allow bad args flag for us */
+ if (!purple_cmd_parse_args(c, cmdline, cmdline, &args)) {
+ g_strfreev(args);
+ return FALSE;
+ }
+
+ ret = c->func(conv, c->cmd, args, &err, c->data);
+
+ g_free(err);
+ g_strfreev(args);
+
+ return ret == PURPLE_CMD_RET_OK;
+}
GList *purple_cmd_list(PurpleConversation *conv)
{
@@ -368,6 +411,21 @@ gpointer purple_cmds_get_handle(void)
return &handle;
}
+void
+purple_cmds_set_ui_ops(PurpleCommandsUiOps *ops)
+{
+ cmds_ui_ops = ops;
+}
+
+PurpleCommandsUiOps *
+purple_cmds_get_ui_ops(void)
+{
+ /* It is perfectly acceptable for cmds_ui_ops to be NULL; this just
+ * means that the default libpurple implementation will be used.
+ */
+ return cmds_ui_ops;
+}
+
void purple_cmds_init(void)
{
gpointer handle = purple_cmds_get_handle();
diff --git a/libpurple/cmds.h b/libpurple/cmds.h
--- a/libpurple/cmds.h
+++ b/libpurple/cmds.h
@@ -31,6 +31,8 @@
/**************************************************************************/
/*@{*/
+typedef struct _PurpleCmd PurpleCmd;
+
/** The possible results of running a command with purple_cmd_do_command(). */
typedef enum _PurpleCmdStatus {
PURPLE_CMD_STATUS_OK,
@@ -96,6 +98,31 @@ typedef enum _PurpleCmdFlag {
PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS = 0x08
} PurpleCmdFlag;
+/**
+ * Command UI operations; UIs should implement this if they want to handle
+ * commands themselves, rather than relying on the core.
+ *
+ * @see @ref ui-ops
+ */
+typedef struct
+{
+ /** If implemented, the UI is responsible for handling commands. */
+ /* @see purple_cmd_register for the argument values. */
+ void (*register_command)(const gchar *name, PurpleCmdPriority priority,
+ PurpleCmdFlag flags, const gchar *prpl_id,
+ const gchar *help, PurpleCmd *cmd);
+
+ /** Should be implemented if register_command is implemented.
+ * name and prpl_id will have the same value that were used
+ * for the register_command call.
+ */
+ void (*unregister_command)(const gchar *name, const gchar *prpl_id);
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+} PurpleCommandsUiOps;
/*@}*/
@@ -182,9 +209,9 @@ void purple_cmd_unregister(PurpleCmdId i
* @param cmdline The command the user typed (including all arguments) as a single string.
* The caller doesn't have to do any parsing, except removing the command
* prefix, which the core has no knowledge of. cmd should not contain any
- * formatting, and should be in plain text (no html entities).
+ * formatting, and should be in plain text (no HTML entities).
* @param markup This is the same as cmd, but is the formatted version. It should be in
- * HTML, with < > and &, at least, escaped to html entities, and should
+ * HTML, with < > and &, at least, escaped to HTML entities, and should
* include both the default formatting and any extra manual formatting.
* @param errormsg If the command failed errormsg is filled in with the appropriate error
* message. It must be freed by the caller with g_free().
@@ -194,6 +221,23 @@ PurpleCmdStatus purple_cmd_do_command(Pu
const gchar *markup, gchar **errormsg);
/**
+ * Execute a specific command.
+ *
+ * The UI calls this to execute a command, after parsing the
+ * command name.
+ *
+ * @param c The command to execute.
+ * @param conv The conversation the command was typed in.
+ * @param cmdline The command the user typed (only the arguments).
+ * The caller should remove the prefix and the command name.
+ * It should not contain any formatting, and should be
+ * in plain text (no HTML entities).
+ * @return TRUE if the command handled the @a cmdline, FALSE otherwise.
+ */
+gboolean purple_cmd_execute(PurpleCmd *c, PurpleConversation *conv,
+ const gchar *cmdline);
+
+/**
* List registered commands.
*
* Returns a <tt>GList</tt> (which must be freed by the caller) of all commands
@@ -230,6 +274,23 @@ GList *purple_cmd_help(PurpleConversatio
gpointer purple_cmds_get_handle(void);
/**
+ * Sets the UI operations structure to be used when registering and
+ * unregistering commands. The UI operations need only be set if the
+ * UI wants to handle the commands itself; otherwise, leave it as NULL.
+ *
+ * @param ops The UI operations structure.
+ */
+void purple_cmds_set_ui_ops(PurpleCommandsUiOps *ops);
+
+/**
+ * Returns the UI operations structure to be used when registering and
+ * unregistering commands.
+ *
+ * @return The UI operations structure.
+ */
+PurpleCommandsUiOps *purple_cmds_get_ui_ops(void);
+
+/**
* Initialize the commands subsystem.
* @since 2.5.0
*/
More information about the Commits
mailing list