summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/Makefile.am4
-rw-r--r--src/plugins/manager-int.h10
-rw-r--r--src/plugins/native-int.h13
-rw-r--r--src/plugins/native.c29
-rw-r--r--src/plugins/native.h7
-rw-r--r--src/plugins/pglist.c172
-rw-r--r--src/plugins/pglist.h69
-rw-r--r--src/plugins/plugin.c39
-rw-r--r--src/plugins/tweakable-int.h50
-rw-r--r--src/plugins/tweakable.c98
-rw-r--r--src/plugins/tweakable.h62
11 files changed, 419 insertions, 134 deletions
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 7d375e3..fa65484 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -10,7 +10,9 @@ libplugins_la_SOURCES = \
plugin-def.h \
plugin-int.h \
plugin.h plugin.c \
- self.h
+ self.h \
+ tweakable-int.h \
+ tweakable.h tweakable.c
libplugins_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
diff --git a/src/plugins/manager-int.h b/src/plugins/manager-int.h
index 5ccc8f8..dbd1d69 100644
--- a/src/plugins/manager-int.h
+++ b/src/plugins/manager-int.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * singleton-int.h - définitions internes propres aux interventions dans la gestion des extensions
+ * manager-int.h - définitions internes propres aux interventions dans la gestion des extensions
*
* Copyright (C) 2025 Cyrille Bagard
*
@@ -21,8 +21,8 @@
*/
-#ifndef _PLUGINS_CONTAINER_INT_H
-#define _PLUGINS_CONTAINER_INT_H
+#ifndef _PLUGINS_MANAGER_INT_H
+#define _PLUGINS_MANAGER_INT_H
#include "manager.h"
@@ -39,7 +39,7 @@ typedef void (* handle_native_plugins_cb) (GPluginManager *);
typedef void (* handle_all_plugins_cb) (GPluginManager *);
-/* Instance d'objet visant à être unique (interface) */
+/* Accompagnant dans la gestion des extensions (interface) */
struct _GPluginManagerInterface
{
GTypeInterface base_iface; /* A laisser en premier */
@@ -51,4 +51,4 @@ struct _GPluginManagerInterface
-#endif /* _PLUGINS_CONTAINER_INT_H */
+#endif /* _PLUGINS_MANAGER_INT_H */
diff --git a/src/plugins/native-int.h b/src/plugins/native-int.h
index 8b8e0eb..575994f 100644
--- a/src/plugins/native-int.h
+++ b/src/plugins/native-int.h
@@ -41,7 +41,18 @@ struct _GNativePlugin
{
GPluginModule parent; /* A laisser en premier */
- GModule *module; /* Abstration de manipulation */
+ /**
+ * Le module porte le code et les données en mémoire.
+ *
+ * Les fonctions *_dispose() et *_finalize() accompagnant la libération des
+ * greffons de la mémoire ne peuvent donc pas libérer ce module car elles
+ * scieraient la branche sur laquelle elles se trouvent.
+ *
+ * Par ailleurs, même s'ils sont conservés dans chaque greffon, les modules
+ * sont mis en place dans le code principal. C'est donc ce dernier qui les
+ * libère, dans la fonction on_plugin_ref_toggle().
+ */
+ GModule *module; /* Structure de chargement GLib*/
};
diff --git a/src/plugins/native.c b/src/plugins/native.c
index fedccbe..de20abe 100644
--- a/src/plugins/native.c
+++ b/src/plugins/native.c
@@ -131,12 +131,6 @@ static void g_native_plugin_init(GNativePlugin *plugin)
static void g_native_plugin_dispose(GNativePlugin *plugin)
{
- if (plugin->module != NULL)
- {
- g_module_close(plugin->module);
- plugin->module = NULL;
- }
-
G_OBJECT_CLASS(g_native_plugin_parent_class)->dispose(G_OBJECT(plugin));
}
@@ -194,6 +188,29 @@ bool g_native_plugin_create(GNativePlugin *plugin, const char *name, const char
}
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à consulter. *
+* *
+* Description : Renvoie la structure opaque associée au module en mémoire. *
+* *
+* Retour : Structure de chargement côté GLib. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GModule *g_native_plugin_get_module(const GNativePlugin *plugin)
+{
+ GModule *result; /* Accès au module à renvoyer */
+
+ result = plugin->module;
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
diff --git a/src/plugins/native.h b/src/plugins/native.h
index 205342c..18039c8 100644
--- a/src/plugins/native.h
+++ b/src/plugins/native.h
@@ -26,6 +26,9 @@
#define _PLUGINS_NATIVE_H
+#include <gmodule.h>
+
+
#include "../glibext/helpers.h"
@@ -35,5 +38,9 @@
DECLARE_GTYPE(GNativePlugin, g_native_plugin, G, NATIVE_PLUGIN);
+/* Renvoie la structure opaque associée au module en mémoire. */
+GModule *g_native_plugin_get_module(const GNativePlugin *);
+
+
#endif /* _PLUGINS_NATIVE_H */
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index 277e4f5..3e107b8 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -37,9 +37,10 @@
#include "manager.h"
+#include "native.h"
#include "plugin-int.h"
#include "../common/cpp.h"
-#include "../common/extstr.h" // REMME ?
+#include "../common/extstr.h"
#include "../core/logs.h"
#include "../core/nox.h"
#include "../core/paths.h"
@@ -69,6 +70,9 @@ static void browse_directory_for_plugins(const char *);
/* Suit les variations du compteur de références d'un greffon. */
static void on_plugin_ref_toggle(gpointer, GPluginModule *, gboolean);
+/* Fournit le greffon répondant à un nom donné. */
+static GPluginModule *_find_plugin_by_name(const char *, size_t *);
+
/******************************************************************************
@@ -134,71 +138,23 @@ bool init_all_plugins(bool load)
void exit_all_plugins(void)
{
-
-#if 0 //////
-
-
size_t i; /* Boucle de parcours */
- const plugin_interface *pg_iface; /* Définition du greffon */
lock_plugin_list_for_reading();
- if (_pg_list != NULL)
+ for (i = 0; i < _pg_count; i++)
{
- for (i = 0; i < _pg_count; i++)
- {
- assert(_pg_list[i] != NULL);
-
- /**
- * Si le greffon a conduit à la mise en place d'autres greffons, le
- * système de dépendances ne suffit pas pour le décompte des références :
- * le greffon voit à un instant T son compteur décroître ici ; à un
- * instant T+1, un greffon fils décrémente à son tour le compteur vers
- * le greffon principal.
- *
- * Le compteur du conteneur tombe alors à 0, et le code correspondant
- * est retiré. Lorsque que le flot d'exécution revient à la procédure
- * de sortie du second greffon, son code n'est plus en mémoire.
- *
- * On s'assure donc que les greffons qui génèrent d'autres greffons
- * sont bien traités en dernier.
- */
-
- pg_iface = g_plugin_module_get_interface(_pg_list[i]);
-
- if (pg_iface != NULL && pg_iface->container)
- g_object_ref(_pg_list[i]);
-
- g_object_unref(_pg_list[i]);
-
- }
-
- for (i = 0; i < _pg_count; i++)
- {
- if (_pg_list[i] == NULL)
- continue;
-
- pg_iface = g_plugin_module_get_interface(_pg_list[i]);
-
- if (pg_iface == NULL || !pg_iface->container)
- continue;
-
- g_object_unref(_pg_list[i]);
-
- }
+ assert(_pg_list[i] != NULL);
+ unref_object(_pg_list[i]);
+ }
+ if (_pg_list != NULL)
free(_pg_list);
- }
-
unlock_plugin_list_for_reading();
g_rw_lock_clear(&_pg_lock);
-
-
-#endif
-
}
@@ -388,22 +344,10 @@ static void browse_directory_for_plugins(const char *dir)
else
{
-
- printf("// Candidate // %s\n", filename);
-
has_alt = check_for_plugin_versions(dir, namelist[k]->d_name, &is_nox, &is_ui);
- printf(" -> nox=%d ui=%d -> alt? %d\n", is_nox, is_ui, has_alt);
-
-
if ((nox_mode && is_nox) || (!nox_mode && ((is_nox && !has_alt) || is_ui)))
{
-
-
- printf(" ---> load!\n");
-
-
-
module = g_module_open(filename, G_MODULE_BIND_LAZY);
if (module == NULL)
{
@@ -413,32 +357,18 @@ static void browse_directory_for_plugins(const char *dir)
goto next_file;
}
-
- printf(" (main) module=%p '%s'\n", module, g_module_name(module));
-
+ get_instance = NULL;
if (!g_module_symbol(module, "get_chrysalide_plugin_instance", (gpointer *)&get_instance))
- {
log_variadic_message(LMT_ERROR,
_("No '%s' entry in plugin candidate '%s'"),
"<sym>", filename);
-
-
- }
-
-
if (get_instance == NULL)
plugin = NULL;
else
plugin = get_instance(module);
-
-
- printf(" ===> plugin: %p\n", plugin);
-
-
-
if (plugin != NULL)
{
register_plugin(plugin);
@@ -485,6 +415,7 @@ static void on_plugin_ref_toggle(gpointer unused, GPluginModule *plugin, gboolea
const char *name; /* Désignation du greffon */
size_t index; /* Indice du greffon */
GPluginModule *same; /* Juste pour la récupération */
+ GModule *module; /* Structure de chargement GLib*/
if (last)
{
@@ -492,15 +423,44 @@ static void on_plugin_ref_toggle(gpointer unused, GPluginModule *plugin, gboolea
name = g_plugin_module_get_name(plugin);
- same = get_plugin_by_name(name, &index);
+ /**
+ * Les mécanismes de g_object_unref() prennent en compte la bascule d'un
+ * compteur de références initialement à 2 avant appel pour déclencher
+ * cet appel à on_plugin_ref_toggle() mis en place par g_object_add_toggle_ref().
+ *
+ * Incrémenter ce compteur à nouveau, via get_plugin_by_name(), puis le
+ * décrémenter ensuite via unref_object() va conduire à une nouvelle
+ * bascule des statuts de suivi dans g_object_unref().
+ *
+ * Il est ainsi impératif de rechercher une instance du greffon dans
+ * la liste des extensions sans toucher au compteur de références.
+ */
+
+ same = _find_plugin_by_name(name, &index);
+
assert(same != NULL);
assert(same == plugin);
- g_clear_object(&_pg_list[index]);
+ _pg_list[index] = NULL;
+
+ /**
+ * Suppression de la dernière référence.
+ */
+
+ if (G_IS_NATIVE_PLUGIN(plugin))
+ module = g_native_plugin_get_module(G_NATIVE_PLUGIN(plugin));
+ else
+ module = NULL;
g_object_remove_toggle_ref(G_OBJECT(same), (GToggleNotify)on_plugin_ref_toggle, NULL);
- unref_object(same);
+ /**
+ * Plus aucun code issu du greffon n'est désormais utile. Le module associé peut
+ * être libéré de la mémoire.
+ */
+
+ if (module != NULL)
+ g_module_close(module);
}
@@ -622,13 +582,18 @@ void load_remaning_plugins(void)
/* Supprime les greffons non chargés */
- for (i = 0; i < _pg_count; i++)
+ for (i = 0; i < _pg_count;)
{
flags = g_plugin_module_get_flags(_pg_list[i]);
- if ((flags & PSF_LOADED) == 0)
+ if (flags & PSF_LOADED)
+ i++;
+
+ else
{
- g_object_unref(G_OBJECT(_pg_list[i]));
+ unref_object(_pg_list[i]);
+
+ assert(_pg_list[i] == NULL);
memmove(&_pg_list[i], &_pg_list[i + 1], (_pg_count - i - 1) * sizeof(GPluginModule *));
_pg_count--;
@@ -655,11 +620,12 @@ void load_remaning_plugins(void)
* *
* Retour : Instance du greffon trouvé ou NULL si aucun. *
* *
-* Remarques : - *
+* Remarques : Le compteur de référence d'un greffon trouvé n'est pas *
+* modifié. *
* *
******************************************************************************/
-GPluginModule *get_plugin_by_name(const char *name, size_t *index)
+static GPluginModule *_find_plugin_by_name(const char *name, size_t *index)
{
GPluginModule *result; /* Greffon trouvé à renvoyer */
size_t i; /* Boucle de parcours */
@@ -682,7 +648,6 @@ GPluginModule *get_plugin_by_name(const char *name, size_t *index)
if (strcmp(current, name) == 0)
{
result = _pg_list[i];
- ref_object(result);
if (index != NULL)
*index = i;
@@ -698,6 +663,33 @@ GPluginModule *get_plugin_by_name(const char *name, size_t *index)
/******************************************************************************
* *
+* Paramètres : name = désignation du greffon recherché. *
+* index = indice du greffon trouvé. [OUT] *
+* *
+* Description : Fournit le greffon répondant à un nom donné. *
+* *
+* Retour : Instance du greffon trouvé ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GPluginModule *get_plugin_by_name(const char *name, size_t *index)
+{
+ GPluginModule *result; /* Greffon trouvé à renvoyer */
+
+ result = _find_plugin_by_name(name, index);
+
+ if (result != NULL)
+ ref_object(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : count = nombre de greffons trouvés. [OUT] *
* *
* Description : Fournit la liste de l'ensemble des greffons. *
diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h
index 5541493..777b19c 100644
--- a/src/plugins/pglist.h
+++ b/src/plugins/pglist.h
@@ -69,25 +69,60 @@ GPluginModule **get_all_plugins(size_t *);
* Définitions des opérations appliquables à une catégories de greffons.
*/
-#define process_all_plugins_for(tp, cst, fc) \
- do \
- { \
- size_t __count; \
- GPluginModule **__list; \
- size_t __i; \
- __list = get_all_plugins(&__count); \
- for (__i = 0; __i < __count; __i++) \
- { \
- if (G_TYPE_CHECK_INSTANCE_TYPE(__list[__i], tp)) \
- fc(cst(__list[__i])); \
- unref_object(__list[__i]); \
- } \
- if (__list != NULL) \
- free(__list); \
- } \
+#define process_all_plugins_for(tp, cst, fc) \
+ do \
+ { \
+ size_t __count; \
+ GPluginModule **__list; \
+ size_t __i; \
+ GPluginModule *__pg; \
+ __list = get_all_plugins(&__count); \
+ for (__i = 0; __i < __count; __i++) \
+ { \
+ __pg = __list[__i]; \
+ if (G_TYPE_CHECK_INSTANCE_TYPE(__pg, tp)) \
+ fc(cst(__pg)); \
+ unref_object(__pg); \
+ } \
+ if (__list != NULL) \
+ free(__list); \
+ } \
while (0)
-
+#define accumulate_from_all_plugins(tp, cst, fc, atp, cnt) \
+ ({ \
+ atp *__acc_list; \
+ size_t __count; \
+ GPluginModule **__list; \
+ size_t __i; \
+ GPluginModule *__pg; \
+ size_t __tmp_count; \
+ atp *__tmp_list; \
+ *cnt = 0; \
+ __acc_list = NULL; \
+ __list = get_all_plugins(&__count); \
+ for (__i = 0; __i < __count; __i++) \
+ { \
+ __pg = __list[__i]; \
+ if (G_TYPE_CHECK_INSTANCE_TYPE(__pg, tp)) \
+ { \
+ __tmp_list = fc(cst(__pg), &__tmp_count); \
+ if (__tmp_list != NULL) \
+ { \
+ __acc_list = realloc(__acc_list, \
+ (*cnt + __tmp_count) * sizeof(atp)); \
+ memcpy(&__acc_list[*cnt], __tmp_list, \
+ __tmp_count * sizeof(atp)); \
+ *cnt += __tmp_count; \
+ free(__tmp_list); \
+ } \
+ } \
+ unref_object(__pg); \
+ } \
+ if (__list != NULL) \
+ free(__list); \
+ __acc_list; \
+ })
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index d14e656..dfdf3ed 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -135,34 +135,45 @@ static void g_plugin_module_init(GPluginModule *plugin)
static void g_plugin_module_dispose(GPluginModule *plugin)
{
size_t i; /* Boucle de parcours */
+ size_t index; /* Indice de greffon visé */
GPluginModule *dependency; /* Module nécessaire */
GPluginModuleClass *class; /* Classe de l'instance active */
- lock_plugin_list_for_reading();
-
- for (i = 0; i < plugin->required_count; i++)
+ if (plugin->dependencies != NULL)
{
- dependency = get_plugin_by_name(plugin->required[i], NULL);
+ lock_plugin_list_for_reading();
- /* Si le chargement a bien été complet avant la sortie... */
- if (dependency != NULL)
+ for (i = 0; i < plugin->required_count; i++)
{
- /* Un coup pour l'appel à get_plugin_by_name(). */
- unref_object(dependency);
+ dependency = get_plugin_by_name(plugin->required[i], &index);
+
+ /* Si la dépendance a bien été pris en compte... */
+ if (test_in_bit_field(plugin->dependencies, index))
+ {
+ assert(dependency != NULL);
+
+ /* Un coup pour l'appel à get_plugin_by_name(). */
+ unref_object(dependency);
- /* Un coup pour la dépendance */
- unref_object(dependency);
+ /* Un coup pour la dépendance */
+ unref_object(dependency);
+
+ }
}
+ unlock_plugin_list_for_reading();
+
}
- unlock_plugin_list_for_reading();
+ if (plugin->flags & PSF_LOADED)
+ {
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
- class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+ if (class->disable != NULL)
+ class->disable(plugin);
- if (class->disable != NULL)
- class->disable(plugin);
+ }
G_OBJECT_CLASS(g_plugin_module_parent_class)->dispose(G_OBJECT(plugin));
diff --git a/src/plugins/tweakable-int.h b/src/plugins/tweakable-int.h
new file mode 100644
index 0000000..776626f
--- /dev/null
+++ b/src/plugins/tweakable-int.h
@@ -0,0 +1,50 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tweakable-int.h - définitions internes propres aux participations aux mécanismes de configuration
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_TWEAKABLE_INT_H
+#define _PLUGINS_TWEAKABLE_INT_H
+
+
+#include "tweakable.h"
+
+
+
+/* ------------------- INTEGRATION DANS L'EDITION DES PREFERENCES ------------------- */
+
+
+/* Fournit une liste de sections de configuration. */
+typedef tweak_info_t * (* get_tweakable_plugin_info) (const GTweakablePlugin *, size_t *);
+
+
+/* Greffon avec des compléments pour l'interface de configuration (interface) */
+struct _GTweakablePluginInterface
+{
+ GTypeInterface base_iface; /* A laisser en premier */
+
+ get_tweakable_plugin_info get_info; /* Récupération de section(s) */
+
+};
+
+
+
+#endif /* _PLUGINS_TWEAKABLE_INT_H */
diff --git a/src/plugins/tweakable.c b/src/plugins/tweakable.c
new file mode 100644
index 0000000..517c4a3
--- /dev/null
+++ b/src/plugins/tweakable.c
@@ -0,0 +1,98 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tweakable.c - participation aux mécanismes de configuration
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "tweakable.h"
+
+
+#include "tweakable-int.h"
+
+
+
+/* ------------------- INTEGRATION DANS L'EDITION DES PREFERENCES ------------------- */
+
+
+/* Procède à l'initialisation de l'interface d'intervention. */
+static void g_tweakable_plugin_default_init(GTweakablePluginInterface *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTEGRATION DANS L'EDITION DES PREFERENCES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type d'une interface pour l'intervention dans la gestion des greffons. */
+G_DEFINE_INTERFACE(GTweakablePlugin, g_tweakable_plugin, G_TYPE_OBJECT)
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface d'intervention. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_tweakable_plugin_default_init(GTweakablePluginInterface *iface)
+{
+ iface->get_info = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = interface à manipuler. *
+* count = taille de la liste renvoyée. [OUT] *
+* *
+* Description : Fournit une liste de sections de configuration. *
+* *
+* Retour : Définition(s) de section de configuration ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+tweak_info_t *g_tweakable_plugin_get_tweak_info(const GTweakablePlugin *plugin, size_t *count)
+{
+ tweak_info_t *result; /* Liste à renvoyer */
+ GTweakablePluginInterface *iface; /* Interface utilisée */
+
+ iface = G_TWEAKABLE_PLUGIN_GET_IFACE(plugin);
+
+ if (iface->get_info != NULL)
+ result = iface->get_info(plugin, count);
+
+ else
+ {
+ *count = 0;
+ result = NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/plugins/tweakable.h b/src/plugins/tweakable.h
new file mode 100644
index 0000000..aea70b4
--- /dev/null
+++ b/src/plugins/tweakable.h
@@ -0,0 +1,62 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tweakable.h - prototypes pour la participation aux mécanismes de configuration
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_TWEAKABLE_H
+#define _PLUGINS_TWEAKABLE_H
+
+
+#include "../glibext/helpers.h"
+#include "../gtkext/tweak.h"
+
+
+
+/* ------------------- INTEGRATION DANS L'EDITION DES PREFERENCES ------------------- */
+
+
+#define G_TYPE_TWEAKABLE_PLUGIN (g_tweakable_plugin_get_type())
+
+DECLARE_INTERFACE(GTweakablePlugin, g_tweakable_plugin, G, TWEAKABLE_PLUGIN);
+
+
+/* Fournit une liste de sections de configuration. */
+tweak_info_t *g_tweakable_plugin_get_tweak_info(const GTweakablePlugin *, size_t *);
+
+
+
+/* -------------------- SOLLICITATION DES FONCTIONNALITES CREEES -------------------- */
+
+
+#define get_tweakable_plugins_info(c) \
+ ({ \
+ tweak_info_t *__all_info; \
+ __all_info = accumulate_from_all_plugins(G_TYPE_TWEAKABLE_PLUGIN, \
+ G_TWEAKABLE_PLUGIN, \
+ g_tweakable_plugin_get_tweak_info, \
+ tweak_info_t, \
+ c); \
+ __all_info; \
+ })
+
+
+
+#endif /* _PLUGINS_TWEAKABLE_H */