From a4b70be160203f0c0c50e9ba4d8ab07db08bdeb6 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 24 Jun 2012 15:04:46 +0000
Subject: Updated code to prepare the return of graph views.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@245 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                  |  21 ++++
 src/glibext/gcodebuffer.c  | 140 +++++++++++++++++++++--
 src/glibext/gcodebuffer.h  |   9 ++
 src/graph/dot.c            |   9 +-
 src/graph/layout.c         |  78 +++++++------
 src/graph/layout.h         |   6 +-
 src/graph/node.c           |  20 ++--
 src/graph/node.h           |   7 +-
 src/gtkext/gtkblockview.c  |   4 +-
 src/gtkext/gtkbufferview.c |  25 ++++-
 src/gtkext/gtkbufferview.h |   5 +-
 src/gtkext/gtkgraphview.c  | 268 ++++++++++++++++++++++++++++++++++++---------
 src/gtkext/gtkviewpanel.c  |  43 ++++++++
 src/gtkext/gtkviewpanel.h  |   6 +
 14 files changed, 514 insertions(+), 127 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ea088a4..07eb283 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+12-06-24  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/glibext/gcodebuffer.c:
+	* src/glibext/gcodebuffer.h:
+	Restrict views to address ranges.
+
+	* src/graph/dot.c:
+	* src/graph/layout.c:
+	* src/graph/layout.h:
+	* src/graph/node.c:
+	* src/graph/node.h:
+	Update graph code to match current code widgets.
+
+	* src/gtkext/gtkblockview.c:
+	* src/gtkext/gtkbufferview.c:
+	* src/gtkext/gtkbufferview.h:
+	* src/gtkext/gtkgraphview.c:
+	* src/gtkext/gtkviewpanel.c:
+	* src/gtkext/gtkviewpanel.h:
+	Update code to prepare the return of graph views.
+
 12-04-02  Cyrille Bagard <nocbos@gmail.com>
 
 	* po/fr.po:
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index 3dfb10e..de92b71 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -118,6 +118,9 @@ static void g_code_buffer_class_init(GCodeBufferClass *);
 /* Procède à l'initialisation d'un tampon pour code désassemblé. */
 static void g_code_buffer_init(GCodeBuffer *);
 
+/* Convertit une adresse en indice de ligne. */
+static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t);
+
 
 
 /* ---------------------- VUE PARTICULIERE D'UN TAMPON DE CODE ---------------------- */
@@ -129,8 +132,8 @@ struct _GBufferView
     GObject parent;                         /* A laisser en premier        */
 
     GCodeBuffer *buffer;                    /* Tampon de code visualisé    */
-    size_t first;                           /* Première ligne intégrée     */
-    size_t last;                            /* Dernière ligne intégrée     */
+    vmpa_t start;                           /* Première ligne intégrée     */
+    vmpa_t end;                             /* Dernière ligne intégrée     */
 
     gint line_height;                       /* Hauteur maximale des lignes */
     gint max_widths[BLC_COUNT];             /* Taille cachée des colonnes  */
@@ -273,8 +276,10 @@ static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar)
     guint id;                               /* Identifiant de statut       */
     size_t i;                               /* Boucle de parcours          */
 
-    first = 0;
-    last = (scan->buffer->used > 0 ? scan->buffer->used - 1 : 0);
+    /* TODO : lock scan->buffer->lines */
+
+    first = g_code_buffer_get_index_from_address(scan->buffer, scan->start);
+    last = g_code_buffer_get_index_from_address(scan->buffer, scan->end);
 
     lines = scan->buffer->lines;
 
@@ -290,6 +295,8 @@ static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar)
 
     }
 
+    /* TODO : unlock scan->buffer->lines */
+
     gtk_extended_status_bar_remove(statusbar, id);
 
     /* Avertit le commanditaire... */
@@ -366,6 +373,32 @@ GCodeBuffer *g_code_buffer_new(void)
 
 }
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : buffer = composant GTK à mettre à jour.                      *
+*                addr   = adresse où va se situer la ligne.                   *
+*                                                                             *
+*  Description : Convertit une adresse en indice de ligne.                    *
+*                                                                             *
+*  Retour      : Indice de l'adresse trouvée, ou buffer->used en cas d'échec, *
+*                pour assurer la prise en compte de VMPA_MAX.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t addr)
+{
+    size_t result;                          /* Indice à retourner          */
+
+    for (result = 0; result < buffer->used; result++)
+        if (g_buffer_line_get_address(buffer->lines[result]) == addr)
+            break;
+
+    return result;
+
+}
+
 
 /******************************************************************************
 *                                                                             *
@@ -477,7 +510,7 @@ static void g_buffer_view_init(GBufferView *buffer)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : buffer = tamon à représenter à l'écran.                      *
+*  Paramètres  : buffer = tampon à représenter à l'écran.                     *
 *                                                                             *
 *  Description : Crée une nouvelle vue d'un tampon pour code désassemblé.     *
 *                                                                             *
@@ -493,9 +526,11 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer)
 
     result = g_object_new(G_TYPE_BUFFER_VIEW, NULL);
 
+    g_object_ref(G_OBJECT(buffer));
+
     result->buffer = buffer;
-    result->first = 0;
-    result->last = buffer->used;
+    result->start = 0;
+    result->end = VMPA_MAX;
 
     g_buffer_view_reset_required_widths(result);
 
@@ -506,6 +541,69 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : view  = visualisateur à mettre à jour.                       *
+*                first = première ligne à imprimer.                           *
+*                last  = première ligne hors cadre.                           *
+*                                                                             *
+*  Description : Restreint le champ d'application de l'affichage.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_view_restrict(GBufferView *view, vmpa_t start, vmpa_t end)
+{
+    view->start = start;
+    view->end = end;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view  = visualisateur à mettre à jour.                       *
+*                first = première ligne à imprimer ou NULL. [OUT]             *
+*                last  = première ligne hors cadre ou NULL. [OUT]             *
+*                                                                             *
+*  Description : Indique le champ d'application de l'affichage.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_view_get_restrictions(GBufferView *view, vmpa_t *start, vmpa_t *end)
+{
+    if (start != NULL) *start = view->start;
+    if (end != NULL) *end = view->end;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view = visualisateur à consulter.                            *
+*                                                                             *
+*  Description : Fournit le tampon de code lié à un visualisateur donné.      *
+*                                                                             *
+*  Retour      : Tampon de code associé au gestionnaire d'affichage.          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *view)
+{
+    return view->buffer;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : view = visualisation à consulter.                            *
 *                                                                             *
 *  Description : Réinitialise le cache des largeurs de colonne calculées.     *
@@ -541,18 +639,25 @@ static void g_buffer_view_reset_required_widths(GBufferView *view)
 static void g_buffer_view_compute_required_widths(GBufferView *view)
 {
     GBufferLine **lines;                    /* Liste des lignes à traiter  */
+    size_t first;                           /* Première ligne intégrée     */
+    size_t last;                            /* Dernière ligne intégrée     */
     size_t i;                               /* Boucle de parcours #1       */
     unsigned int j;                         /* Boucle de parcours #2       */
     gint width;                             /* Largeur d'une colonne       */
 
     lines = view->buffer->lines;
 
+    first = g_code_buffer_get_index_from_address(view->buffer, view->start);
+    last = g_code_buffer_get_index_from_address(view->buffer, view->end);
+
+    last = MIN(last, view->buffer->used > 0 ? view->buffer->used - 1 : 0);
+
     view->line_height = 17;
 
     view->left_margin = 2 * view->line_height;
     view->left_text = 2.5 * view->line_height;
 
-    for (i = view->first; i < view->last; i++)
+    for (i = first; i <= last; i++)
         for (j = 0; j < BLC_COUNT; j++)
         {
             width = g_buffer_line_get_width(lines[i], j);
@@ -603,6 +708,8 @@ gint g_buffer_view_get_line_height(GBufferView *view)
 void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool addr, bool code)
 {
     unsigned int i;                         /* Boucle de parcours          */
+    size_t first;                           /* Première ligne intégrée     */
+    size_t last;                            /* Dernière ligne intégrée     */
 
     *width = 0;
     *height = view->line_height;
@@ -619,7 +726,10 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
 
     }
 
-    *height *= (view->last - view->first);
+    first = g_code_buffer_get_index_from_address(view->buffer, view->start);
+    last = g_code_buffer_get_index_from_address(view->buffer, view->end);
+
+    *height *= (last - first);
 
 }
 
@@ -760,15 +870,21 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y)
 bool g_buffer_view_get_address_coordinates(GBufferView *view, vmpa_t addr, gint *x, gint *y)
 {
     gint lheight;                           /* Hauteur d'une ligne         */
-    size_t i;                               /* Boucle de parcours          */
     vmpa_t current;                         /* Adresse parcourue           */
+    size_t first;                           /* Première ligne intégrée     */
+    size_t last;                            /* Dernière ligne intégrée     */
+    size_t i;                               /* Boucle de parcours          */
 
     *x = 0;
     *y = 0;
 
     lheight = g_buffer_view_get_line_height(view);
+    current = VMPA_MAX;
+
+    first = g_code_buffer_get_index_from_address(view->buffer, view->start);
+    last = g_code_buffer_get_index_from_address(view->buffer, view->end);
 
-    for (i = 0; i < view->buffer->used; i++)
+    for (i = first; i < last; i++)
     {
         current = g_buffer_line_get_address(view->buffer->lines[i]);
 
@@ -782,6 +898,6 @@ bool g_buffer_view_get_address_coordinates(GBufferView *view, vmpa_t addr, gint
 
     }
 
-    return true;
+    return (current == addr);
 
 }
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
index 74e376c..3fc6155 100644
--- a/src/glibext/gcodebuffer.h
+++ b/src/glibext/gcodebuffer.h
@@ -94,6 +94,15 @@ GType g_buffer_view_get_type(void);
 /* Crée une nouvelle vue d'un tampon pour code désassemblé. */
 GBufferView *g_buffer_view_new(GCodeBuffer *);
 
+/* Restreint le champ d'application de l'affichage. */
+void g_buffer_view_restrict(GBufferView *, vmpa_t, vmpa_t);
+
+/* Indique le champ d'application de l'affichage. */
+void g_buffer_view_get_restrictions(GBufferView *, vmpa_t *, vmpa_t *);
+
+/* Fournit le tampon de code lié à un visualisateur donné. */
+GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *);
+
 /* Fournit la hauteur d'impression d'une ligne visualisée. */
 gint g_buffer_view_get_line_height(GBufferView *);
 
diff --git a/src/graph/dot.c b/src/graph/dot.c
index 27e60bc..5a80f59 100644
--- a/src/graph/dot.c
+++ b/src/graph/dot.c
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * dot.c - interactions avec le système dot
  *
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -148,15 +148,12 @@ void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view,
 {
     int height;                             /* Hauteur du graphique        */
     node_t *iter;                           /* Boucle de parcours          */
-    GGraphNode *node;                       /* Intermédiaire concerné      */
+    const GGraphNode *node;                 /* Intermédiaire concerné      */
 
     height = GD_bb(layout->graph).UR.y;
 
     for (iter = agfstnode(layout->graph); iter != NULL; iter = agnxtnode(layout->graph, iter))
     {
-
-        printf(" pos :: (%d ; %d)\n", iter->u.coord.x, height - iter->u.coord.y);
-
         node = find_graph_node_by_name(nodes, count, iter->name);
         g_graph_node_place(node, view, iter->u.coord.x, height - iter->u.coord.y);
     }
@@ -227,7 +224,7 @@ GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, siz
             }
 
             result = (GtkLinkRenderer **)realloc(result, ++(*count) * sizeof(GtkLinkRenderer *));
-            result[*count - 1] = gtk_link_renderer_new(points, points_count);
+            result[*count - 1] = GTK_LINK_RENDERER(gtk_link_renderer_new(points, points_count));
 
         }
 
diff --git a/src/graph/layout.c b/src/graph/layout.c
index 667074b..21f7454 100644
--- a/src/graph/layout.c
+++ b/src/graph/layout.c
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * layout.c - mise en place de graphique
  *
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -31,7 +31,9 @@
 
 #include "dot.h"
 #include "node.h"
+#include "../analysis/binary.h"
 #include "../common/extstr.h"
+#include "../gtkext/gtkbufferview.h"
 
 
 
@@ -40,7 +42,7 @@
 
 
 /* Etablit tous les liens entre les différents morceaux de code. */
-static char *complete_graph_links(const GtkGraphView *, GtkBinView **, size_t, char *);
+static char *complete_graph_links(const GtkGraphView *, GtkViewPanel **, size_t, char *);
 
 
 
@@ -58,7 +60,7 @@ static char *complete_graph_links(const GtkGraphView *, GtkBinView **, size_t, c
 *                                                                             *
 ******************************************************************************/
 
-bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
+bool build_graph_view(GtkGraphView *view, GtkViewPanel **views, size_t count)
 {
     GGraphNode **nodes;                     /* Intermédiaires en place     */
     size_t i;                               /* Boucle de parcours          */
@@ -72,12 +74,11 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
     nodes = (GGraphNode **)calloc(count, sizeof(GGraphNode *));
 
     for (i = 0; i < count; i++)
-        nodes[i] = g_graph_node_new(views[i]);
+        nodes[i] = g_graph_node_new(GTK_WIDGET(views[i]));
  
     /* Définition du graphique */
 
     cmds = strdup("digraph G {\noverlap=false;\n  splines=true;\n");
-    //cmds = strdup("digraph G {\n");
 
     for (i = 0; i < count; i++)
         cmds = g_graph_node_register_for_dot(nodes[i], cmds);
@@ -86,8 +87,6 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
 
     cmds = stradd(cmds, "}");
 
-    printf("first step :: '%s'\n", cmds);
-
     layout = create_graph_layout(cmds);
 
     /* Affichage du graphique */
@@ -113,7 +112,7 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
 *  Paramètres  : view  = support contenant les différentes lignes.            *
 *                views = morceaux de code à afficher de façon organisée.      *
 *                count = quantité de ces morceaux de code.                    *
-*                desc  = description du graphique à compléter.                *
+*                desc  = description du graphique à compléter. [OUT]          *
 *                                                                             *
 *  Description : Etablit tous les liens entre les différents morceaux de code.*
 *                                                                             *
@@ -123,51 +122,65 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
 *                                                                             *
 ******************************************************************************/
 
-static char *complete_graph_links(const GtkGraphView *view, GtkBinView **views, size_t count, char *desc)
+static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views, size_t count, char *desc)
 {
+    GOpenidaBinary *binary;                 /* Binaire rattaché aux vues   */
+    GArchInstruction *instrs;               /* Instructions pour assembleur*/
+    GBufferView *buffer;                    /* Tampon d'une partie de code */
+    vmpa_t end;                             /* Adresse finale du tampon    */
     size_t i;                               /* Boucle de parcours #1       */
-    GRenderingLine *last;                   /* Dernière ligne d'un bloc    */
-    GRenderingLine **dests;                 /* Ligne visée par une autre   */
+    GArchInstruction *last;                 /* Dernière instruc. d'un bloc */
+    vmpa_t addr;                            /* Addresse d'instruction      */
+    GArchInstruction **dests;               /* Instr. visée par une autre  */
     InstructionLinkType *types;             /* Type de lien entre lignes   */
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t j;                               /* Boucle de parcours #2       */
-    vmpa_t addr;                            /* Addresse de destination     */
     size_t k;                               /* Boucle de parcours #3       */
-    char buffer[LINKS_DESC_LEN];            /* Tampon pour l'ajout de liens*/
-    GRenderingLine *next;                   /* Ligne suivante dans le flux */
+    char cmd[LINKS_DESC_LEN];               /* Tampon pour l'ajout de liens*/
+    GArchInstruction *next;                 /* Instruction suivante        */
+
+    if (count == 0)
+        return desc;
+
+    binary = gtk_view_panel_get_binary(views[0]);
+    instrs = g_openida_binary_get_instructions(binary);
 
     for (i = 0; i < count; i++)
     {
-        last = gtk_bin_view_get_last_line(views[i]);
+        buffer = gtk_buffer_view_get_buffer(GTK_BUFFER_VIEW(views[i]));
+        g_buffer_view_get_restrictions(buffer, NULL, &end);
 
-        if (g_rendering_line_has_destinations(last))
+        last = g_arch_instruction_find_by_address(instrs, end, true);
+        g_arch_instruction_get_location(last, NULL, NULL, &addr);
+
+        if (g_arch_instruction_has_destinations(last))
         {
-            dcount = g_rendering_line_get_destinations(last, &dests, &types);
+            dcount = g_arch_instruction_get_destinations(last, &dests, &types);
 
             for (j = 0; j < dcount; j++)
             {
-                addr = get_rendering_line_address(dests[j]);
+                g_arch_instruction_get_location(dests[j], NULL, NULL, &addr);
 
                 for (k = 0; k < count; k++)
-                    if (gtk_bin_view_contain_address(views[k], addr))
+                    if (gtk_view_panel_contain_address(views[k], addr))
                         break;
 
                 if (k < count)
                     switch (types[j])
                     {
                         case ILT_JUMP:
-                            snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
-                            desc = stradd(desc, buffer);
+                            snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+                            desc = stradd(desc, cmd);
                             break;
 
                         case ILT_JUMP_IF_TRUE:
-                            snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
-                            desc = stradd(desc, buffer);
+                            snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+                            desc = stradd(desc, cmd);
                             break;
 
                         case ILT_JUMP_IF_FALSE:
-                            snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
-                            desc = stradd(desc, buffer);
+                            snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+                            desc = stradd(desc, cmd);
                             break;
 
                         default:
@@ -180,24 +193,21 @@ static char *complete_graph_links(const GtkGraphView *view, GtkBinView **views,
         }
 
         /* Si la ligne n'est pas la dernière, on suit le flux normal */
-        else if (last != gtk_bin_view_get_last_line(view))
+        else if (addr != end)
         {
-            next = g_rendering_line_get_next_iter(gtk_bin_view_get_lines(GTK_BIN_VIEW(view)),
-                                                  last,
-                                                  gtk_bin_view_get_last_line(GTK_BIN_VIEW(view)));
-
+            next = g_arch_instruction_get_next_iter(instrs, last, end);
             if (next == NULL) continue;
 
-            addr = get_rendering_line_address(next);
+            g_arch_instruction_get_location(next, NULL, NULL, &addr);
 
             for (k = 0; k < count; k++)
-                if (gtk_bin_view_contain_address(views[k], addr))
+                if (gtk_view_panel_contain_address(views[k], addr))
                     break;
 
             if (k < count)
             {
-                snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
-                desc = stradd(desc, buffer);
+                snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+                desc = stradd(desc, cmd);
             }
 
         }
diff --git a/src/graph/layout.h b/src/graph/layout.h
index 5212168..006fa9b 100644
--- a/src/graph/layout.h
+++ b/src/graph/layout.h
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * layout.h - prototypes pour la mise en place de graphique
  *
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -28,13 +28,13 @@
 #include <stdbool.h>
 
 
-#include "../gtkext/gtkbinview.h"
 #include "../gtkext/gtkgraphview.h"
+#include "../gtkext/gtkviewpanel.h"
 
 
 
 /* Dispose une série de morceaux d'affichage en graphique. */
-bool build_graph_view(GtkGraphView *, GtkBinView **, size_t);
+bool build_graph_view(GtkGraphView *, GtkViewPanel **, size_t);
 
 
 
diff --git a/src/graph/node.c b/src/graph/node.c
index 09cfe30..3e6cc14 100644
--- a/src/graph/node.c
+++ b/src/graph/node.c
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * node.c - éléments de graphiques chez dot
  *
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -24,7 +24,9 @@
 #include "node.h"
 
 
+#include <malloc.h>
 #include <stdio.h>
+#include <string.h>
 
 
 #include "../common/extstr.h"
@@ -39,7 +41,7 @@ struct _GGraphNode
 {
     GObject parent;                         /* A laisser en premier        */
 
-    GtkBinView *view;                       /* Morceau de code représenté  */
+    GtkWidget *view;                        /* Morceau de code représenté  */
     char *name;                             /* Adresse sous forme humaine  */
 
 };
@@ -159,7 +161,7 @@ static void g_graph_node_init(GGraphNode *node)
 *                                                                             *
 ******************************************************************************/
 
-GGraphNode *g_graph_node_new(GtkBinView *view)
+GGraphNode *g_graph_node_new(GtkWidget *view)
 {
     GGraphNode *result;                     /* Structure à retourner       */
     size_t len;                             /* Taille du nom               */
@@ -168,7 +170,7 @@ GGraphNode *g_graph_node_new(GtkBinView *view)
 
     result->view = view;
 
-    len = 3 + sizeof(GtkBinView *) * 2 + 1;
+    len = 3 + sizeof(GtkWidget *) * 2 + 1;
 
     result->name = (char *)calloc(len, sizeof(char));
     snprintf(result->name, len, "_%p", result->view);
@@ -196,7 +198,7 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds)
     GtkRequisition requisition;             /* Taille à l'écran requise    */
     char buffer[128];
 
-    gtk_widget_size_request(GTK_WIDGET(node->view), &requisition);
+    gtk_widget_size_request(node->view, &requisition);
 
     cmds = stradd(cmds, node->name);
     cmds = stradd(cmds, " [shape=box, fixedsize ");
@@ -240,12 +242,12 @@ void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint
 {
     GtkRequisition requisition;             /* Taille à l'écran actuelle   */
 
-    gtk_widget_size_request(GTK_WIDGET(node->view), &requisition);
+    gtk_widget_size_request(node->view, &requisition);
 
     x -= requisition.width / 2;
     y -= requisition.height / 2;
 
-    gtk_graph_view_put(view, GTK_WIDGET(node->view), x, y);
+    gtk_graph_view_put(view, node->view, x, y);
 
 }
 
@@ -270,9 +272,9 @@ void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint
 *                                                                             *
 ******************************************************************************/
 
-GGraphNode *find_graph_node_by_name(const GGraphNode **nodes, size_t count, const char *target)
+const GGraphNode *find_graph_node_by_name(GGraphNode **nodes, size_t count, const char *target)
 {
-    GGraphNode *result;                     /* Trouvaille à remonter       */
+    const GGraphNode *result;               /* Trouvaille à remonter       */
     size_t i;                               /* Boucle de parcours          */
 
     result = NULL;
diff --git a/src/graph/node.h b/src/graph/node.h
index 4998553..f8d0078 100644
--- a/src/graph/node.h
+++ b/src/graph/node.h
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * node.h - prototypes pour les éléments de graphiques chez dot
  *
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -25,7 +25,6 @@
 #define _GRAPH_NODE_H
 
 
-#include "../gtkext/gtkbinview.h"
 #include "../gtkext/gtkgraphview.h"
 
 
@@ -51,7 +50,7 @@ typedef struct _GGraphNodeClass GGraphNodeClass;
 GType g_graph_node_get_type(void);
 
 /* Constitue un intermédiaire entre un noeud dot et du code. */
-GGraphNode *g_graph_node_new(GtkBinView *);
+GGraphNode *g_graph_node_new(GtkWidget *);
 
 /* Déclare l'intermédiaire en tant que noeud pour dot. */
 char *g_graph_node_register_for_dot(const GGraphNode *, char *);
@@ -65,7 +64,7 @@ void g_graph_node_place(const GGraphNode *, GtkGraphView *, gint , gint);
 
 
 /* Recherche un noeud donné dans une série de noeuds. */
-GGraphNode *find_graph_node_by_name(const GGraphNode **, size_t, const char *);
+const GGraphNode *find_graph_node_by_name(GGraphNode **, size_t, const char *);
 
 
 
diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c
index a420194..cd2d99d 100644
--- a/src/gtkext/gtkblockview.c
+++ b/src/gtkext/gtkblockview.c
@@ -123,7 +123,7 @@ GtkWidget *gtk_block_view_new(void)
 {
     GtkBlockView *result;                   /* Composant à retourner       */
 
-    result = gtk_type_new(GTK_TYPE_BLOCK_VIEW);
+    result = g_object_new(GTK_TYPE_BLOCK_VIEW, NULL);
 
     return GTK_WIDGET(result);
 
@@ -151,6 +151,6 @@ static void gtk_block_view_attach_binary(GtkBlockView *view, GOpenidaBinary *bin
 
     buffer = g_openida_binary_get_disassembled_buffer(binary);
 
-    gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), buffer, addr, code);
+    gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), g_buffer_view_new(buffer), addr, code);
 
 }
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index c3457e9..99b67ab 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -397,7 +397,7 @@ static void gtk_buffer_view_scroll(GtkBufferView *view)
 *                                                                             *
 ******************************************************************************/
 
-void gtk_buffer_view_attach_buffer(GtkBufferView *view, GCodeBuffer *buffer, bool *addr, bool *code)
+void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer, bool *addr, bool *code)
 {
     gint width;                             /* Largeur de l'objet actuelle */
     gint height;                            /* Hauteur de l'objet actuelle */
@@ -408,10 +408,10 @@ void gtk_buffer_view_attach_buffer(GtkBufferView *view, GCodeBuffer *buffer, boo
         g_object_unref(G_OBJECT(view->buffer_view));
     }
 
-    view->buffer = buffer;
+    view->buffer = g_buffer_view_get_buffer(buffer);
     g_object_ref(G_OBJECT(view->buffer));
 
-    view->buffer_view = g_buffer_view_new(view->buffer);
+    view->buffer_view = buffer;
 
     //gdk_threads_enter();
 
@@ -436,3 +436,22 @@ void gtk_buffer_view_attach_buffer(GtkBufferView *view, GCodeBuffer *buffer, boo
     //gdk_threads_leave();
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view   = composant GTK à consulter.                          *
+*                                                                             *
+*  Description : Fournit la vue associée au tampon de lignes courant.         *
+*                                                                             *
+*  Retour      : Vue mise en place.                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view)
+{
+    return view->buffer_view;
+
+}
diff --git a/src/gtkext/gtkbufferview.h b/src/gtkext/gtkbufferview.h
index da04533..df34b72 100644
--- a/src/gtkext/gtkbufferview.h
+++ b/src/gtkext/gtkbufferview.h
@@ -52,7 +52,10 @@ typedef struct _GtkBufferViewClass GtkBufferViewClass;
 GType gtk_buffer_view_get_type(void);
 
 /* Prend acte de l'association d'un tampon de lignes. */
-void gtk_buffer_view_attach_buffer(GtkBufferView *, GCodeBuffer *, bool *, bool *);
+void gtk_buffer_view_attach_buffer(GtkBufferView *, GBufferView *, bool *, bool *);
+
+/* Fournit la vue associée au tampon de lignes courant. */
+GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *);
 
 
 
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index ff020d4..263ab7d 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -25,6 +25,7 @@
 
 
 #include "gtkblockview.h"
+#include "gtkbufferview.h"
 #include "gtkviewpanel-int.h"
 
 
@@ -37,6 +38,9 @@ struct _GtkGraphView
 
     GtkRequisition requisition;             /* Espace requis d'affichage   */   /* A garder ?? */
 
+    vmpa_t start;                           /* Début de la portion vue     */
+    vmpa_t end;                             /* Fin de la portion affichée  */
+
     GtkBlockView **childs;                  /* Liste des sous-blocs        */
     size_t childs_count;                    /* Taille de cette liste       */
 
@@ -69,9 +73,15 @@ static void gtk_graph_view_size_allocate(GtkWidget *, GtkAllocation *);
 /*  Met à jour l'affichage de la vue sous forme graphique. */
 static gboolean gtk_graph_view_expose(GtkWidget *, GdkEventExpose *, GtkGraphView *);
 
+/* Indique la position d'affichage d'une adresse donnée. */
+static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, vmpa_t, gint *, gint *);
+
 /* Réagit à un défilement quelconque. */
 static void gtk_graph_view_scroll(GtkGraphView *);
 
+/* Supprime tout contenu de l'afficheur de code en graphique. */
+static void gtk_graph_view_reset(GtkGraphView *);
+
 
 
 /* Détermine le type du composant d'affichage en graphique. */
@@ -122,6 +132,7 @@ static void gtk_graph_view_init(GtkGraphView *view)
 
     viewpanel = GTK_VIEW_PANEL(view);
 
+    viewpanel->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
     viewpanel->scroll = (scroll_fc)gtk_graph_view_scroll;
 
     //binview = GTK_BIN_VIEW(view);
@@ -131,7 +142,7 @@ static void gtk_graph_view_init(GtkGraphView *view)
     //binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
 
     view->support = GTK_FIXED(gtk_fixed_new());
-    gtk_fixed_set_has_window(view->support, TRUE);
+    gtk_widget_set_has_window(GTK_WIDGET(view->support), TRUE);
 
     g_signal_connect(G_OBJECT(view->support), "expose-event",
                      G_CALLBACK(gtk_graph_view_expose), view);
@@ -276,6 +287,31 @@ static gboolean gtk_graph_view_expose(GtkWidget *widget, GdkEventExpose *event,
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : view = composant GTK à consulter.                            *
+*                addr = adresse à présenter à l'écran.                        *
+*                x    = position horizontale au sein du composant. [OUT]      *
+*                y    = position verticale au sein du composant. [OUT]        *
+*                                                                             *
+*  Description : Indique la position d'affichage d'une adresse donnée.        *
+*                                                                             *
+*  Retour      : true si l'adresse fait partie du composant, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, vmpa_t addr, gint *x, gint *y)
+{
+
+
+
+    return false;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : view  = composant GTK à mettre à jour.                       *
 *                                                                             *
 *  Description : Réagit à un défilement quelconque.                           *
@@ -365,6 +401,184 @@ void gtk_graph_view_attach_links(GtkGraphView *view, GtkLinkRenderer **links, si
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  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          */
+
+    view->requisition.width = 0;
+    view->requisition.height = 0;
+
+    view->start = VMPA_MAX;
+    view->end = VMPA_MAX;
+
+    for (i = 0; i < view->links_count; i++)
+        gtk_object_destroy(GTK_OBJECT(view->links[i]));
+
+    if (view->links_count > 0)
+    {
+        free(view->links);
+        view->links = NULL;
+
+        view->links_count = 0;
+
+    }
+
+    for (i = 0; i < view->childs_count; i++)
+        gtk_widget_destroy(GTK_WIDGET(view->childs[i]));
+
+    if (view->childs_count > 0)
+    {
+        free(view->childs);
+        view->childs = NULL;
+
+        view->childs_count = 0;
+
+    }
+
+}
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view   = composant d'affichage GTK à mettre à jour.          *
+*                binary = contenu binaire à l'origine des lignes.             *
+*                start  = première adresse à traiter.                         *
+*                end    = première adresse hors cadre de l'opération.         *
+*                                                                             *
+*  Description : Définit la liste complète des éléments du futur graphique.   *
+*                                                                             *
+*  Retour      : Liste d'éléments du graphique à placer.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GOpenidaBinary *binary, vmpa_t start, vmpa_t end)
+{
+    GtkViewPanel **result;                  /* Liste à retourner           */
+    size_t *count;                          /* Nombre d'éléments créés.    */
+    GArchInstruction *list;                 /* Liste des instructions      */
+    GCodeBuffer *buffer;                    /* Tampon brut à découper      */
+    bool *addr;                             /* Affichage des adresses ?    */
+    bool *code;                             /* Affichage du binaire ?      */
+    vmpa_t first;                           /* Début d'un groupe de lignes */
+    GArchInstruction *iter;                 /* Boucle de parcours          */
+    vmpa_t last;                            /* Fin d'un groupe de lignes   */
+    GBufferView *subview;                   /* Partie affichée du tampon   */
+
+    result = NULL;
+
+    count = &view->childs_count;
+    *count = 0;
+
+    list = g_openida_binary_get_instructions(binary);
+    buffer = g_openida_binary_get_disassembled_buffer(binary);
+
+    addr = g_openida_binary_display_addresses_in_text(binary);
+    code = g_openida_binary_display_code_in_text(binary);
+
+    first = start;
+
+    for (iter = g_arch_instruction_find_by_address(list, start, true);
+         iter != NULL;
+         iter = g_arch_instruction_get_next_iter(list, iter, end))
+    {
+        if (g_arch_instruction_has_sources(iter))
+        {
+            result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
+
+            result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+
+            gtk_view_panel_show_border(result[*count - 1], true);
+
+            subview = g_buffer_view_new(buffer);
+            //g_buffer_view_restrict(subview, size_t first, size_t last);
+            gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
+                                          subview, addr, code);
+
+            first = VMPA_MAX;
+
+        }
+
+        g_arch_instruction_get_location(iter, NULL, NULL, &last);
+        if (first == VMPA_MAX) first = last;
+
+        if (g_arch_instruction_has_destinations(iter))
+        {
+            result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
+
+            result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+
+            gtk_view_panel_show_border(result[*count - 1], true);
+
+            subview = g_buffer_view_new(buffer);
+            //g_buffer_view_restrict(subview, size_t first, size_t last);
+            gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
+                                          subview, addr, code);
+
+            first = VMPA_MAX;
+
+        }
+
+    }
+
+    if (first != VMPA_MAX)
+    {
+        result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
+
+        result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+
+        gtk_view_panel_show_border(result[*count - 1], true);
+
+        subview = g_buffer_view_new(buffer);
+        //g_buffer_view_restrict(subview, size_t first, size_t last);
+        gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
+                                      subview, addr, code);
+
+    }
+
+    return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 
@@ -424,9 +638,6 @@ 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 *);
 
@@ -524,55 +735,6 @@ static void gtk_graph_view_init(GtkGraphView *view)
 
 
 
-/******************************************************************************
-*                                                                             *
-*  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          */
-
-    view->requisition.width = 0;
-    view->requisition.height = 0;
-
-    view->start = 0;
-    view->end = 0;
-
-    for (i = 0; i < view->links_count; i++)
-        gtk_object_destroy(view->links[i]);
-
-    if (view->links_count > 0)
-    {
-        free(view->links);
-        view->links = NULL;
-
-        view->links_count = 0;
-
-    }
-
-    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;
-
-    }
-
-}
-
-
 
 
 
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 35cfa5c..2dac981 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -323,6 +323,26 @@ static gboolean gtk_view_panel_expose(GtkWidget *widget, GdkEventExpose *event)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : panel = composant GTK à mettre à jour.                       *
+*                show  = état de l'affichage auquel parvenir.                 *
+*                                                                             *
+*  Description : Définit si une bordure est à afficher.                       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_view_panel_show_border(GtkViewPanel *panel, bool show)
+{
+    panel->show_border = show;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : panel  = composant GTK à mettre à jour.                      *
 *                binary = binaire associé à intégrer.                         *
 *                addr   = indique si les positions doivent être affichées.    *
@@ -457,6 +477,29 @@ GOpenidaBinary *gtk_view_panel_get_binary(const GtkViewPanel *panel)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : view = composant GTK à manipuler.                            *
+*                addr = adresse à rechercher.                                 *
+*                                                                             *
+*  Description : Indique si la vue contient une addrese donnée.               *
+*                                                                             *
+*  Retour      : true si l'adresse est présente, false sinon.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool gtk_view_panel_contain_address(const GtkViewPanel *panel, vmpa_t addr)
+{
+    gint dummy_x;                           /* Abscisse pour l'appel       */
+    gint dummy_y;                           /* Ordonnée pour l'appel       */
+
+    return panel->get_coordinates(panel, addr, &dummy_x, &dummy_y);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : panel = composant GTK à manipuler.                           *
 *                addr = adresse à présenter à l'écran.                        *
 *                                                                             *
diff --git a/src/gtkext/gtkviewpanel.h b/src/gtkext/gtkviewpanel.h
index ccac08b..12b0e44 100644
--- a/src/gtkext/gtkviewpanel.h
+++ b/src/gtkext/gtkviewpanel.h
@@ -50,6 +50,9 @@ typedef struct _GtkViewPanelClass GtkViewPanelClass;
 /* Détermine le type du composant d'affichage générique. */
 GType gtk_view_panel_get_type(void);
 
+/* Définit si une bordure est à afficher. */
+void gtk_view_panel_show_border(GtkViewPanel *, bool);
+
 /* Associe à un panneau d'affichage un binaire chargé. */
 void gtk_view_panel_attach_binary(GtkViewPanel *, GOpenidaBinary *, bool *, bool *);
 
@@ -68,6 +71,9 @@ void gtk_view_panel_set_code_display(const GtkViewPanel *, bool);
 /* Fournit le binaire associé à la représentation. */
 GOpenidaBinary *gtk_view_panel_get_binary(const GtkViewPanel *);
 
+/* Indique si la vue contient une addrese donnée. */
+bool gtk_view_panel_contain_address(const GtkViewPanel *, vmpa_t);
+
 /* S'assure qu'une adresse donnée est visible à l'écran. */
 void gtk_view_panel_scroll_to_address(const GtkViewPanel *, vmpa_t);
 
-- 
cgit v0.11.2-87-g4458