summaryrefslogtreecommitdiff
path: root/src/gtkext/gtkgraphview.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/gtkgraphview.c')
-rw-r--r--src/gtkext/gtkgraphview.c183
1 files changed, 181 insertions, 2 deletions
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 80ca06b..8389148 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -25,6 +25,7 @@
#include "gtkbinview-int.h"
+#include "../graph/layout.h"
#include <malloc.h>
@@ -36,6 +37,9 @@ struct _GtkGraphView
{
GtkBinView parent; /* A laisser en premier */
+ vmpa_t start; /* Début de la portion vue */
+ vmpa_t end; /* Fin de la portion affichée */
+
GtkBinView **childs; /* Liste des sous-blocs */
size_t childs_count; /* Taille de cette liste */
@@ -55,12 +59,20 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *);
/* Initialise une instance d'afficheur de code en graphique. */
static void gtk_graph_view_init(GtkGraphView *);
+/* Supprime tout contenu de l'afficheur de code en graphique. */
+static void gtk_graph_view_reset(GtkGraphView *);
+
/* Définit les lignes du graphique de représentation. */
static void gtk_graph_view_set_rendering_lines(GtkGraphView *, GRenderingLine *, GRenderingLine *);
+/* Réagit à la sélection externe d'une adresse. */
+static void gtk_graph_view_define_main_address(GtkGraphView *, vmpa_t);
+
/* Indique la position d'affichage d'une adresse donnée. */
static bool gtk_graph_view_get_address_coordinates(GtkGraphView *, vmpa_t, gint *, gint *);
+/* Définit la liste complète des éléments du futur graphique. */
+static GtkBinView **gtk_graph_view_load_nodes(openida_binary *, GRenderingLine *, GRenderingLine *, size_t *);
/* Détermine le type du composant d'affichage en graphique. */
@@ -104,6 +116,7 @@ static void gtk_graph_view_init(GtkGraphView *view)
binview = GTK_BIN_VIEW(view);
binview->set_lines = (set_rendering_lines_fc)gtk_graph_view_set_rendering_lines;
+ binview->define_address = (define_main_address_fc)gtk_graph_view_define_main_address;
binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
}
@@ -128,6 +141,36 @@ GtkWidget* gtk_graph_view_new(void)
}
+/******************************************************************************
+* *
+* Paramètres : view = instance GTK à réinitialiser. *
+* *
+* Description : Supprime tout contenu de l'afficheur de code en graphique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_view_reset(GtkGraphView *view)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < view->childs_count; i++)
+ gtk_widget_destroy(view->childs[i]);
+
+ if (view->childs_count > 0)
+ {
+ free(view->childs);
+ view->childs = NULL;
+
+ view->childs_count = 0;
+
+ }
+
+}
+
@@ -161,7 +204,7 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->childs[0]), 50, 50);
- gtk_bin_view_set_rendering_lines(view->childs[0], lines, lines);
+ gtk_bin_view_set_rendering_lines(view->childs[0], GTK_BIN_VIEW(view)->binary, lines, lines);
@@ -176,7 +219,7 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->childs[1]), 100, 450);
- gtk_bin_view_set_rendering_lines(view->childs[1], mainl, mainl);
+ gtk_bin_view_set_rendering_lines(view->childs[1], GTK_BIN_VIEW(view)->binary, mainl, mainl);
@@ -191,6 +234,65 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
/******************************************************************************
* *
+* Paramètres : view = composant GTK à mettre à jour. *
+* addr = adresse sélectionnée de manière externe. *
+* *
+* Description : Réagit à la sélection externe d'une adresse. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr)
+{
+ exe_format *format; /* Type de fichier chargé */
+ GBinRoutine **routines; /* Liste des routines trouvées */
+ size_t routines_count; /* Nombre de ces routines */
+ size_t i; /* Boucle de parcours */
+ vmpa_t start; /* Début d'une routine */
+ vmpa_t end; /* Fin d'une routine */
+ GRenderingLine *first; /* Première ligne à traiter */
+ GRenderingLine *last; /* Dernière ligne à traiter */
+
+ if (!(view->start <= addr && addr < view->end))
+ {
+ gtk_graph_view_reset(view);
+
+ format = get_openida_binary_format(GTK_BIN_VIEW(view)->binary);
+ routines = get_all_exe_routines(format, &routines_count);
+
+ for (i = 0; i < routines_count; i++)
+ {
+ start = g_binary_routine_get_address(routines[i]);
+ end = start + g_binary_routine_get_size(routines[i]);
+
+ if (start <= addr && addr < end)
+ {
+ view->start = start;
+ view->end = end;
+
+ first = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, start);
+ last = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, end);
+
+ view->childs = gtk_graph_view_load_nodes(GTK_BIN_VIEW(view)->binary, first, last, &view->childs_count);
+
+ build_graph_view(GTK_FIXED(view), view->childs, view->childs_count);
+
+ break;
+
+ }
+
+ }
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = composant GTK à consulter. *
* addr = adresse à présenter à l'écran. *
* x = position horizontale au sein du composant. [OUT] *
@@ -225,3 +327,80 @@ static bool gtk_graph_view_get_address_coordinates(GtkGraphView *view, vmpa_t ad
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = contenu binaire à l'origine des lignes. *
+* first = première ligne à analyser. *
+* last = dernière ligne à analyser. *
+* count = nombre d'éléments créés. [OUT] *
+* *
+* Description : Définit la liste complète des éléments du futur graphique. *
+* *
+* Retour : Liste d'éléments du graphique à placer. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkBinView **gtk_graph_view_load_nodes(openida_binary *binary, GRenderingLine *first, GRenderingLine *last, size_t *count)
+{
+ GtkBinView **result; /* Liste à retourner */
+ GRenderingLine *begin; /* Début d'un groupe de lignes */
+ GRenderingLine *end; /* Fin d'un groupe de lignes */
+ GRenderingLine *iter; /* Boucle de parcours */
+
+ result = NULL;
+ *count = 0;
+
+ begin = NULL;
+
+ for (iter = first; iter != NULL; iter = g_rendering_line_get_next_iter(first, iter, last))
+ {
+ if (begin != NULL && g_rendering_line_has_sources(iter))
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ begin = NULL;
+
+ }
+
+ if (begin == NULL) begin = iter;
+ end = iter;
+
+ if (g_rendering_line_has_destination(iter))
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ begin = NULL;
+
+ }
+
+ }
+
+ if (begin != NULL)
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ }
+
+ return result;
+
+
+}