pidgin: 884124c0: Add support to the Perl plugin loader fo...
datallah at pidgin.im
datallah at pidgin.im
Wed Jul 30 00:01:11 EDT 2008
-----------------------------------------------------------------
Revision: 884124c06e81cdb91185699183edd48a03e0e6ac
Ancestor: 9e3f088fc7df07bdb891f336b152797fd4f1ff07
Author: datallah at pidgin.im
Date: 2008-07-30T03:51:26
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/884124c06e81cdb91185699183edd48a03e0e6ac
Modified files:
libpurple/plugins/perl/common/Prefs.xs
libpurple/plugins/perl/perl-handlers.c
libpurple/plugins/perl/perl-handlers.h
libpurple/plugins/perl/perl.c
libpurple/plugins/perl/scripts/plugin_pref.pl
ChangeLog:
Add support to the Perl plugin loader for listing for pref changes.
The Prefs Functions Test plugin (plugin_pref.pl) includes an example.
Fixes #6383
-------------- next part --------------
============================================================
--- libpurple/plugins/perl/common/Prefs.xs 360a65dfda64f723b76e7372a70c1b9f218acd7c
+++ libpurple/plugins/perl/common/Prefs.xs edfcbd4bd9a29574af611d085c0d3c6f1cd751d2
@@ -1,4 +1,5 @@
#include "module.h"
+#include "../perl-handlers.h"
MODULE = Purple::Prefs PACKAGE = Purple::Prefs PREFIX = purple_prefs_
PROTOTYPES: ENABLE
@@ -62,13 +63,28 @@ purple_prefs_destroy()
void
purple_prefs_destroy()
+guint
+purple_prefs_connect_callback(plugin, name, callback, data = 0);
+ Purple::Plugin plugin
+ const char *name
+ SV *callback
+ SV *data
+CODE:
+ RETVAL = purple_perl_prefs_connect_callback(plugin, name, callback, data);
+OUTPUT:
+ RETVAL
+
void
-purple_prefs_disconnect_by_handle(handle)
- void * handle
+purple_prefs_disconnect_by_handle(plugin)
+ Purple::Plugin plugin
+CODE:
+ purple_perl_pref_cb_clear_for_plugin(plugin);
void
purple_prefs_disconnect_callback(callback_id)
guint callback_id
+CODE:
+ purple_perl_prefs_disconnect_callback(callback_id);
gboolean
purple_prefs_exists(name)
============================================================
--- libpurple/plugins/perl/perl-handlers.c fb326839b77e845bf979ee134461364d20505721
+++ libpurple/plugins/perl/perl-handlers.c f4cc5f1a2bbbf1731b8b34d2eb8421d190125d10
@@ -8,6 +8,7 @@ static GList *timeout_handlers = NULL;
static GList *cmd_handlers = NULL;
static GList *signal_handlers = NULL;
static GList *timeout_handlers = NULL;
+static GSList *pref_handlers = NULL;
/* perl < 5.8.0 doesn't define PERL_MAGIC_ext */
#ifndef PERL_MAGIC_ext
@@ -715,3 +716,141 @@ purple_perl_cmd_unregister(PurpleCmdId i
purple_cmd_unregister(id);
destroy_cmd_handler(handler);
}
+
+static void
+perl_pref_cb(const char *name, PurplePrefType type, gconstpointer value,
+ gpointer data)
+{
+ PurplePerlPrefsHandler *handler = data;
+ STRLEN na;
+
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(sp);
+ XPUSHs(sv_2mortal(newSVpv(name, 0)));
+
+ XPUSHs(sv_2mortal(newSViv(type)));
+
+ switch(type) {
+ case PURPLE_PREF_INT:
+ XPUSHs(sv_2mortal(newSViv(GPOINTER_TO_INT(value))));
+ break;
+ case PURPLE_PREF_BOOLEAN:
+ XPUSHs((GPOINTER_TO_INT(value) == FALSE) ? &PL_sv_no : &PL_sv_yes);
+ break;
+ case PURPLE_PREF_STRING:
+ case PURPLE_PREF_PATH:
+ XPUSHs(sv_2mortal(newSVGChar(value)));
+ break;
+ case PURPLE_PREF_STRING_LIST:
+ case PURPLE_PREF_PATH_LIST:
+ {
+ AV* av = newAV();
+ const GList *l = value;
+
+ /* Append stuff backward to preserve order */
+ while (l && l->next) l = l->next;
+ while (l) {
+ av_push(av, sv_2mortal(newSVGChar(l->data)));
+ l = l->prev;
+ }
+ XPUSHs(sv_2mortal(newRV_noinc((SV *) av)));
+ } break;
+ default:
+ case PURPLE_PREF_NONE:
+ XPUSHs(&PL_sv_undef);
+ break;
+ }
+
+ XPUSHs((SV *)handler->data);
+ PUTBACK;
+ call_sv(handler->callback, G_EVAL | G_VOID | G_DISCARD);
+ SPAGAIN;
+
+ if (SvTRUE(ERRSV)) {
+ purple_debug_error("perl",
+ "Perl prefs callback function exited abnormally: %s\n",
+ SvPV(ERRSV, na));
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+}
+
+guint
+purple_perl_prefs_connect_callback(PurplePlugin *plugin, const char *name,
+ SV *callback, SV *data)
+{
+ PurplePerlPrefsHandler *handler;
+
+ if (plugin == NULL) {
+ croak("Invalid handle in adding perl prefs handler.\n");
+ return 0;
+ }
+
+ handler = g_new0(PurplePerlPrefsHandler, 1);
+
+ handler->plugin = plugin;
+ handler->callback = (callback != NULL && callback != &PL_sv_undef
+ ? newSVsv(callback) : NULL);
+ handler->data = (data != NULL && data != &PL_sv_undef
+ ? newSVsv(data) : NULL);
+
+ pref_handlers = g_slist_prepend(pref_handlers, handler);
+
+ handler->iotag = purple_prefs_connect_callback(plugin, name, perl_pref_cb, handler);
+
+ return handler->iotag;
+}
+
+static void
+destroy_prefs_handler(PurplePerlPrefsHandler *handler)
+{
+ pref_handlers = g_slist_remove(pref_handlers, handler);
+
+ if (handler->iotag > 0)
+ purple_prefs_disconnect_callback(handler->iotag);
+
+ if (handler->callback != NULL)
+ SvREFCNT_dec(handler->callback);
+
+ if (handler->data != NULL)
+ SvREFCNT_dec(handler->data);
+
+ g_free(handler);
+}
+
+void purple_perl_prefs_disconnect_callback(guint callback_id)
+{
+ GSList *l, *l_next;
+ PurplePerlPrefsHandler *handler;
+
+ for (l = pref_handlers; l != NULL; l = l_next) {
+ l_next = l->next;
+ handler = l->data;
+
+ if (handler->iotag == callback_id) {
+ destroy_prefs_handler(handler);
+ return;
+ }
+ }
+
+ purple_debug_info("perl", "No prefs handler found with handle %u.\n",
+ callback_id);
+}
+
+void purple_perl_pref_cb_clear_for_plugin(PurplePlugin *plugin)
+{
+ GSList *l, *l_next;
+ PurplePerlPrefsHandler *handler;
+
+ for (l = pref_handlers; l != NULL; l = l_next) {
+ l_next = l->next;
+ handler = l->data;
+
+ if (handler->plugin == plugin)
+ destroy_prefs_handler(handler);
+ }
+}
============================================================
--- libpurple/plugins/perl/perl-handlers.h 6b5188feb79bf5e40aad40526aa386985674ae9d
+++ libpurple/plugins/perl/perl-handlers.h a4a40f9641594ba13824f16a8d23b29ae6d424a1
@@ -15,8 +15,8 @@ typedef struct
PurpleCmdId id;
SV *callback;
SV *data;
- char *prpl_id;
- char *cmd;
+ gchar *prpl_id;
+ gchar *cmd;
PurplePlugin *plugin;
} PurplePerlCmdHandler;
@@ -31,7 +31,7 @@ typedef struct
typedef struct
{
- char *signal;
+ gchar *signal;
SV *callback;
SV *data;
void *instance;
@@ -39,8 +39,17 @@ typedef struct
} PurplePerlSignalHandler;
+typedef struct
+{
+ SV *callback;
+ SV *data;
+ PurplePlugin *plugin;
+ int iotag;
+
+} PurplePerlPrefsHandler;
+
void purple_perl_plugin_action_cb(PurplePluginAction * gpa);
-GList *purple_perl_plugin_actions(PurplePlugin *plugin, gpointer context);
+GList *purple_perl_plugin_actions(PurplePlugin *plugin, gpointer context);
PurplePluginPrefFrame *purple_perl_get_plugin_frame(PurplePlugin *plugin);
@@ -69,4 +78,8 @@ void purple_perl_cmd_clear_for_plugin(Pu
void purple_perl_cmd_unregister(PurpleCmdId id);
void purple_perl_cmd_clear_for_plugin(PurplePlugin *plugin);
+guint purple_perl_prefs_connect_callback(PurplePlugin *plugin, const char *name, SV *callback, SV *data);
+void purple_perl_prefs_disconnect_callback(guint callback_id);
+void purple_perl_pref_cb_clear_for_plugin(PurplePlugin *plugin);
+
#endif /* _PURPLE_PERL_HANDLERS_H_ */
============================================================
--- libpurple/plugins/perl/perl.c ff81c8afd465331cc0a6e09359f5c34d4967d566
+++ libpurple/plugins/perl/perl.c 0bf5d2c08b10aaf860740cf62ec47bd890d0afd1
@@ -557,6 +557,7 @@ unload_perl_plugin(PurplePlugin *plugin)
purple_perl_cmd_clear_for_plugin(plugin);
purple_perl_signal_clear_for_plugin(plugin);
purple_perl_timeout_clear_for_plugin(plugin);
+ purple_perl_pref_cb_clear_for_plugin(plugin);
destroy_package(gps->package);
============================================================
--- libpurple/plugins/perl/scripts/plugin_pref.pl 104c0861c8286cbaab9c9b33aeaef439f5c7aced
+++ libpurple/plugins/perl/scripts/plugin_pref.pl 31fb2680668448d320c76212b8879c76150d3e89
@@ -44,8 +44,8 @@ sub foo {
$ppref = Purple::PluginPref->new_with_name_and_label(
"/plugins/core/perl_test/choice", "Choice Preference");
$ppref->set_type(1);
- $ppref->add_choice("ch0", $frame);
- $ppref->add_choice("ch1", $frame);
+ $ppref->add_choice("ch0", "ch0-val");
+ $ppref->add_choice("ch1", "ch1-val");
$frame->add($ppref);
$ppref = Purple::PluginPref->new_with_name_and_label(
@@ -56,12 +56,17 @@ sub foo {
return $frame;
}
+sub pref_cb {
+ my ($pref, $type, $value, $data) = @_;
+
+ print "pref changed: [$pref]($type)=$value data=$data\n";
+}
+
sub plugin_init {
return %PLUGIN_INFO;
}
-
# This is the sub defined in %PLUGIN_INFO to be called when the plugin is loaded
# Note: The plugin has a reference to itself on top of the argument stack.
sub plugin_load {
@@ -75,8 +80,12 @@ sub plugin_load {
Purple::Prefs::add_bool("/plugins/core/perl_test/bool", 1);
Purple::Prefs::add_string("/plugins/core/perl_test/choice", "ch1");
Purple::Prefs::add_string("/plugins/core/perl_test/text", "Foobar");
-
+ Purple::Prefs::connect_callback($plugin, "/plugins/core/perl_test", \&pref_cb, "none");
+ Purple::Prefs::connect_callback($plugin, "/plugins/core/perl_test/bool", \&pref_cb, "bool");
+ Purple::Prefs::connect_callback($plugin, "/plugins/core/perl_test/choice", \&pref_cb, "choice");
+ Purple::Prefs::connect_callback($plugin, "/plugins/core/perl_test/text", \&pref_cb, "text");
+
print "\n\n" . "#" x 80 . "\n\n";
}
More information about the Commits
mailing list