diff options
Diffstat (limited to 'plugins/pychrysa/gui')
-rw-r--r-- | plugins/pychrysa/gui/Makefile.am | 1 | ||||
-rw-r--r-- | plugins/pychrysa/gui/editem.c | 441 | ||||
-rw-r--r-- | plugins/pychrysa/gui/editem.h | 39 | ||||
-rw-r--r-- | plugins/pychrysa/gui/module.c | 2 | ||||
-rw-r--r-- | plugins/pychrysa/gui/panels/panel.c | 33 | ||||
-rw-r--r-- | plugins/pychrysa/gui/panels/panel.h | 4 |
6 files changed, 503 insertions, 17 deletions
diff --git a/plugins/pychrysa/gui/Makefile.am b/plugins/pychrysa/gui/Makefile.am index 48fde30..97c2d46 100644 --- a/plugins/pychrysa/gui/Makefile.am +++ b/plugins/pychrysa/gui/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libpychrysagui.la libpychrysagui_la_SOURCES = \ + editem.h editem.c \ module.h module.c libpychrysagui_la_LIBADD = \ diff --git a/plugins/pychrysa/gui/editem.c b/plugins/pychrysa/gui/editem.c new file mode 100644 index 0000000..3b7a8b8 --- /dev/null +++ b/plugins/pychrysa/gui/editem.c @@ -0,0 +1,441 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * editem.c - prototypes pour l'équivalent Python du fichier "gui/editem.c" + * + * Copyright (C) 2012 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "editem.h" + + +#include <pygobject.h> + + +#include <gui/editem-int.h> + + +#include "../helpers.h" +#include "../quirks.h" + + +#include "../analysis/binary.h" +#include "../gtkext/viewpanel.h" + + + +/* Réagit à un changement du binaire courant. */ +static void _update_editor_item_for_binary_python_wrapper(GEditorItem *, GLoadedBinary *); + +/* Réagit à un changement de vue. */ +static void _update_editor_item_for_view_python_wrapper(GEditorItem *, GtkViewPanel *); + +/* Réagit à un changement de contenu. */ +static void _update_editor_item_for_view_content_python_wrapper(GEditorItem *, GtkViewPanel *); + +/* Réagit à un changement du binaire courant. */ +static PyObject *py_editor_item_update_for_binary(PyObject *, PyObject *); + +/* Réagit à un changement d'affichage principal de contenu. */ +static PyObject *py_editor_item_update_for_view(PyObject *, PyObject *); + +/* Réagit à un changement d'affichage principal de contenu. */ +static PyObject *py_editor_item_update_for_content(PyObject *, PyObject *); + +/* Fournit l'affichage de binaire courant. */ +static PyObject *py_editor_item_get_current_view(PyObject *, PyObject *); + +/* Procède à l'enregistrement d'un élément reactif de l'éditeur. */ +static PyObject *py_editor_item_register(PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : item = élément à actualiser. * +* binary = nouvelle instance de binaire analysé. * +* * +* Description : Réagit à un changement du binaire courant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _update_editor_item_for_binary_python_wrapper(GEditorItem *item, GLoadedBinary *binary) +{ + PyObject *target; /* Version Python de l'élément */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Retour obtenu */ + + /** + * Normalement, l'objet Python est enregistré dans la liste de Chrysalide + * des éléments d'éditeur, via py_editor_item_register(), donc son compteur + * de références doit le maintenir en vie. + * + * On peut donc le récupérer directement depuis l'instane GLib, sans passer + * par la procédure de pygobject, qui obligerait à connaître le type précis + * de l'instance GLib manipulée. + */ + target = pychrysalide_get_pygobject(G_OBJECT(item)); + + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, py_loaded_binary_from_c(binary)); + + value = run_python_method(target, "update_for_binary", args); + + Py_XDECREF(value); + Py_DECREF(args); + Py_DECREF(target); + +} + + +/****************************************************************************** +* * +* Paramètres : item = élément à actualiser. * +* view = nouveau panneau d'affichage actif. * +* * +* Description : Réagit à un changement de vue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _update_editor_item_for_view_python_wrapper(GEditorItem *item, GtkViewPanel *view) +{ + PyObject *target; /* Version Python de l'élément */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Retour obtenu */ + + /** + * Normalement, l'objet Python est enregistré dans la liste de Chrysalide + * des éléments d'éditeur, via py_editor_item_register(), donc son compteur + * de références doit le maintenir en vie. + * + * On peut donc le récupérer directement depuis l'instane GLib, sans passer + * par la procédure de pygobject, qui obligerait à connaître le type précis + * de l'instance GLib manipulée. + */ + target = pychrysalide_get_pygobject(G_OBJECT(item)); + + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, py_view_panel_from_c(view)); + + value = run_python_method(target, "update_for_view", args); + + Py_XDECREF(value); + Py_DECREF(args); + Py_DECREF(target); + +} + + +/****************************************************************************** +* * +* Paramètres : item = élément à actualiser. * +* view = nouveau panneau d'affichage actif. * +* * +* Description : Réagit à un changement de contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _update_editor_item_for_view_content_python_wrapper(GEditorItem *item, GtkViewPanel *view) +{ + PyObject *target; /* Version Python de l'élément */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Retour obtenu */ + + /** + * Normalement, l'objet Python est enregistré dans la liste de Chrysalide + * des éléments d'éditeur, via py_editor_item_register(), donc son compteur + * de références doit le maintenir en vie. + * + * On peut donc le récupérer directement depuis l'instane GLib, sans passer + * par la procédure de pygobject, qui obligerait à connaître le type précis + * de l'instance GLib manipulée. + */ + target = pychrysalide_get_pygobject(G_OBJECT(item)); + + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, py_view_panel_from_c(view)); + + value = run_python_method(target, "update_for_content", args); + + Py_XDECREF(value); + Py_DECREF(args); + Py_DECREF(target); + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Réagit à un changement du binaire courant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_update_for_binary(PyObject *self, PyObject *args) +{ + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Réagit à un changement d'affichage principal de contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_update_for_view(PyObject *self, PyObject *args) +{ + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Réagit à un changement d'affichage principal de contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_update_for_content(PyObject *self, PyObject *args) +{ + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Fournit le gestionnaire du binaire courant. * +* * +* Retour : Instance en place ou Py_None si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_get_current_binary(PyObject *self, PyObject *args) +{ + PyObject *result; /* Résultat à retourner */ + GEditorItem *item; /* Elément à manipuler */ + GLoadedBinary *binary; /* Instance à convertir */ + + item = G_EDITOR_ITEM(pygobject_get(self)); + binary = g_editor_item_get_current_binary(item); + + if (binary == NULL) + { + Py_INCREF(Py_None); + result = Py_None; + } + else + result = py_loaded_binary_from_c(binary); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Fournit l'affichage de binaire courant. * +* * +* Retour : Instance en place ou Py_None si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_get_current_view(PyObject *self, PyObject *args) +{ + PyObject *result; /* Résultat à retourner */ + GEditorItem *item; /* Elément à manipuler */ + GtkViewPanel *panel; /* Instance à convertir */ + + item = G_EDITOR_ITEM(pygobject_get(self)); + panel = g_editor_item_get_current_view(item); + + if (panel == NULL) + { + Py_INCREF(Py_None); + result = Py_None; + } + else + result = py_view_panel_from_c(panel); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Procède à l'enregistrement d'un élément reactif de l'éditeur.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_editor_item_register(PyObject *self, PyObject *args) +{ + GEditorItem *item; /* Version GLib de l'élément */ + + item = G_EDITOR_ITEM(pygobject_get(self)); + + item->update_binary = _update_editor_item_for_binary_python_wrapper; + item->update_view = _update_editor_item_for_view_python_wrapper; + item->update_content = _update_editor_item_for_view_content_python_wrapper; + + Py_INCREF(self); + register_editor_item(item); + + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.gui.EditorItem'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_editor_item(PyObject *module) +{ + PyObject *parent_mod; /* Module Python-GObject */ + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_editor_item_methods[] = { + { + "update_for_binary", (PyCFunction)py_editor_item_update_for_binary, + METH_VARARGS, + "Called by Chrysalide on each binary change, if the item is registered." + }, + { + "update_for_view", (PyCFunction)py_editor_item_update_for_view, + METH_VARARGS, + "Called by Chrysalide on each view change, if the item is registered." + }, + { + "update_for_content", (PyCFunction)py_editor_item_update_for_content, + METH_VARARGS, + "Called by Chrysalide on each view content change, if the item is registered." + }, + { + "get_current_binary", (PyCFunction)py_editor_item_get_current_binary, + METH_NOARGS, + "Provide the current binary." + }, + { + "get_current_view", (PyCFunction)py_editor_item_get_current_view, + METH_NOARGS, + "Provide the current binary view." + }, + { + "register", (PyCFunction)py_editor_item_register, + METH_NOARGS, + "Register the item as editor item." + }, + { NULL } + }; + + static PyGetSetDef py_editor_item_getseters[] = { + { NULL } + }; + + static PyTypeObject py_editor_item_type = { + + PyObject_HEAD_INIT(NULL) + + .tp_name = "pychrysalide.gui.EditorItem", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide editor item", + + .tp_methods = py_editor_item_methods, + .tp_getset = py_editor_item_getseters + + }; + + parent_mod = PyImport_ImportModule("gobject"); + if (parent_mod == NULL) return false; + + py_editor_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "GObject"); + Py_DECREF(parent_mod); + + if (PyType_Ready(&py_editor_item_type) < 0) + return false; + + Py_INCREF(&py_editor_item_type); + ret = PyModule_AddObject(module, "EditorItem", (PyObject *)&py_editor_item_type); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/gui/editem.h b/plugins/pychrysa/gui/editem.h new file mode 100644 index 0000000..cea5118 --- /dev/null +++ b/plugins/pychrysa/gui/editem.h @@ -0,0 +1,39 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * editem.h - prototypes pour l'équivalent Python du fichier "gui/editem.h" + * + * Copyright (C) 2012 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSA_GUI_EDITEM_H +#define _PLUGINS_PYCHRYSA_GUI_EDITEM_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Prend en charge l'objet 'pychrysalide.gui.EditorItem'. */ +bool register_python_editor_item(PyObject *module); + + + +#endif /* _PLUGINS_PYCHRYSA_GUI_EDITEM_H */ diff --git a/plugins/pychrysa/gui/module.c b/plugins/pychrysa/gui/module.c index bee46df..cf09c44 100644 --- a/plugins/pychrysa/gui/module.c +++ b/plugins/pychrysa/gui/module.c @@ -25,6 +25,7 @@ #include "module.h" +#include "editem.h" #include "panels/module.h" @@ -61,6 +62,7 @@ bool add_gui_module_to_python_module(PyObject *super) if (ret != 0) /* ... */; + result &= register_python_editor_item(module); result &= add_gui_panels_module_to_python_module(module); return true; diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c index b1bcc61..4b982d0 100644 --- a/plugins/pychrysa/gui/panels/panel.c +++ b/plugins/pychrysa/gui/panels/panel.c @@ -40,7 +40,6 @@ static PyObject *py_panel_item_dock(PyObject *, PyObject *); - /****************************************************************************** * * * Paramètres : type = type de l'objet à instancier. * @@ -71,7 +70,7 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject item = g_panel_item_new(get_internal_ref(), name, lname, GTK_WIDGET(pygobject_get(widget)), path); - result = py_panel_item_from_c(G_PANEL_ITEM(item)); + result = _py_panel_item_from_c(G_PANEL_ITEM(item), type); g_object_unref(item); return (PyObject *)result; @@ -79,9 +78,11 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject } + /****************************************************************************** * * * Paramètres : item = instance existante GLib. * +* type = éventuel type final de l'instance Python imposé. * * * * Description : Crée un nouvel objet Python de type 'PanelItem'. * * * @@ -91,14 +92,16 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject * * ******************************************************************************/ -PyObject *py_panel_item_from_c(GPanelItem *item) +PyObject *_py_panel_item_from_c(GPanelItem *item, PyTypeObject *type) { PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - module = PyImport_ImportModule("pychrysalide.gui.panels"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "PanelItem"); - Py_DECREF(module); + if (type == NULL) + { + module = PyImport_ImportModule("pychrysalide.gui.panels"); + type = (PyTypeObject *)PyObject_GetAttrString(module, "PanelItem"); + Py_DECREF(module); + } pychrysalide_set_instance_data(G_OBJECT(item), type); @@ -128,7 +131,7 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) g_panel_item_dock(item); - return Py_None; + Py_RETURN_NONE; } @@ -145,8 +148,6 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) - - /****************************************************************************** * * * Paramètres : module = module dont la définition est à compléter. * @@ -161,14 +162,14 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args) bool register_python_panel_item(PyObject *module) { - PyObject *pygobj_mod; /* Module Python-GObject */ + PyObject *parent_mod; /* Module Python-EditorItem */ int ret; /* Bilan d'un appel */ static PyMethodDef py_panel_item_methods[] = { { "dock", (PyCFunction)py_panel_item_dock, METH_NOARGS, - "DIsplay the panel item in the right place." + "Display the panel item in the right place." }, { NULL } }; @@ -195,11 +196,11 @@ bool register_python_panel_item(PyObject *module) }; - pygobj_mod = PyImport_ImportModule("gobject"); - if (pygobj_mod == NULL) return false; + parent_mod = PyImport_ImportModule("pychrysalide.gui"); + if (parent_mod == NULL) return false; - py_panel_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); - Py_DECREF(pygobj_mod); + py_panel_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "EditorItem"); + Py_DECREF(parent_mod); if (PyType_Ready(&py_panel_item_type) < 0) return false; diff --git a/plugins/pychrysa/gui/panels/panel.h b/plugins/pychrysa/gui/panels/panel.h index 8d06094..a7b6e0c 100644 --- a/plugins/pychrysa/gui/panels/panel.h +++ b/plugins/pychrysa/gui/panels/panel.h @@ -34,7 +34,9 @@ /* Crée un nouvel objet Python de type 'PanelItem'. */ -PyObject *py_panel_item_from_c(GPanelItem *); +PyObject *_py_panel_item_from_c(GPanelItem *, PyTypeObject *); + +#define py_panel_item_from_c(item) _py_panel_item_from_c(item, NULL) /* Prend en charge l'objet 'pychrysalide.gui.panels.PanelItem'. */ bool register_python_panel_item(PyObject *module); |