purple_plugins_init
in libpurple/plugin.c
:
purple_signal_register( purple_plugins_get_handle(), /* Instance */ "plugin-load", /* Signal name */ purple_marshal_VOID__POINTER,/* Marshal function */ NULL, /* Callback return value type */ 1, /* Number of callback arguments (not including void *data) */ purple_value_new(PURPLE_TYPE_SUBTYPE,PURPLE_SUBTYPE_PLUGIN) /* Type of first callback argument */ );
purple_marshal_VOID__POINTER
represents the callback function prototype, not including a "data" argument, explained later. The form is purple_marshal_RETURNVALUETYPE__ARG1TYPE_ARG2TYPE_ETC
. See signals.h for more possible types.In this case, the callback will have the form
void cb(void *arg1, void *data)
If purple_marshal_BOOLEAN__POINTER_POINTER_POINTER
were specified, it would be:
gboolean cb(void *arg1, void *arg2, void *arg3, void *data)
The void
*data
argument at the end of each callback function provides the data argument given to purple_signal_connect() .
data
) that the callback function will take.purple_value_new(PURPLE_TYPE_SUBTYPE,PURPLE_SUBTYPE_PLUGIN)
specifies that the first argument given to the callback will be a PurplePlugin*
. You will need as many "type of argument" arguments to purple_signal_register() as you specified in "Number of arguments" above.
static void plugin_load_cb(PurplePlugin *plugin, gpointer data) { GtkTreeView *view = (GtkTreeView *)data; plugin_loading_common(plugin, view, TRUE); }
Once the callback function is defined, you can connect it to the signal. Again from gtkplugin.c , in pidgin_plugin_dialog_show()
:
purple_signal_connect(purple_plugins_get_handle(), "plugin-load", /* What to connect to */ plugin_dialog, /* Object receiving the signal */ PURPLE_CALLBACK(plugin_load_cb), /* Callback function */ event_view, /* Data to pass to the callback function );
The first two arguments ("What to connect to") specify the object emitting the signal (the plugin module) and what signal to listen for ("plugin-load").
The object receiving the signal is plugin_dialog
, the Pidgin plugins dialog. When plugin_dialog
is deleted, then purple_signals_disconnect_by_handle(plugin_dialog)
should be called to remove all signal connections it is associated with.
The callback function is given using a helper macro, and finally the data
argument to be passed to plugin_load_cb
is given as event_view
, a pointer to the GTK widget that plugin_load_cb
needs to update.
As seen in purple_plugin_load()
in plugin.c :
purple_signal_emit(purple_plugins_get_handle(), "plugin-load", plugin);
purple_plugins_get_handle()
), with the newly loaded plugin as the argument to pass to any registered callback functions.
In our example, plugin_load_cb
is called immediately as
plugin_load_cb(plugin, event_view);