summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-12-05 10:28:15 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-12-05 10:44:28 (GMT)
commit333e68541e376a7b86703fad8e917f71c0f243d0 (patch)
treea658682ed01ba8dbb4d5ad0edab4999dd9e9ff54
parent1e3fa9b79ebe55698e2aa7d5484baec7e8400a8f (diff)
Extended the plugin API to include some panel events.
-rw-r--r--plugins/pychrysalide/constants.c3
-rw-r--r--plugins/pychrysalide/plugin.c139
-rw-r--r--src/gui/panel.c7
-rw-r--r--src/plugins/pglist.h8
-rw-r--r--src/plugins/plugin-def.h11
-rw-r--r--src/plugins/plugin-int.h8
-rw-r--r--src/plugins/plugin.c95
-rw-r--r--src/plugins/plugin.h7
8 files changed, 278 insertions, 0 deletions
diff --git a/plugins/pychrysalide/constants.c b/plugins/pychrysalide/constants.c
index e31a8fe..ded25c3 100644
--- a/plugins/pychrysalide/constants.c
+++ b/plugins/pychrysalide/constants.c
@@ -57,7 +57,10 @@ bool define_plugin_module_constants(PyTypeObject *type)
if (result) result = add_const_to_group(values, "PLUGIN_INIT", PGA_PLUGIN_INIT);
if (result) result = add_const_to_group(values, "PLUGIN_EXIT", PGA_PLUGIN_EXIT);
if (result) result = add_const_to_group(values, "NATIVE_LOADED", PGA_NATIVE_LOADED);
+ if (result) result = add_const_to_group(values, "TYPE_BUILDING", PGA_TYPE_BUILDING);
if (result) result = add_const_to_group(values, "GUI_THEME", PGA_GUI_THEME);
+ if (result) result = add_const_to_group(values, "PANEL_CREATION", PGA_PANEL_CREATION);
+ if (result) result = add_const_to_group(values, "PANEL_DOCKING", PGA_PANEL_DOCKING);
if (result) result = add_const_to_group(values, "CONTENT_EXPLORER", PGA_CONTENT_EXPLORER);
if (result) result = add_const_to_group(values, "CONTENT_RESOLVER", PGA_CONTENT_RESOLVER);
if (result) result = add_const_to_group(values, "CONTENT_ANALYZED", PGA_CONTENT_ANALYZED);
diff --git a/plugins/pychrysalide/plugin.c b/plugins/pychrysalide/plugin.c
index a552aaa..b3bcce5 100644
--- a/plugins/pychrysalide/plugin.c
+++ b/plugins/pychrysalide/plugin.c
@@ -63,6 +63,12 @@ static void py_plugin_module_notify_native_loaded_wrapper(GPluginModule *, Plugi
/* Complète une liste de resources pour thème. */
static void py_plugin_module_include_theme_wrapper(const GPluginModule *, PluginAction, gboolean, char ***, size_t *);
+/* Rend compte de la création d'un panneau. */
+static void py_plugin_module_notify_panel_creation_wrapper(const GPluginModule *, PluginAction, GPanelItem *);
+
+/* Rend compte d'un affichage ou d'un retrait de panneau. */
+static void py_plugin_module_notify_panel_docking_wrapper(const GPluginModule *, PluginAction, GPanelItem *, bool);
+
/* Procède à une opération liée à un contenu binaire. */
static void py_plugin_module_handle_binary_content_wrapper(const GPluginModule *, PluginAction, GBinContent *, wgroup_id_t, GtkStatusStack *);
@@ -228,6 +234,8 @@ static void py_plugin_module_init_gclass(GPluginModuleClass *class, gpointer unu
class->native_loaded = py_plugin_module_notify_native_loaded_wrapper;
class->include_theme = py_plugin_module_include_theme_wrapper;
+ class->notify_panel = py_plugin_module_notify_panel_creation_wrapper;
+ class->notify_docking = py_plugin_module_notify_panel_docking_wrapper;
class->handle_content = py_plugin_module_handle_binary_content_wrapper;
class->handle_loaded = py_plugin_module_handle_loaded_content_wrapper;
@@ -287,6 +295,8 @@ static int py_plugin_module_init(PyObject *self, PyObject *args, PyObject *kwds)
" have to be defined for new classes:\n" \
"* pychrysalide.PluginModule._notify_native_loaded();\n" \
"* pychrysalide.PluginModule._include_theme();\n" \
+ "* pychrysalide.PluginModule._on_panel_creation;\n" \
+ "* pychrysalide.PluginModule._on_panel_docking();\n" \
"* pychrysalide.PluginModule._handle_binary_content();\n" \
"* pychrysalide.PluginModule._handle_loaded_content();\n" \
"* pychrysalide.PluginModule._handle_format_analysis();\n" \
@@ -530,6 +540,133 @@ static void py_plugin_module_include_theme_wrapper(const GPluginModule *plugin,
/******************************************************************************
* *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* item = nouveau panneau créé. *
+* *
+* Description : Rend compte de la création d'un panneau. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_plugin_module_notify_panel_creation_wrapper(const GPluginModule *plugin, PluginAction action, GPanelItem *item)
+{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan d'exécution */
+
+#define PLUGIN_MODULE_ON_PANEL_CREATION_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _on_panel_creation, "$self, action, item, /", \
+ METH_VARARGS, \
+ "Abstract method called when a new instance of panel is created.\n" \
+ "\n" \
+ "The expected *action* is a pychrysalide.PluginModule.PluginAction" \
+ " value and the *item* is a pychrysalide.gui.PanelItem instance.\n" \
+ "\n" \
+ "This method has to be defined in order to handle action such as" \
+ " *PANEL_CREATION*." \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(plugin));
+
+ if (has_python_method(pyobj, "_on_panel_creation"))
+ {
+ args = PyTuple_New(2);
+
+ PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action));
+ PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(item)));
+
+ pyret = run_python_method(pyobj, "_on_panel_creation", args);
+
+ Py_XDECREF(pyret);
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* item = panneau marqué par un changement d'affichage. *
+* dock = indique une accroche et non un décrochage. *
+* *
+* Description : Rend compte d'un affichage ou d'un retrait de panneau. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_plugin_module_notify_panel_docking_wrapper(const GPluginModule *plugin, PluginAction action, GPanelItem *item, bool dock)
+{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pydock; /* Valeur booléenne à joindre */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan d'exécution */
+
+#define PLUGIN_MODULE_ON_PANEL_DOCKING_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _on_panel_docking, "$self, action, item, dock, /", \
+ METH_VARARGS, \
+ "Abstract method called when a panel is docked or undocked into" \
+ " the Chrysalide main graphical interface.\n" \
+ "\n" \
+ "The expected *action* is a pychrysalide.PluginModule.PluginAction" \
+ " value, the *item* is a pychrysalide.gui.PanelItem instance and" \
+ " the *dock* parameter indicates if the panel request a docking" \
+ " operation or an undocking one.\n" \
+ "\n" \
+ "This method has to be defined in order to handle action such as" \
+ " *PANEL_DOCKING*." \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(plugin));
+
+ if (has_python_method(pyobj, "_on_panel_docking"))
+ {
+ args = PyTuple_New(3);
+
+ pydock = (dock ? Py_True : Py_False);
+ Py_INCREF(pydock);
+
+ PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action));
+ PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(item)));
+ PyTuple_SetItem(args, 2, pydock);
+
+ pyret = run_python_method(pyobj, "_on_panel_docking", args);
+
+ Py_XDECREF(pyret);
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : plugin = greffon à manipuler. *
* action = type d'action attendue. *
* content = contenu binaire à traiter. *
@@ -1494,6 +1631,8 @@ PyTypeObject *get_python_plugin_module_type(void)
static PyMethodDef py_plugin_module_methods[] = {
PLUGIN_MODULE_NOTIFY_NATIVE_LOADED_WRAPPER,
PLUGIN_MODULE_INCLUDE_THEME_WRAPPER,
+ PLUGIN_MODULE_ON_PANEL_CREATION_WRAPPER,
+ PLUGIN_MODULE_ON_PANEL_DOCKING_WRAPPER,
PLUGIN_MODULE_HANDLE_BINARY_CONTENT_WRAPPER,
PLUGIN_MODULE_HANDLE_LOADED_CONTENT_WRAPPER,
PLUGIN_MODULE_HANDLE_BINARY_FORMAT_ANALYSIS_WRAPPER,
diff --git a/src/gui/panel.c b/src/gui/panel.c
index a509f40..976a2d7 100644
--- a/src/gui/panel.c
+++ b/src/gui/panel.c
@@ -38,6 +38,7 @@
#include "../gtkext/gtkdockable-int.h"
#include "../gtkext/named.h"
#include "../plugins/dt.h"
+#include "../plugins/pglist.h"
@@ -601,6 +602,8 @@ GPanelItem *g_panel_item_new(GType type, const char *path)
register_editor_item(G_EDITOR_ITEM(result));
+ notify_panel_creation(result);
+
singleton:
if (path != NULL)
@@ -818,6 +821,8 @@ void g_panel_item_dock(GPanelItem *item)
if (G_PANEL_ITEM_GET_CLASS(item)->ack_dock != NULL)
G_PANEL_ITEM_GET_CLASS(item)->ack_dock(item);
+ notify_panel_docking(item, true);
+
}
@@ -895,6 +900,8 @@ void g_panel_item_undock(GPanelItem *item)
if (G_PANEL_ITEM_GET_CLASS(item)->ack_undock != NULL)
G_PANEL_ITEM_GET_CLASS(item)->ack_undock(item);
+ notify_panel_docking(item, false);
+
personality = gtk_panel_item_class_get_personality(G_PANEL_ITEM_GET_CLASS(item));
if (personality != PIP_PERSISTENT_SINGLETON)
diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h
index fd8e30a..ccf854f 100644
--- a/src/plugins/pglist.h
+++ b/src/plugins/pglist.h
@@ -118,6 +118,14 @@ GPluginModule **get_all_plugins_for_action(PluginAction, size_t *);
#define include_plugin_theme(d, r, c) \
process_all_plugins_for(PGA_GUI_THEME, g_plugin_module_include_theme, d, r, c)
+/* DPS_RUNNING */
+
+#define notify_panel_creation(i) \
+ process_all_plugins_for(PGA_PANEL_CREATION, g_plugin_module_notify_panel_creation, i)
+
+#define notify_panel_docking(i, d) \
+ process_all_plugins_for(PGA_PANEL_DOCKING, g_plugin_module_notify_panel_docking, i, d)
+
/* DPS_CONTENT */
#define handle_binary_content(a, c, i, s) \
diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h
index 5a2dc54..e99d7b1 100644
--- a/src/plugins/plugin-def.h
+++ b/src/plugins/plugin-def.h
@@ -79,6 +79,7 @@ typedef uint32_t plugin_action_t;
/* DPC_GUI */
#define DPS_SETUP DEFINE_PLUGIN_SUB_CATEGORY(0)
+#define DPS_RUNNING DEFINE_PLUGIN_SUB_CATEGORY(1)
/* DPC_BINARY_PROCESSING */
@@ -133,6 +134,16 @@ typedef enum _PluginAction
PGA_GUI_THEME = DPC_GUI | DPS_SETUP | DEFINE_PLUGIN_ACTION(0),
/**
+ * DPC_GUI | DPS_RUNNING
+ */
+
+ /* Accrochage / décrochage de panneaux */
+ PGA_PANEL_CREATION = DPC_GUI | DPS_RUNNING | DEFINE_PLUGIN_ACTION(0),
+
+ /* Accrochage / décrochage de panneaux */
+ PGA_PANEL_DOCKING = DPC_GUI | DPS_RUNNING | DEFINE_PLUGIN_ACTION(1),
+
+ /**
* DPC_BINARY_PROCESSING | DPS_CONTENT
*/
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 129e155..9dd9173 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -60,6 +60,12 @@ typedef void (* pg_handle_loaded_fc) (const GPluginModule *, PluginAction, GLoad
/* Complète une liste de resources pour thème. */
typedef void (* pg_include_theme_fc) (const GPluginModule *, PluginAction, gboolean, char ***, size_t *);
+/* Rend compte de la création d'un panneau. */
+typedef void (* pg_notify_panel_fc) (const GPluginModule *, PluginAction, GPanelItem *);
+
+/* Rend compte d'un affichage ou d'un retrait de panneau. */
+typedef void (* pg_notify_docking_fc) (const GPluginModule *, PluginAction, GPanelItem *, bool);
+
/* Assure l'interprétation d'un format en différé. */
typedef bool (* pg_handle_format_analysis_fc) (const GPluginModule *, PluginAction, GKnownFormat *, wgroup_id_t, GtkStatusStack *);
@@ -107,6 +113,8 @@ struct _GPluginModuleClass
pg_get_modname_fc get_modname; /* Fourniture du nom brut */
pg_include_theme_fc include_theme; /* Extension d'un thème */
+ pg_notify_panel_fc notify_panel; /* Création de panneau */
+ pg_notify_docking_fc notify_docking; /* Affichage ou retrait */
pg_handle_content_fc handle_content; /* Explorations ou résolutions */
pg_handle_loaded_fc handle_loaded; /* Traitement de contenu chargé*/
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index df593ea..8b3654e 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -373,6 +373,28 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
break;
+ case DPS_RUNNING:
+
+ switch (action)
+ {
+ case PGA_PANEL_CREATION:
+ valid = check_plugin_symbol(module, "chrysalide_plugin_on_panel_creation");
+ break;
+
+ case PGA_PANEL_DOCKING:
+ valid = check_plugin_symbol(module, "chrysalide_plugin_on_panel_docking");
+ break;
+
+ default:
+ log_variadic_message(LMT_WARNING,
+ _("Unknown action '0x%02x' in plugin '%s'..."),
+ interface->actions[i], filename);
+ break;
+
+ }
+
+ break;
+
default:
log_variadic_message(LMT_WARNING,
_("Unknown sub-category '0x%02x' in plugin '%s'..."), sub, filename);
@@ -640,6 +662,28 @@ static void g_plugin_module_init_gclass(GPluginModuleClass *class, GModule *modu
break;
+ case DPS_RUNNING:
+
+ switch (action)
+ {
+ case PGA_PANEL_CREATION:
+ load_plugin_symbol(module, "chrysalide_plugin_on_panel_creation",
+ &class->notify_panel);
+ break;
+
+ case PGA_PANEL_DOCKING:
+ load_plugin_symbol(module, "chrysalide_plugin_on_panel_docking",
+ &class->notify_docking);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
default:
assert(false);
break;
@@ -1270,6 +1314,57 @@ void g_plugin_module_include_theme(const GPluginModule *plugin, PluginAction act
/******************************************************************************
* *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* item = nouveau panneau créé. *
+* *
+* Description : Rend compte de la création d'un panneau. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_plugin_module_notify_panel_creation(const GPluginModule *plugin, PluginAction action, GPanelItem *item)
+{
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ class->notify_panel(plugin, action, item);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* item = panneau marqué par un changement d'affichage. *
+* dock = indique une accroche et non un décrochage. *
+* *
+* Description : Rend compte d'un affichage ou d'un retrait de panneau. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_plugin_module_notify_panel_docking(const GPluginModule *plugin, PluginAction action, GPanelItem *item, bool dock)
+{
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ class->notify_docking(plugin, action, item, dock);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : plugin = greffon à manipuler. *
* action = type d'action attendue. *
* content = contenu binaire à traiter. *
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index f65d0eb..3e8d9c1 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -36,6 +36,7 @@
#include "../format/known.h"
#include "../format/preload.h"
#include "../gtkext/gtkstatusstack.h"
+#include "../gui/panel.h"
@@ -114,6 +115,12 @@ gpointer g_plugin_module_build_type_instance(GPluginModule *, PluginAction, GTyp
/* Complète une liste de resources pour thème. */
void g_plugin_module_include_theme(const GPluginModule *, PluginAction, gboolean, char ***, size_t *);
+/* Rend compte de la création d'un panneau. */
+void g_plugin_module_notify_panel_creation(const GPluginModule *, PluginAction, GPanelItem *);
+
+/* Rend compte d'un affichage ou d'un retrait de panneau. */
+void g_plugin_module_notify_panel_docking(const GPluginModule *, PluginAction, GPanelItem *, bool);
+
/* Procède à une opération liée à un contenu binaire. */
void g_plugin_module_handle_binary_content(const GPluginModule *, PluginAction, GBinContent *, wgroup_id_t, GtkStatusStack *);