--- a/doc/reference/libpurple/libpurple-docs.xml Thu Jun 17 23:43:50 2021 -0500
+++ b/doc/reference/libpurple/libpurple-docs.xml Fri Jun 18 00:00:00 2021 -0500
@@ -82,6 +82,7 @@
<xi:include href="xml/purplemarkup.xml" />
<xi:include href="xml/purplenoopcredentialprovider.xml" />
<xi:include href="xml/purpleoptions.xml" />
+ <xi:include href="xml/purpleplugininfo.xml" /> <xi:include href="xml/purplepresence.xml" />
<xi:include href="xml/purpleprotocolattention.xml" />
<xi:include href="xml/purpleprotocolchat.xml" />
--- a/libpurple/meson.build Thu Jun 17 23:43:50 2021 -0500
+++ b/libpurple/meson.build Fri Jun 18 00:00:00 2021 -0500
@@ -59,6 +59,7 @@
'purplenoopcredentialprovider.c',
'purpleprotocolattention.c',
@@ -153,6 +154,7 @@
'purplenoopcredentialprovider.h',
'purpleprotocolattention.h',
@@ -236,6 +238,7 @@
'purpleimconversation.h',
--- a/libpurple/plugins.c Thu Jun 17 23:43:50 2021 -0500
+++ b/libpurple/plugins.c Fri Jun 18 00:00:00 2021 -0500
@@ -31,49 +31,6 @@
-typedef struct _PurplePluginInfoPrivate PurplePluginInfoPrivate;
-/**************************************************************************
- * Plugin info private data
- **************************************************************************/
-struct _PurplePluginInfoPrivate {
- char *ui_requirement; /* ID of UI that is required to load the plugin */
- char *error; /* Why a plugin is not loadable */
- PurplePluginInfoFlags flags; /* Flags for the plugin */
- /* Callback that returns a list of actions the plugin can perform */
- PurplePluginActionsCb actions_cb;
- /* Callback that returns extra information about a plugin */
- PurplePluginExtraCb extra_cb;
- /* Callback that returns a preferences frame for a plugin */
- PurplePluginPrefFrameCb pref_frame_cb;
- /* Callback that returns a preferences request handle for a plugin */
- PurplePluginPrefRequestCb pref_request_cb;
- /* TRUE if a plugin has been unloaded at least once. Auto-load
- * plugins that have been unloaded once will not be auto-loaded again. */
-G_DEFINE_TYPE_WITH_PRIVATE(PurplePluginInfo, purple_plugin_info,
- GPLUGIN_TYPE_PLUGIN_INFO);
/**************************************************************************
**************************************************************************/
@@ -88,7 +45,7 @@
- PurplePluginInfoPrivate *priv;
+ const gchar *info_error = NULL; g_return_val_if_fail(PURPLE_IS_PLUGIN(plugin), FALSE);
@@ -96,16 +53,15 @@
return TRUE; /* a GPlugin internal plugin */
- priv = purple_plugin_info_get_instance_private(info);
+ info_error = purple_plugin_info_get_error(info); + if(info_error != NULL) { gchar *filename = gplugin_plugin_get_filename(plugin);
purple_debug_error("plugins", "Failed to load plugin %s: %s",
g_set_error(error, PURPLE_PLUGINS_DOMAIN, 0,
- "Plugin is not loadable: %s", priv->error);
+ "Plugin is not loadable: %s", info_error); @@ -158,7 +114,6 @@
plugin_unloaded_cb(GObject *manager, PurplePlugin *plugin)
- PurplePluginInfoPrivate *priv;
g_return_if_fail(PURPLE_IS_PLUGIN(plugin));
@@ -166,8 +121,6 @@
return; /* a GPlugin internal plugin */
- priv = purple_plugin_info_get_instance_private(info);
/* cancel any pending dialogs the plugin has */
purple_request_close_with_handle(plugin);
purple_notify_close_with_handle(plugin);
@@ -175,7 +128,7 @@
purple_signals_disconnect_by_handle(plugin);
purple_signals_unregister_by_instance(plugin);
+ purple_plugin_info_set_unloaded(info, TRUE); loaded_plugins = g_list_remove(loaded_plugins, plugin);
plugins_to_disable = g_list_remove(plugins_to_disable, plugin);
@@ -299,277 +252,6 @@
/**************************************************************************
- * GObject code for PurplePluginInfo
- **************************************************************************/
-/* GObject initialization function */
-purple_plugin_info_init(PurplePluginInfo *info)
-/* Set method for GObject properties */
-purple_plugin_info_set_property(GObject *obj, guint param_id, const GValue *value,
- PurplePluginInfo *info = PURPLE_PLUGIN_INFO(obj);
- PurplePluginInfoPrivate *priv =
- purple_plugin_info_get_instance_private(info);
- case PROP_UI_REQUIREMENT:
- priv->ui_requirement = g_value_dup_string(value);
- priv->actions_cb = g_value_get_pointer(value);
- priv->extra_cb = g_value_get_pointer(value);
- case PROP_PREF_FRAME_CB:
- priv->pref_frame_cb = g_value_get_pointer(value);
- case PROP_PREF_REQUEST_CB:
- priv->pref_request_cb = g_value_get_pointer(value);
- priv->flags = g_value_get_flags(value);
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-/* Get method for GObject properties */
-purple_plugin_info_get_property(GObject *obj, guint param_id, GValue *value,
- PurplePluginInfo *info = PURPLE_PLUGIN_INFO(obj);
- g_value_set_pointer(value,
- purple_plugin_info_get_actions_cb(info));
- g_value_set_pointer(value,
- purple_plugin_info_get_extra_cb(info));
- case PROP_PREF_FRAME_CB:
- g_value_set_pointer(value,
- purple_plugin_info_get_pref_frame_cb(info));
- case PROP_PREF_REQUEST_CB:
- g_value_set_pointer(value,
- purple_plugin_info_get_pref_request_cb(info));
- g_value_set_flags(value, purple_plugin_info_get_flags(info));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-/* Called when done constructing */
-purple_plugin_info_constructed(GObject *object)
- PurplePluginInfo *info = PURPLE_PLUGIN_INFO(object);
- GPluginPluginInfo *ginfo = GPLUGIN_PLUGIN_INFO(info);
- PurplePluginInfoPrivate *priv =
- purple_plugin_info_get_instance_private(info);
- const char *id = gplugin_plugin_info_get_id(ginfo);
- G_OBJECT_CLASS(purple_plugin_info_parent_class)->constructed(object);
- if (id == NULL || *id == '\0')
- priv->error = g_strdup(_("This plugin has not defined an ID."));
- if (priv->ui_requirement && !purple_strequal(priv->ui_requirement, purple_core_get_ui()))
- priv->error = g_strdup_printf(_("You are using %s, but this plugin requires %s."),
- purple_core_get_ui(), priv->ui_requirement);
- purple_debug_error("plugins", "%s is not loadable: The UI requirement is not met. (%s)\n",
- version = gplugin_plugin_info_get_abi_version(ginfo);
- if (PURPLE_PLUGIN_ABI_MAJOR_VERSION(version) != PURPLE_MAJOR_VERSION ||
- PURPLE_PLUGIN_ABI_MINOR_VERSION(version) > PURPLE_MINOR_VERSION)
- priv->error = g_strdup_printf(_("Your libpurple version is %d.%d.x (need %d.%d.x)"),
- PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION,
- PURPLE_PLUGIN_ABI_MAJOR_VERSION(version),
- PURPLE_PLUGIN_ABI_MINOR_VERSION(version));
- purple_debug_error("plugins", "%s is not loadable: libpurple version is %d.%d.x (need %d.%d.x)\n",
- id, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION,
- PURPLE_PLUGIN_ABI_MAJOR_VERSION(version),
- PURPLE_PLUGIN_ABI_MINOR_VERSION(version));
-/* GObject finalize function */
-purple_plugin_info_finalize(GObject *object)
- PurplePluginInfoPrivate *priv =
- purple_plugin_info_get_instance_private(
- PURPLE_PLUGIN_INFO(object));
- g_free(priv->ui_requirement);
- G_OBJECT_CLASS(purple_plugin_info_parent_class)->finalize(object);
-/* Class initializer function */
-static void purple_plugin_info_class_init(PurplePluginInfoClass *klass)
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- obj_class->constructed = purple_plugin_info_constructed;
- obj_class->finalize = purple_plugin_info_finalize;
- obj_class->get_property = purple_plugin_info_get_property;
- obj_class->set_property = purple_plugin_info_set_property;
- g_object_class_install_property(obj_class, PROP_UI_REQUIREMENT,
- g_param_spec_string("ui-requirement",
- "ID of UI that is required by this plugin", NULL,
- G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(obj_class, PROP_ACTIONS_CB,
- g_param_spec_pointer("actions-cb",
- "Callback that returns list of plugin's actions",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(obj_class, PROP_EXTRA_CB,
- g_param_spec_pointer("extra-cb",
- "Callback that returns extra info about the plugin",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(obj_class, PROP_PREF_FRAME_CB,
- g_param_spec_pointer("pref-frame-cb",
- "Preferences frame callback",
- "The callback that returns the preferences frame",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(obj_class, PROP_PREF_REQUEST_CB,
- g_param_spec_pointer("pref-request-cb",
- "Preferences request callback",
- "Callback that returns preferences request handle",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property(obj_class, PROP_FLAGS,
- g_param_spec_flags("flags",
- "The flags for the plugin",
- PURPLE_TYPE_PLUGIN_INFO_FLAGS, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-/**************************************************************************
- **************************************************************************/
-purple_plugin_info_new(const char *first_property, ...)
- /* at least ID is required */
- va_start(var_args, first_property);
- info = g_object_new_valist(PURPLE_TYPE_PLUGIN_INFO, first_property,
- return GPLUGIN_PLUGIN_INFO(info);
-purple_plugin_info_get_actions_cb(PurplePluginInfo *info)
- PurplePluginInfoPrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL);
- priv = purple_plugin_info_get_instance_private(info);
- return priv->actions_cb;
-purple_plugin_info_get_extra_cb(PurplePluginInfo *info)
- PurplePluginInfoPrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL);
- priv = purple_plugin_info_get_instance_private(info);
-purple_plugin_info_get_pref_frame_cb(PurplePluginInfo *info)
- PurplePluginInfoPrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL);
- priv = purple_plugin_info_get_instance_private(info);
- return priv->pref_frame_cb;
-PurplePluginPrefRequestCb
-purple_plugin_info_get_pref_request_cb(PurplePluginInfo *info)
- PurplePluginInfoPrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL);
- priv = purple_plugin_info_get_instance_private(info);
- return priv->pref_request_cb;
-purple_plugin_info_get_flags(PurplePluginInfo *info)
- PurplePluginInfoPrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), 0);
- priv = purple_plugin_info_get_instance_private(info);
-purple_plugin_info_get_error(PurplePluginInfo *info)
- PurplePluginInfoPrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL);
- priv = purple_plugin_info_get_instance_private(info);
-/**************************************************************************
**************************************************************************/
@@ -657,16 +339,17 @@
for (l = plugins; l != NULL; l = l->next) {
PurplePlugin *plugin = PURPLE_PLUGIN(l->data);
- PurplePluginInfoPrivate *priv;
+ PurplePluginInfoFlags flags; if (purple_plugin_is_loaded(plugin))
info = purple_plugin_get_info(plugin);
- priv = purple_plugin_info_get_instance_private(info);
- if (!priv->unloaded && purple_plugin_info_get_flags(info) &
- PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD) {
+ unloaded = purple_plugin_info_get_unloaded(info); + flags = purple_plugin_info_get_flags(info); + if (!unloaded && flags & PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD) { gchar *filename = gplugin_plugin_get_filename(plugin);
purple_debug_info("plugins", "Auto-loading plugin %s\n",
--- a/libpurple/plugins.h Thu Jun 17 23:43:50 2021 -0500
+++ b/libpurple/plugins.h Fri Jun 18 00:00:00 2021 -0500
@@ -57,13 +57,7 @@
typedef GPluginPluginInterface PurplePluginInterface;
- * PURPLE_TYPE_PLUGIN_INFO:
- * The standard _get_type macro for #PurplePluginInfo.
-#define PURPLE_TYPE_PLUGIN_INFO (purple_plugin_info_get_type())
-typedef struct _PurplePluginInfo PurplePluginInfo;
+#include "purpleplugininfo.h" * PURPLE_TYPE_PLUGIN_ACTION:
@@ -73,8 +67,6 @@
#define PURPLE_TYPE_PLUGIN_ACTION (purple_plugin_action_get_type())
typedef struct _PurplePluginAction PurplePluginAction;
* @action: the action information.
@@ -84,69 +76,6 @@
typedef void (*PurplePluginActionCb)(PurplePluginAction *action);
- * PurplePluginActionsCb:
- * @plugin: the plugin associated with this callback.
- * Returns a list of actions the plugin can perform.
- * Returns: (transfer none): A list of actions the plugin can perform.
-typedef GList *(*PurplePluginActionsCb)(PurplePlugin *plugin);
- * @plugin: the plugin associated with this callback.
- * Gives extra information about the plguin.
- * Returns: a newly allocated string denoting extra information
-typedef gchar *(*PurplePluginExtraCb)(PurplePlugin *plugin);
- * PurplePluginPrefFrameCb:
- * @plugin: the plugin associated with this callback.
- * Returns the preferences frame for the plugin.
- * Returns: Preference frame.
-typedef PurplePluginPrefFrame *(*PurplePluginPrefFrameCb)(PurplePlugin *plugin);
- * Returns the preferences request handle for a plugin.
- * Returns: Preferences request handle.
-typedef gpointer (*PurplePluginPrefRequestCb)(PurplePlugin *plugin);
- * PurplePluginInfoFlags:
- * @PURPLE_PLUGIN_INFO_FLAGS_INTERNAL: Plugin is not shown in UI lists
- * @PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD: Auto-load the plugin
- * Flags that can be used to treat plugins differently.
-typedef enum /*< flags >*/
- PURPLE_PLUGIN_INFO_FLAGS_INTERNAL = 1 << 1,
- PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD = 1 << 2,
-} PurplePluginInfoFlags;
- * Holds information about a plugin.
-struct _PurplePluginInfo {
- GPluginPluginInfo parent;
* @label: The label to display in the user interface.
* @callback: The function to call when the user wants to perform this action.
@@ -163,41 +92,6 @@
- * PURPLE_PLUGIN_ABI_VERSION:
- * Note: The lower six nibbles represent the ABI version for libpurple, the
- * rest are required by GPlugin.
- * Returns: An ABI version to set in plugins using major and minor versions.
-#define PURPLE_PLUGIN_ABI_VERSION(major,minor) \
- (0x01000000 | ((major) << 16) | (minor))
- * PURPLE_PLUGIN_ABI_MAJOR_VERSION:
- * Returns: The major version from an ABI version
-#define PURPLE_PLUGIN_ABI_MAJOR_VERSION(abi) \
- * PURPLE_PLUGIN_ABI_MINOR_VERSION:
- * Returns: The minor version from an ABI version
-#define PURPLE_PLUGIN_ABI_MINOR_VERSION(abi) \
- * A convenience‎ macro that returns an ABI version using PURPLE_MAJOR_VERSION
- * and PURPLE_MINOR_VERSION
-#define PURPLE_ABI_VERSION PURPLE_PLUGIN_ABI_VERSION(PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION)
/**************************************************************************/
@@ -293,182 +187,6 @@
GSList *purple_plugin_get_dependent_plugins(PurplePlugin *plugin);
/**************************************************************************/
-/**************************************************************************/
- * purple_plugin_info_get_type:
- * Returns: The #GType for the #PurplePluginInfo object.
-G_DECLARE_FINAL_TYPE(PurplePluginInfo, purple_plugin_info, PURPLE, PLUGIN_INFO,
- * purple_plugin_info_new:
- * @first_property: The first property name
- * @...: The value of the first property, followed optionally by more
- * name/value pairs, followed by %NULL
- * Creates a new #PurplePluginInfo instance to be returned from
- * #plugin_query of a plugin, using the provided name/value pairs.
- * All properties except <literal>"id"</literal> and
- * <literal>"purple-abi"</literal> are optional.
- * Valid property names are:
- * <informaltable frame='none'>
- * <tgroup cols='2'><tbody>
- * <row><entry><literal>"id"</literal></entry>
- * <entry>(string) The ID of the plugin.</entry>
- * <row><entry><literal>"abi-version"</literal></entry>
- * <entry>(<type>guint32</type>) The ABI version required by the
- * <row><entry><literal>"name"</literal></entry>
- * <entry>(string) The translated name of the plugin.</entry>
- * <row><entry><literal>"version"</literal></entry>
- * <entry>(string) Version of the plugin.</entry>
- * <row><entry><literal>"category"</literal></entry>
- * <entry>(string) Primary category of the plugin.</entry>
- * <row><entry><literal>"summary"</literal></entry>
- * <entry>(string) Brief summary of the plugin.</entry>
- * <row><entry><literal>"description"</literal></entry>
- * <entry>(string) Full description of the plugin.</entry>
- * <row><entry><literal>"authors"</literal></entry>
- * <entry>(<type>const gchar * const *</type>) A %NULL-terminated list of
- * plugin authors. format: First Last <user\@domain.com></entry>
- * <row><entry><literal>"website"</literal></entry>
- * <entry>(string) Website of the plugin.</entry>
- * <row><entry><literal>"icon"</literal></entry>
- * <entry>(string) Path to a plugin's icon.</entry>
- * <row><entry><literal>"license-id"</literal></entry>
- * <entry>(string) Short name of the plugin's license. This should
- * either be an identifier of the license from
- * <ulink url="http://dep.debian.net/deps/dep5/#license-specification">
- * DEP5</ulink> or "Other" for custom licenses.</entry>
- * <row><entry><literal>"license-text"</literal></entry>
- * <entry>(string) The text of the plugin's license, if unlisted on
- * <row><entry><literal>"license-url"</literal></entry>
- * <entry>(string) The plugin's license URL, if unlisted on DEP5.</entry>
- * <row><entry><literal>"dependencies"</literal></entry>
- * <entry>(<type>const gchar * const *</type>) A %NULL-terminated list of
- * plugin IDs required by the plugin.</entry>
- * <row><entry><literal>"actions-cb"</literal></entry>
- * <entry>(#PurplePluginActionsCb) Callback that returns a list of
- * actions the plugin can perform.</entry>
- * <row><entry><literal>"extra-cb"</literal></entry>
- * <entry>(#PurplePluginExtraCb) Callback that returns a newly
- * allocated string denoting extra information about a plugin.</entry>
- * <row><entry><literal>"pref-frame-cb"</literal></entry>
- * <entry>(#PurplePluginPrefFrameCb) Callback that returns a
- * preferences frame for the plugin.</entry>
- * <row><entry><literal>"pref-request-cb"</literal></entry>
- * <entry>(#PurplePluginPrefRequestCb) Callback that returns a
- * preferences request handle for the plugin.</entry>
- * <row><entry><literal>"flags"</literal></entry>
- * <entry>(#PurplePluginInfoFlags) The flags for a plugin.</entry>
- * See #PURPLE_PLUGIN_ABI_VERSION,
- * <link linkend="chapter-plugin-ids">Plugin IDs</link>.
- * Returns: A new #PurplePluginInfo instance.
-GPluginPluginInfo *purple_plugin_info_new(const char *first_property, ...) G_GNUC_NULL_TERMINATED;
- * purple_plugin_info_get_actions_cb:
- * @info: The plugin info to get the callback from.
- * Returns the callback that retrieves the list of actions a plugin can perform
- * Returns: The callback that returns a list of #PurplePluginAction
- * instances corresponding to the actions a plugin can perform.
-purple_plugin_info_get_actions_cb(PurplePluginInfo *info);
- * purple_plugin_info_get_extra_cb:
- * @info: The plugin info to get extra information from.
- * Returns a callback that gives extra information about a plugin. You must
- * free the string returned by this callback.
- * Returns: (transfer none): The callback that returns extra information about a plugin.
-purple_plugin_info_get_extra_cb(PurplePluginInfo *info);
- * purple_plugin_info_get_pref_frame_cb:
- * @info: The plugin info to get the callback from.
- * Returns the callback that retrieves the preferences frame for a plugin, set
- * via the "pref-frame-cb" property of the plugin info.
- * Returns: The callback that returns the preferences frame.
-purple_plugin_info_get_pref_frame_cb(PurplePluginInfo *info);
- * purple_plugin_info_get_pref_request_cb:
- * @info: The plugin info to get the callback from.
- * Returns the callback that retrieves the preferences request handle for a
- * plugin, set via the "pref-request-cb" property of the plugin info.
- * Returns: (transfer none): The callback that returns the preferences request handle.
-PurplePluginPrefRequestCb
-purple_plugin_info_get_pref_request_cb(PurplePluginInfo *info);
- * purple_plugin_info_get_flags:
- * @info: The plugin's info instance.
- * Returns the plugin's flags.
- * Returns: The flags of the plugin.
-purple_plugin_info_get_flags(PurplePluginInfo *info);
- * purple_plugin_info_get_error:
- * @info: The plugin info.
- * Returns an error in the plugin info that would prevent the plugin from being
- * Returns: The plugin info error, or %NULL.
-const gchar *purple_plugin_info_get_error(PurplePluginInfo *info);
-/**************************************************************************/
/**************************************************************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleplugininfo.c Fri Jun 18 00:00:00 2021 -0500
@@ -0,0 +1,353 @@
+ * Purple - Internet Messaging Library + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <https://www.gnu.org/licenses/>. +#include <glib/gi18n-lib.h> +#include "purpleplugininfo.h" + gchar *ui_requirement; /* ID of UI that is required to load the plugin */ + gchar *error; /* Why a plugin is not loadable */ + PurplePluginInfoFlags flags; /* Flags for the plugin */ + /* Callback that returns a list of actions the plugin can perform */ + PurplePluginActionsCb actions_cb; + /* Callback that returns extra information about a plugin */ + PurplePluginExtraCb extra_cb; + /* Callback that returns a preferences frame for a plugin */ + PurplePluginPrefFrameCb pref_frame_cb; + /* Callback that returns a preferences request handle for a plugin */ + PurplePluginPrefRequestCb pref_request_cb; + /* TRUE if a plugin has been unloaded at least once. Auto-load + * plugins that have been unloaded once will not be auto-loaded again. */ +} PurplePluginInfoPrivate; +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; +G_DEFINE_TYPE_WITH_PRIVATE(PurplePluginInfo, purple_plugin_info, + GPLUGIN_TYPE_PLUGIN_INFO); +/************************************************************************** + * GObject Implementation + **************************************************************************/ +purple_plugin_info_init(PurplePluginInfo *info) { +purple_plugin_info_set_property(GObject *obj, guint param_id, + const GValue *value, GParamSpec *pspec) + PurplePluginInfo *info = PURPLE_PLUGIN_INFO(obj); + PurplePluginInfoPrivate *priv = NULL; + priv = purple_plugin_info_get_instance_private(info); + case PROP_UI_REQUIREMENT: + priv->ui_requirement = g_value_dup_string(value); + priv->actions_cb = g_value_get_pointer(value); + priv->extra_cb = g_value_get_pointer(value); + case PROP_PREF_FRAME_CB: + priv->pref_frame_cb = g_value_get_pointer(value); + case PROP_PREF_REQUEST_CB: + priv->pref_request_cb = g_value_get_pointer(value); + priv->flags = g_value_get_flags(value); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +purple_plugin_info_get_property(GObject *obj, guint param_id, GValue *value, + PurplePluginInfo *info = PURPLE_PLUGIN_INFO(obj); + g_value_set_pointer(value, + purple_plugin_info_get_actions_cb(info)); + g_value_set_pointer(value, + purple_plugin_info_get_extra_cb(info)); + case PROP_PREF_FRAME_CB: + g_value_set_pointer(value, + purple_plugin_info_get_pref_frame_cb(info)); + case PROP_PREF_REQUEST_CB: + g_value_set_pointer(value, + purple_plugin_info_get_pref_request_cb(info)); + g_value_set_flags(value, purple_plugin_info_get_flags(info)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +purple_plugin_info_constructed(GObject *object) { + PurplePluginInfo *info = PURPLE_PLUGIN_INFO(object); + GPluginPluginInfo *ginfo = GPLUGIN_PLUGIN_INFO(info); + PurplePluginInfoPrivate *priv = NULL; + const gchar *id = gplugin_plugin_info_get_id(ginfo); + priv = purple_plugin_info_get_instance_private(info); + G_OBJECT_CLASS(purple_plugin_info_parent_class)->constructed(object); + if(id == NULL || *id == '\0') { + priv->error = g_strdup(_("This plugin has not defined an ID.")); + if(priv->ui_requirement != NULL) { + if(!purple_strequal(priv->ui_requirement, purple_core_get_ui())) { + priv->error = g_strdup_printf(_("You are using %s, but this plugin " + purple_debug_error("plugins", + "%s is not loadable: The UI requirement is not " + version = gplugin_plugin_info_get_abi_version(ginfo); + if (PURPLE_PLUGIN_ABI_MAJOR_VERSION(version) != PURPLE_MAJOR_VERSION || + PURPLE_PLUGIN_ABI_MINOR_VERSION(version) > PURPLE_MINOR_VERSION) + priv->error = g_strdup_printf(_("Your libpurple version is %d.%d.x " + PURPLE_PLUGIN_ABI_MAJOR_VERSION(version), + PURPLE_PLUGIN_ABI_MINOR_VERSION(version)); + purple_debug_error("plugins", + "%s is not loadable: libpurple version is %d.%d.x " + id, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, + PURPLE_PLUGIN_ABI_MAJOR_VERSION(version), + PURPLE_PLUGIN_ABI_MINOR_VERSION(version)); +purple_plugin_info_finalize(GObject *object) { + PurplePluginInfoPrivate *priv = NULL; + priv = purple_plugin_info_get_instance_private(PURPLE_PLUGIN_INFO(object)); + g_free(priv->ui_requirement); + G_OBJECT_CLASS(purple_plugin_info_parent_class)->finalize(object); +purple_plugin_info_class_init(PurplePluginInfoClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->constructed = purple_plugin_info_constructed; + obj_class->finalize = purple_plugin_info_finalize; + obj_class->get_property = purple_plugin_info_get_property; + obj_class->set_property = purple_plugin_info_set_property; + properties[PROP_UI_REQUIREMENT] = g_param_spec_string( + "ui-requirement", "UI Requirement", + "ID of UI that is required by this plugin", + G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); + properties[PROP_ACTIONS_CB] = g_param_spec_pointer( + "actions-cb", "Plugin actions", + "Callback that returns list of plugin's actions", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_EXTRA_CB] = g_param_spec_pointer( + "extra-cb", "Extra info callback", + "Callback that returns extra info about the plugin", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_PREF_FRAME_CB] = g_param_spec_pointer( + "pref-frame-cb", "Preferences frame callback", + "The callback that returns the preferences frame", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_PREF_REQUEST_CB] = g_param_spec_pointer( + "pref-request-cb", "Preferences request callback", + "Callback that returns preferences request handle", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_FLAGS] = g_param_spec_flags( + "flags", "Plugin flags", + "The flags for the plugin", + PURPLE_TYPE_PLUGIN_INFO_FLAGS, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); +/************************************************************************** + **************************************************************************/ +purple_plugin_info_new(const char *first_property, ...) { + /* at least ID is required */ + va_start(var_args, first_property); + info = g_object_new_valist(PURPLE_TYPE_PLUGIN_INFO, first_property, + return GPLUGIN_PLUGIN_INFO(info); +purple_plugin_info_get_actions_cb(PurplePluginInfo *info) { + PurplePluginInfoPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL); + priv = purple_plugin_info_get_instance_private(info); + return priv->actions_cb; +purple_plugin_info_get_extra_cb(PurplePluginInfo *info) { + PurplePluginInfoPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL); + priv = purple_plugin_info_get_instance_private(info); +purple_plugin_info_get_pref_frame_cb(PurplePluginInfo *info) { + PurplePluginInfoPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL); + priv = purple_plugin_info_get_instance_private(info); + return priv->pref_frame_cb; +PurplePluginPrefRequestCb +purple_plugin_info_get_pref_request_cb(PurplePluginInfo *info) { + PurplePluginInfoPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL); + priv = purple_plugin_info_get_instance_private(info); + return priv->pref_request_cb; +purple_plugin_info_get_flags(PurplePluginInfo *info) { + PurplePluginInfoPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), 0); + priv = purple_plugin_info_get_instance_private(info); +purple_plugin_info_get_error(PurplePluginInfo *info) { + PurplePluginInfoPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), NULL); + priv = purple_plugin_info_get_instance_private(info); +purple_plugin_info_get_unloaded(PurplePluginInfo *info) { + PurplePluginInfoPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PLUGIN_INFO(info), FALSE); + priv = purple_plugin_info_get_instance_private(info); +purple_plugin_info_set_unloaded(PurplePluginInfo *info, gboolean unloaded) { + PurplePluginInfoPrivate *priv = NULL; + g_return_if_fail(PURPLE_IS_PLUGIN_INFO(info)); + priv = purple_plugin_info_get_instance_private(info); + priv->unloaded = unloaded; --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleplugininfo.h Fri Jun 18 00:00:00 2021 -0500
@@ -0,0 +1,364 @@
+ * Purple - Internet Messaging Library + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <https://www.gnu.org/licenses/>. +#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) +# error "only <purple.h> may be included directly" +#ifndef PURPLE_PLUGIN_INFO_H +#define PURPLE_PLUGIN_INFO_H + * SECTION:purpleplugininfo + * @section_id: libpurple-purpleplugininfo + * @title: PurplePluginInfo Object + * @see_also: <link linkend="chapter-signals-plugin">Plugin signals</link>, + * <link linkend="chapter-plugin-ids">Plugin IDs</link>, + * <link linkend="chapter-plugin-i18n">Third Party Plugin Translation</link> +#include <gplugin-native.h> + * PURPLE_TYPE_PLUGIN_INFO: + * The standard _get_type macro for #PurplePluginInfo. +#define PURPLE_TYPE_PLUGIN_INFO (purple_plugin_info_get_type()) + * purple_plugin_info_get_type: + * Returns: The #GType for the #PurplePluginInfo object. +G_DECLARE_DERIVABLE_TYPE(PurplePluginInfo, purple_plugin_info, PURPLE, PLUGIN_INFO, +struct _PurplePluginInfoClass { + GPluginPluginInfoClass parent; + * PurplePluginActionsCb: + * @plugin: the plugin associated with this callback. + * Returns a list of actions the plugin can perform. + * Returns: (transfer none): A list of actions the plugin can perform. +typedef GList *(*PurplePluginActionsCb)(PurplePlugin *plugin); + * @plugin: the plugin associated with this callback. + * Gives extra information about the plguin. + * Returns: a newly allocated string denoting extra information +typedef gchar *(*PurplePluginExtraCb)(PurplePlugin *plugin); + * PurplePluginPrefFrameCb: + * @plugin: the plugin associated with this callback. + * Returns the preferences frame for the plugin. + * Returns: Preference frame. +typedef PurplePluginPrefFrame *(*PurplePluginPrefFrameCb)(PurplePlugin *plugin); + * Returns the preferences request handle for a plugin. + * Returns: Preferences request handle. +typedef gpointer (*PurplePluginPrefRequestCb)(PurplePlugin *plugin); + * PurplePluginInfoFlags: + * @PURPLE_PLUGIN_INFO_FLAGS_INTERNAL: Plugin is not shown in UI lists + * @PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD: Auto-load the plugin + * Flags that can be used to treat plugins differently. +typedef enum /*< flags >*/ + PURPLE_PLUGIN_INFO_FLAGS_INTERNAL = 1 << 1, + PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD = 1 << 2, +} PurplePluginInfoFlags; + * Holds information about a plugin. + * PURPLE_PLUGIN_ABI_VERSION: + * Note: The lower six nibbles represent the ABI version for libpurple, the + * rest are required by GPlugin. + * Returns: An ABI version to set in plugins using major and minor versions. +#define PURPLE_PLUGIN_ABI_VERSION(major,minor) \ + (0x01000000 | ((major) << 16) | (minor)) + * PURPLE_PLUGIN_ABI_MAJOR_VERSION: + * Returns: The major version from an ABI version +#define PURPLE_PLUGIN_ABI_MAJOR_VERSION(abi) \ + * PURPLE_PLUGIN_ABI_MINOR_VERSION: + * Returns: The minor version from an ABI version +#define PURPLE_PLUGIN_ABI_MINOR_VERSION(abi) \ + * A convenience macro that returns an ABI version using PURPLE_MAJOR_VERSION + * and PURPLE_MINOR_VERSION +#define PURPLE_ABI_VERSION PURPLE_PLUGIN_ABI_VERSION(PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION) + * purple_plugin_info_new: + * @first_property: The first property name + * @...: The value of the first property, followed optionally by more + * name/value pairs, followed by %NULL + * Creates a new #PurplePluginInfo instance to be returned from + * #plugin_query of a plugin, using the provided name/value pairs. + * All properties except <literal>"id"</literal> and + * <literal>"purple-abi"</literal> are optional. + * Valid property names are: + * <informaltable frame='none'> + * <tgroup cols='2'><tbody> + * <row><entry><literal>"id"</literal></entry> + * <entry>(string) The ID of the plugin.</entry> + * <row><entry><literal>"abi-version"</literal></entry> + * <entry>(<type>guint32</type>) The ABI version required by the + * <row><entry><literal>"name"</literal></entry> + * <entry>(string) The translated name of the plugin.</entry> + * <row><entry><literal>"version"</literal></entry> + * <entry>(string) Version of the plugin.</entry> + * <row><entry><literal>"category"</literal></entry> + * <entry>(string) Primary category of the plugin.</entry> + * <row><entry><literal>"summary"</literal></entry> + * <entry>(string) Brief summary of the plugin.</entry> + * <row><entry><literal>"description"</literal></entry> + * <entry>(string) Full description of the plugin.</entry> + * <row><entry><literal>"authors"</literal></entry> + * <entry>(<type>const gchar * const *</type>) A %NULL-terminated list of + * plugin authors. format: First Last <user\@domain.com></entry> + * <row><entry><literal>"website"</literal></entry> + * <entry>(string) Website of the plugin.</entry> + * <row><entry><literal>"icon"</literal></entry> + * <entry>(string) Path to a plugin's icon.</entry> + * <row><entry><literal>"license-id"</literal></entry> + * <entry>(string) Short name of the plugin's license. This should + * either be an identifier of the license from + * <ulink url="http://dep.debian.net/deps/dep5/#license-specification"> + * DEP5</ulink> or "Other" for custom licenses.</entry> + * <row><entry><literal>"license-text"</literal></entry> + * <entry>(string) The text of the plugin's license, if unlisted on + * <row><entry><literal>"license-url"</literal></entry> + * <entry>(string) The plugin's license URL, if unlisted on DEP5.</entry> + * <row><entry><literal>"dependencies"</literal></entry> + * <entry>(<type>const gchar * const *</type>) A %NULL-terminated list of + * plugin IDs required by the plugin.</entry> + * <row><entry><literal>"actions-cb"</literal></entry> + * <entry>(#PurplePluginActionsCb) Callback that returns a list of + * actions the plugin can perform.</entry> + * <row><entry><literal>"extra-cb"</literal></entry> + * <entry>(#PurplePluginExtraCb) Callback that returns a newly + * allocated string denoting extra information about a plugin.</entry> + * <row><entry><literal>"pref-frame-cb"</literal></entry> + * <entry>(#PurplePluginPrefFrameCb) Callback that returns a + * preferences frame for the plugin.</entry> + * <row><entry><literal>"pref-request-cb"</literal></entry> + * <entry>(#PurplePluginPrefRequestCb) Callback that returns a + * preferences request handle for the plugin.</entry> + * <row><entry><literal>"flags"</literal></entry> + * <entry>(#PurplePluginInfoFlags) The flags for a plugin.</entry> + * See #PURPLE_PLUGIN_ABI_VERSION, + * <link linkend="chapter-plugin-ids">Plugin IDs</link>. + * Returns: A new #PurplePluginInfo instance. +GPluginPluginInfo *purple_plugin_info_new(const char *first_property, ...) G_GNUC_NULL_TERMINATED; + * purple_plugin_info_get_actions_cb: + * @info: The plugin info to get the callback from. + * Returns the callback that retrieves the list of actions a plugin can perform + * Returns: The callback that returns a list of #PurplePluginAction + * instances corresponding to the actions a plugin can perform. +PurplePluginActionsCb purple_plugin_info_get_actions_cb(PurplePluginInfo *info); + * purple_plugin_info_get_extra_cb: + * @info: The plugin info to get extra information from. + * Returns a callback that gives extra information about a plugin. You must + * free the string returned by this callback. + * Returns: (transfer none): The callback that returns extra information about a plugin. +PurplePluginExtraCb purple_plugin_info_get_extra_cb(PurplePluginInfo *info); + * purple_plugin_info_get_pref_frame_cb: + * @info: The plugin info to get the callback from. + * Returns the callback that retrieves the preferences frame for a plugin, set + * via the "pref-frame-cb" property of the plugin info. + * Returns: The callback that returns the preferences frame. +PurplePluginPrefFrameCb purple_plugin_info_get_pref_frame_cb(PurplePluginInfo *info); + * purple_plugin_info_get_pref_request_cb: + * @info: The plugin info to get the callback from. + * Returns the callback that retrieves the preferences request handle for a + * plugin, set via the "pref-request-cb" property of the plugin info. + * Returns: (transfer none): The callback that returns the preferences request handle. +PurplePluginPrefRequestCb purple_plugin_info_get_pref_request_cb(PurplePluginInfo *info); + * purple_plugin_info_get_flags: + * @info: The plugin's info instance. + * Returns the plugin's flags. + * Returns: The flags of the plugin. +PurplePluginInfoFlags purple_plugin_info_get_flags(PurplePluginInfo *info); + * purple_plugin_info_get_error: + * @info: The plugin info. + * Returns an error in the plugin info that would prevent the plugin from being + * Returns: The plugin info error, or %NULL. +const gchar *purple_plugin_info_get_error(PurplePluginInfo *info); + * purple_plugin_info_get_unloaded: + * @info: The #PurplePluginInfo instance. + * Gets whether or not the plugin has been unloaded. + * Returns: %TRUE if the plugin has been unloaded previously, or %FALSE if not. +gboolean purple_plugin_info_get_unloaded(PurplePluginInfo *info); + * purple_plugin_info_set_unloaded: + * @info: The #PurplePluginInfo instance. + * @unloaded: %TRUE to say the plugin has been unloaded. + * Sets the unloaded state of @info to @unloaded. +void purple_plugin_info_set_unloaded(PurplePluginInfo *info, gboolean unloaded); +#endif /* PURPLE_PLUGIN_INFO_H */ --- a/po/POTFILES.in Thu Jun 17 23:43:50 2021 -0500
+++ b/po/POTFILES.in Fri Jun 18 00:00:00 2021 -0500
@@ -255,6 +255,7 @@
libpurple/purplenoopcredentialprovider.c
libpurple/purpleoptions.c
libpurple/purplepresence.c
+libpurple/purpleplugininfo.c libpurple/purpleprotocolattention.c
libpurple/purpleprotocolchat.c
libpurple/purpleprotocolclient.c