From 1c42375efb56bccb2ed55153cfd82826f910cac1 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 9 Jun 2016 00:50:40 +0200 Subject: [PATCH] libnm/vpn: pass NMVpnPluginInfo to the NMVpnEditorPlugin instance The NMVpnPluginInfo is essentially the .name file, that is, a configuration file about the plugin itself. Via NMVpnPluginInfo instance, the NMVpnEditorPlugin can be created. Usually, one would create a NMVpnPluginInfo (that is, reading the .name file) and then create a NMVpnEditorPlugin instance from there. In this case, usually the editor-plugin is owned by the plugin-info instance (although the API allows for creating the editor-plugin independently). Now, pass the NMVpnPluginInfo to the editor-plugin too. This is useful, because then the editor-plugin can look at the .name file. The .name file is not user configuration. Instead it is configuration about the plugin itself. Although the .name file is part of the plugin build artefacts, it is useful to allow the plugin to access the .name file. The reason is, that this can allow the user to easily change a configuration knob of the plugin without requiring to patch or the plugin. --- libnm-core/nm-vpn-editor-plugin.c | 106 ++++++++++++++++++++++++++++++ libnm-core/nm-vpn-editor-plugin.h | 12 ++++ libnm-core/nm-vpn-plugin-info.c | 2 + libnm-core/nm-vpn-plugin-info.h | 4 +- libnm/libnm.ver | 2 + 5 files changed, 125 insertions(+), 1 deletion(-) diff --git a/libnm-core/nm-vpn-editor-plugin.c b/libnm-core/nm-vpn-editor-plugin.c index 09df246957..1a4944b066 100644 --- a/libnm-core/nm-vpn-editor-plugin.c +++ b/libnm-core/nm-vpn-editor-plugin.c @@ -74,6 +74,112 @@ nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface) /*********************************************************************/ +typedef struct { + NMVpnPluginInfo *plugin_info; +} NMVpnEditorPluginPrivate; + +static void +_private_destroy (gpointer data) +{ + NMVpnEditorPluginPrivate *priv = data; + + if (priv->plugin_info) + g_object_remove_weak_pointer ((GObject *) priv->plugin_info, (gpointer *) &priv->plugin_info); + + g_slice_free (NMVpnEditorPluginPrivate, priv); +} + +static NMVpnEditorPluginPrivate * +_private_get (NMVpnEditorPlugin *plugin, gboolean create) +{ + static GQuark quark = 0; + NMVpnEditorPluginPrivate *priv; + + nm_assert (NM_IS_VPN_EDITOR_PLUGIN (plugin)); + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_string ("nm-vpn-editor-plugin-private"); + + priv = g_object_get_qdata ((GObject *) plugin, quark); + if (G_LIKELY (priv)) + return priv; + if (!create) + return NULL; + priv = g_slice_new0 (NMVpnEditorPluginPrivate); + g_object_set_qdata_full ((GObject *) plugin, quark, priv, _private_destroy); + return priv; +} + +#define NM_VPN_EDITOR_PLUGIN_GET_PRIVATE(plugin) _private_get (plugin, TRUE) +#define NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE(plugin) _private_get (plugin, FALSE) + +/*********************************************************************/ + +/** + * nm_vpn_editor_plugin_get_plugin_info: + * @plugin: the #NMVpnEditorPlugin instance + * + * Returns: (transfer-none): if set, return the #NMVpnPluginInfo instance. + * + * Since: 1.4 + */ +NMVpnPluginInfo * +nm_vpn_editor_plugin_get_plugin_info (NMVpnEditorPlugin *plugin) +{ + NMVpnEditorPluginPrivate *priv; + + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL); + + priv = NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE (plugin); + return priv ? priv->plugin_info : NULL; +} + +/** + * nm_vpn_editor_plugin_set_plugin_info: + * @plugin: the #NMVpnEditorPlugin instance + * @plugin_info: (allow-none): a #NMVpnPluginInfo instance or %NULL + * + * Returns: (transfer-none): set or clear the plugin-info instance. + * This takes a weak reference on @plugin_info, to avoid circular + * reference as the plugin-info might also reference the editor-plugin. + * + * Since: 1.4 + */ +void +nm_vpn_editor_plugin_set_plugin_info (NMVpnEditorPlugin *plugin, NMVpnPluginInfo *plugin_info) +{ + NMVpnEditorPluginInterface *interface; + NMVpnEditorPluginPrivate *priv; + + g_return_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin)); + + if (!plugin_info) { + priv = NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE (plugin); + if (!priv) + return; + } else { + g_return_if_fail (NM_IS_VPN_PLUGIN_INFO (plugin_info)); + priv = NM_VPN_EDITOR_PLUGIN_GET_PRIVATE (plugin); + } + + if (priv->plugin_info == plugin_info) + return; + if (priv->plugin_info) + g_object_remove_weak_pointer ((GObject *) priv->plugin_info, (gpointer *) &priv->plugin_info); + priv->plugin_info = plugin_info; + if (priv->plugin_info) + g_object_add_weak_pointer ((GObject *) priv->plugin_info, (gpointer *) &priv->plugin_info); + + if (plugin_info) { + interface = NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin); + if (interface->notify_plugin_info_set) + interface->notify_plugin_info_set (plugin, plugin_info); + } + +} + +/*********************************************************************/ + static NMVpnEditorPlugin * _nm_vpn_editor_plugin_load (const char *plugin_name, gboolean do_file_checks, diff --git a/libnm-core/nm-vpn-editor-plugin.h b/libnm-core/nm-vpn-editor-plugin.h index 82c609b969..dc18f04b74 100644 --- a/libnm-core/nm-vpn-editor-plugin.h +++ b/libnm-core/nm-vpn-editor-plugin.h @@ -34,6 +34,8 @@ G_BEGIN_DECLS +struct _NMVpnPluginInfo; + typedef struct _NMVpnEditorPlugin NMVpnEditorPlugin; typedef struct _NMVpnEditor NMVpnEditor; @@ -119,6 +121,9 @@ typedef struct { GError **error); char * (*get_suggested_filename) (NMVpnEditorPlugin *plugin, NMConnection *connection); + + void (*notify_plugin_info_set) (NMVpnEditorPlugin *plugin, + struct _NMVpnPluginInfo *plugin_info); } NMVpnEditorPluginInterface; GType nm_vpn_editor_plugin_get_type (void); @@ -152,6 +157,13 @@ NMVpnEditorPlugin *nm_vpn_editor_plugin_load (const char *plugin_name, const char *check_service, GError **error); +NM_AVAILABLE_IN_1_4 +struct _NMVpnPluginInfo *nm_vpn_editor_plugin_get_plugin_info (NMVpnEditorPlugin *plugin); +NM_AVAILABLE_IN_1_4 +void nm_vpn_editor_plugin_set_plugin_info (NMVpnEditorPlugin *plugin, struct _NMVpnPluginInfo *plugin_info); + +#include "nm-vpn-plugin-info.h" + G_END_DECLS #endif /* __NM_VPN_EDITOR_PLUGIN_H__ */ diff --git a/libnm-core/nm-vpn-plugin-info.c b/libnm-core/nm-vpn-plugin-info.c index 94911e377b..7a3198c3d9 100644 --- a/libnm-core/nm-vpn-plugin-info.c +++ b/libnm-core/nm-vpn-plugin-info.c @@ -1089,6 +1089,8 @@ nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *self, GError **error) NULL, NULL, error); + if (priv->editor_plugin) + nm_vpn_editor_plugin_set_plugin_info (priv->editor_plugin, self); return priv->editor_plugin; } diff --git a/libnm-core/nm-vpn-plugin-info.h b/libnm-core/nm-vpn-plugin-info.h index 1df8598b80..908ee4827c 100644 --- a/libnm-core/nm-vpn-plugin-info.h +++ b/libnm-core/nm-vpn-plugin-info.h @@ -44,10 +44,12 @@ G_BEGIN_DECLS #define NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM "libnm" #define NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME "GNOME" +struct _NMVpnPluginInfo; + /** * NMVpnPluginInfo: */ -typedef struct { +typedef struct _NMVpnPluginInfo { NM_AVAILABLE_IN_1_2 GObject parent; } NMVpnPluginInfo; diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 9b3a741d97..2dc2103517 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1068,7 +1068,9 @@ global: nm_device_team_get_config; nm_setting_ip6_config_get_token; nm_setting_ip_config_get_dns_priority; + nm_vpn_editor_plugin_get_plugin_info; nm_vpn_editor_plugin_load; + nm_vpn_editor_plugin_set_plugin_info; nm_vpn_plugin_info_get_aliases; nm_vpn_plugin_info_get_auth_dialog; nm_vpn_plugin_info_get_service;