From f5df6496fa50927d3d274c939a888afde652b7ad Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 2 Nov 2012 15:50:07 +0000
Subject: Improved the computing and the rendering of the graphic view.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@277 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                     |  56 +++++++
 configure.ac                  |   2 +-
 src/Makefile.am               |   3 +-
 src/analysis/binary-int.h     |   2 +-
 src/analysis/binary.c         |  16 +-
 src/analysis/binary.h         |  14 +-
 src/arch/dalvik/instruction.c |  45 +++++-
 src/glibext/gbufferline.c     |   4 -
 src/glibext/gbufferline.h     |   4 +
 src/glibext/gcodebuffer.c     |  11 +-
 src/graph/Makefile.am         |  18 ---
 src/graph/dot.c               | 233 ----------------------------
 src/graph/dot.h               |  51 ------
 src/graph/layout.c            | 219 --------------------------
 src/graph/layout.h            |  41 -----
 src/graph/node.c              | 283 ---------------------------------
 src/graph/node.h              |  71 ---------
 src/gtkext/Makefile.am        |   5 +
 src/gtkext/graph/Makefile.am  |  18 +++
 src/gtkext/graph/dot.c        | 267 ++++++++++++++++++++++++++++++++
 src/gtkext/graph/dot.h        |  51 ++++++
 src/gtkext/graph/layout.c     | 229 +++++++++++++++++++++++++++
 src/gtkext/graph/layout.h     |  41 +++++
 src/gtkext/graph/node.c       | 353 ++++++++++++++++++++++++++++++++++++++++++
 src/gtkext/graph/node.h       |  74 +++++++++
 src/gtkext/gtkgraphview.c     |   8 +-
 src/gtkext/gtklinkrenderer.c  | 100 +++++++++++-
 src/gtkext/gtklinkrenderer.h  |  14 +-
 src/gtkext/gtkviewpanel.c     |   7 +-
 src/project.c                 |   4 +-
 30 files changed, 1293 insertions(+), 951 deletions(-)
 delete mode 100755 src/graph/Makefile.am
 delete mode 100644 src/graph/dot.c
 delete mode 100644 src/graph/dot.h
 delete mode 100644 src/graph/layout.c
 delete mode 100644 src/graph/layout.h
 delete mode 100644 src/graph/node.c
 delete mode 100644 src/graph/node.h
 create mode 100755 src/gtkext/graph/Makefile.am
 create mode 100644 src/gtkext/graph/dot.c
 create mode 100644 src/gtkext/graph/dot.h
 create mode 100644 src/gtkext/graph/layout.c
 create mode 100644 src/gtkext/graph/layout.h
 create mode 100644 src/gtkext/graph/node.c
 create mode 100644 src/gtkext/graph/node.h

diff --git a/ChangeLog b/ChangeLog
index af9d3e2..46b8ce7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,59 @@
+12-11-02  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Move the Makefile of the graph directory.
+
+	* src/analysis/binary.c:
+	* src/analysis/binary.h:
+	* src/analysis/binary-int.h:
+	Define display options for each kind of view.
+
+	* src/arch/dalvik/instruction.c:
+	Provide links from Dalvik instructions.
+
+	* src/glibext/gbufferline.c:
+	* src/glibext/gbufferline.h:
+	Define COL_MARGIN in the header file.
+
+	* src/glibext/gcodebuffer.c:
+	Compute size of buffers more accurately. Fix a bug when looking for
+	a line using an address.
+
+	* src/graph/dot.c:
+	* src/graph/dot.h:
+	* src/graph/layout.c:
+	* src/graph/layout.h:
+	* src/graph/Makefile.am:
+	* src/graph/node.c:
+	* src/graph/node.h:
+	Moved entries.
+
+	* src/gtkext/graph/dot.c:
+	* src/gtkext/graph/dot.h:
+	* src/gtkext/graph/layout.c:
+	* src/gtkext/graph/layout.h:
+	* src/gtkext/graph/Makefile.am:
+	* src/gtkext/graph/node.c:
+	* src/gtkext/graph/node.h:
+	Improve the computing and the rendering of the graphic view.
+
+	* src/gtkext/gtkgraphview.c:
+	* src/gtkext/gtklinkrenderer.c:
+	* src/gtkext/gtklinkrenderer.h:
+	Improve the computing and the rendering of the graphic view.
+
+	* src/gtkext/gtkviewpanel.c:
+	Fix a bug: use the real requested size of a panel.
+
+	* src/gtkext/Makefile.am:
+	Add graph/libgtkextgraph.la to libgtkext_la_LIBADD.
+
+	* src/Makefile.am:
+	Remove all references to the graph directory.
+
+	* src/project.c:
+	Update code.
+
 12-10-28  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/archbase.c:
diff --git a/configure.ac b/configure.ac
index 0a79182..5ccb4af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -288,8 +288,8 @@ AC_CONFIG_FILES([Makefile
                  src/format/mangling/Makefile
                  src/format/pe/Makefile
                  src/glibext/Makefile
-                 src/graph/Makefile
                  src/gtkext/Makefile
+                 src/gtkext/graph/Makefile
                  src/gui/Makefile
                  src/gui/menus/Makefile
                  src/gui/panels/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 2d6fd46..8eff972 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,7 +43,6 @@ libchrysagtkext_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBGRAPH_LIBS)		\
 	-L.libs -lchrysadisass
 
 libchrysagtkext_la_LIBADD =						\
-	graph/libgraph.la							\
 	gtkext/libgtkext.la
 
 
@@ -107,6 +106,6 @@ chrysalide_LDADD = $(LIBINTL) 				\
 
 # gtkext doit être traité en premier, à cause des marshals GLib
 
-SUBDIRS = glibext gtkext analysis arch format common debug decomp dialogs graph gui plugins
+SUBDIRS = glibext gtkext analysis arch format common debug decomp dialogs gui plugins
 
 # TODO: rm -rf panels 
diff --git a/src/analysis/binary-int.h b/src/analysis/binary-int.h
index c9be0bf..f813aa8 100644
--- a/src/analysis/binary-int.h
+++ b/src/analysis/binary-int.h
@@ -63,7 +63,7 @@ struct _GLoadedBinary
     size_t decbuf_count;                    /* Taille des tableaux         */
     size_t defsrc;                          /* Fichier source principal    */
 
-    bool text_display[2];                   /* Position et code binaire #1 */
+    bool text_display[BDT_COUNT][2];        /* Position et code binaire #1 */
     bool lines_display;                     /* Affichage des lignes        */
 
 };
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index d5bf029..b9292aa 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -122,8 +122,10 @@ static void g_loaded_binary_class_init(GLoadedBinaryClass *klass)
 
 static void g_loaded_binary_init(GLoadedBinary *binary)
 {
-    binary->text_display[0] = true;
-    binary->text_display[1] = true;
+    binary->text_display[BDT_ASM][0] = true;
+    binary->text_display[BDT_ASM][1] = true;
+    binary->text_display[BDT_GRAPH][0] = true;
+    binary->text_display[BDT_GRAPH][1] = false;
 
     binary->lines_display = true;
 
@@ -681,6 +683,7 @@ GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : binary = élément binaire à consulter.                        *
+*                type   = type de représentation visée.                       *
 *                                                                             *
 *  Description : Indique si les adresses doivent apparaître dans le rendu.    *
 *                                                                             *
@@ -690,9 +693,9 @@ GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary
 *                                                                             *
 ******************************************************************************/
 
-bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *binary)
+bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *binary, BinaryDisplayType type)
 {
-    return &binary->text_display[0];
+    return &binary->text_display[type][0];
 
 }
 
@@ -700,6 +703,7 @@ bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *binary)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : binary = élément binaire à consulter.                        *
+*                type   = type de représentation visée.                       *
 *                                                                             *
 *  Description : Indique si le code doit apparaître dans le rendu.            *
 *                                                                             *
@@ -709,9 +713,9 @@ bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *binary)
 *                                                                             *
 ******************************************************************************/
 
-bool *g_loaded_binary_display_code_in_text(GLoadedBinary *binary)
+bool *g_loaded_binary_display_code_in_text(GLoadedBinary *binary, BinaryDisplayType type)
 {
-    return &binary->text_display[1];
+    return &binary->text_display[type][1];
 
 }
 
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 7ff9080..eb042c6 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -62,6 +62,16 @@ typedef enum _BinaryPartModel
 
 } BinaryPartModel;
 
+/* Types de représentation */
+typedef enum _BinaryDisplayType
+{
+    BDT_ASM,                                /* Rendu du code brut          */
+    BDT_GRAPH,                              /* Rendu avec graphiques       */
+
+    BDT_COUNT
+
+} BinaryDisplayType;
+
 
 /* Indique le type défini pour une description de fichier binaire. */
 GType g_loaded_binary_get_type(void);
@@ -97,10 +107,10 @@ GArchInstruction *g_loaded_binary_get_instructions(const GLoadedBinary *);
 GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *);
 
 /* Indique si les adresses doivent apparaître dans le rendu. */
-bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *);
+bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *, BinaryDisplayType);
 
 /* Indique si le code doit apparaître dans le rendu. */
-bool *g_loaded_binary_display_code_in_text(GLoadedBinary *);
+bool *g_loaded_binary_display_code_in_text(GLoadedBinary *, BinaryDisplayType);
 
 /* Fournit le tampon associé au contenu d'un fichier source. */
 GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *, size_t);
diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c
index 49b5573..d494fb4 100644
--- a/src/arch/dalvik/instruction.c
+++ b/src/arch/dalvik/instruction.c
@@ -26,6 +26,7 @@
 
 #include "instruction-int.h"
 #include "decomp/translate.h"
+#include "operands/target.h"
 #include "../instruction-int.h"
 
 
@@ -452,7 +453,49 @@ static const char *dalvik_get_instruction_text(const GDalvikInstruction *instr,
 
 static InstructionLinkType dalvik_get_instruction_link(const GDalvikInstruction *instr, vmpa_t *addr)
 {
-    return ILT_NONE/*instr->get_link(instr, addr)*/;
+    InstructionLinkType result;             /* Type de lien à retourner    */
+    GArchOperand *operand;                  /* Opérande à manipuler        */
+    const GImmOperand *imm;                 /* Valeur immédiate            */
+
+    switch (instr->type)
+    {
+        case DOP_IF_EQ:
+        case DOP_IF_NE:
+        case DOP_IF_LT:
+        case DOP_IF_GE:
+        case DOP_IF_GT:
+        case DOP_IF_LE:
+
+            operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 2);
+            imm = g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand));
+
+            if (g_imm_operand_to_vmpa_t(imm, addr)) result = ILT_JUMP_IF_TRUE;
+            else result = ILT_NONE;
+
+            break;
+
+        case DOP_IF_EQZ:
+        case DOP_IF_NEZ:
+        case DOP_IF_LTZ:
+        case DOP_IF_GEZ:
+        case DOP_IF_GTZ:
+        case DOP_IF_LEZ:
+
+            operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 1);
+            imm = g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand));
+
+            if (g_imm_operand_to_vmpa_t(imm, addr)) result = ILT_JUMP_IF_TRUE;
+            else result = ILT_NONE;
+
+            break;
+
+        default:
+            result = ILT_NONE;
+            break;
+
+    }
+
+    return result;
 
 }
 
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 4360f8c..ce3e19f 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -35,10 +35,6 @@
 
 
 
-/* Espace entre les colonnes */
-#define COL_MARGIN 23
-
-
 
 /* ---------------------------- REGROUPEMENT PAR COLONNE ---------------------------- */
 
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index ce75895..3cc992b 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -100,9 +100,13 @@ typedef enum _RenderingTagType
 #define RTT_NONE RTT_RAW    /* TODO : remme */
 
 
+
 /* Confort pour l'insertion de texte */
 #define SL(str) str, strlen(str)
 
+/* Espace entre les colonnes */
+#define COL_MARGIN 23
+
 
 /* Accompagnement du dessin pour compléments */
 typedef void (* buffer_line_draw_fc) (GBufferLine *, GdkDrawable *, GdkGC *, gint, gint, void *);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index 573d07d..aec3303 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -803,12 +803,12 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
     size_t first;                           /* Première ligne intégrée     */
     size_t last;                            /* Dernière ligne intégrée     */
 
-    *width = 0;
-    *height = view->line_height;
-
     if (!WIDTHS_CACHED(view))
         g_buffer_view_compute_required_widths(view);
 
+    *width = view->left_text;
+    *height = view->line_height;
+
     for (i = 0; i < BLC_COUNT; i++)
     {
         if (i == BLC_ADDRESS && !addr) continue;
@@ -816,6 +816,9 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
 
         *width += view->max_widths[i];
 
+        if ((i + 1) < BLC_COUNT)
+            *width += COL_MARGIN;
+
     }
 
     first = g_code_buffer_get_index_from_address(view->buffer, view->start);
@@ -1083,7 +1086,7 @@ bool g_buffer_view_get_address_coordinates(GBufferView *view, vmpa_t addr, gint
     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 = first; i < last; i++)
+    for (i = first; i <= last; i++)
     {
         current = g_buffer_line_get_address(view->buffer->lines[i]);
 
diff --git a/src/graph/Makefile.am b/src/graph/Makefile.am
deleted file mode 100755
index e374709..0000000
--- a/src/graph/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-
-noinst_LTLIBRARIES  = libgraph.la
-
-libgraph_la_SOURCES =					\
-	dot.h dot.c							\
-	layout.h layout.c					\
-	node.h node.c
-
-libgraph_la_LDFLAGS = 
-
-
-INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBGRAPH_CFLAGS)
-
-AM_CPPFLAGS = 
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-
-SUBDIRS = 
diff --git a/src/graph/dot.c b/src/graph/dot.c
deleted file mode 100644
index 5a80f59..0000000
--- a/src/graph/dot.c
+++ /dev/null
@@ -1,233 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * dot.c - interactions avec le système dot
- *
- * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "dot.h"
-
-
-#include <malloc.h>
-#include <graphviz/gvc.h>
-#include <graphviz/types.h>
-
-
-
-/* Graphique selon Graphviz */
-struct _graph_layout
-{
-    GVC_t *context;                         /* Contexte pour Graphviz      */
-    graph_t *graph;                         /* Graphique construit         */
-
-};
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : cmds = description textuelle du graphique à représenter.     *
-*                                                                             *
-*  Description : Charge un graphique à partir de sa description.              *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-graph_layout *create_graph_layout(char *cmds)
-{
-    graph_layout *result;                   /* Composants à retourner      */
-    int ret;                                /* Bilan d'un appel            */
-
-    result = (graph_layout *)calloc(1, sizeof(graph_layout));
-
-    result->context = gvContext();
-    result->graph = agmemread(cmds);
-
-    if (result->graph == NULL) goto cdl_error;
-
-
-
-    ret = gvLayout(result->context, result->graph, "dot");
-
-
-    printf("ret = %d\n", ret);
-
-    /*
-    ret = gvLayoutJobs(result->context, result->graph);
-    printf("ret = %d\n", ret);
-    ret = gvRenderJobs(result->context, result->graph);
-    printf("ret = %d\n", ret);
-    */
-
-
-    ret = gvRender(result->context, result->graph, "dot", NULL);
-
-
-
-    ret = gvRender(result->context, result->graph, "plain", NULL);
-
-    printf("ret = %d\n", ret);
-
-
-
-
-
-    return result;
-
- cdl_error:
-
-    delete_graph_layout(result);
-
-    return NULL;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : layout = graphique à supprimer de la mémoire.                *
-*                                                                             *
-*  Description : Décharge un graphique.                                       *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_graph_layout(graph_layout *layout)
-{
-    if (layout->graph != NULL)
-    {
-        gvFreeLayout(layout->context, layout->graph);
-        agclose(layout->graph);
-    }
-
-    gvFreeContext(layout->context);
-
-    free(layout);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : layout = graphique à supprimer de la mémoire.                *
-*                view   = support de destination.                             *
-*                nodes  = liste de noeuds à traiter.                          *
-*                count  = taille de la liste.                                 *
-*                                                                             *
-*  Description : Place tous les éléments du graphique à l'écran.              *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view, GGraphNode **nodes, size_t count)
-{
-    int height;                             /* Hauteur du graphique        */
-    node_t *iter;                           /* Boucle de parcours          */
-    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))
-    {
-        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);
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : layout = graphique à supprimer de la mémoire.                *
-*                count  = nombre d'éléments mis en place.                     *
-*                                                                             *
-*  Description : Charge la définition de tous les liens graphiques.           *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, size_t *count)
-{
-    GtkLinkRenderer **result;               /* Liste à retourner           */
-    int height;                             /* Hauteur du graphique        */
-    node_t *niter;                          /* Boucle de parcours #1       */
-    edge_t *eiter;                          /* Boucle de parcours #2       */
-    splines *lines;                         /* Lignes déjà tracées         */
-    int i;                                  /* Boucle de parcours #3       */
-    int k;                                  /* Boucle de parcours #4       */
-    GdkPoint *points;                       /* Points de ligne relus       */
-    size_t points_count;                    /* Nombre de ces points        */
-
-    result = NULL;
-    *count = 0;
-
-    height = GD_bb(layout->graph).UR.y;
-
-    for (niter = agfstnode(layout->graph); niter != NULL; niter = agnxtnode(layout->graph, niter))
-        for (eiter = agfstout(layout->graph, niter); eiter != NULL; eiter = agnxtout(layout->graph, eiter))
-        {
-            lines = ED_spl(eiter);
-
-            //printf("edge == %p\n", eiter);
-
-            points = NULL;
-            points_count = 0;
-
-            for (i = 0; i < lines->size; i++)
-            {
-                points = (GdkPoint *)realloc(points, (points_count + lines->list[i].size) * sizeof(GdkPoint));
-
-                for (k = 0; k < lines->list[i].size; k++)
-                {
-                    points[points_count + k].x = lines->list[i].list[k].x;
-                    points[points_count + k].y = height - lines->list[i].list[k].y;
-
-                    /*
-                    printf("  ... ( %d ; %d)\n",
-                           lines->list[i].list[k].x, height - lines->list[i].list[k].y);
-                    */
-
-                }
-
-                points_count += lines->list[i].size;
-
-                //printf("  ...\n");
-
-            }
-
-            result = (GtkLinkRenderer **)realloc(result, ++(*count) * sizeof(GtkLinkRenderer *));
-            result[*count - 1] = GTK_LINK_RENDERER(gtk_link_renderer_new(points, points_count));
-
-        }
-
-    return result;
-
-}
diff --git a/src/graph/dot.h b/src/graph/dot.h
deleted file mode 100644
index 47550a8..0000000
--- a/src/graph/dot.h
+++ /dev/null
@@ -1,51 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * dot.h - prototypes pour les interactions avec le système dot
- *
- * Copyright (C) 2009 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _GRAPH_DOT_H
-#define _GRAPH_DOT_H
-
-
-#include "node.h"
-#include "../gtkext/gtklinkrenderer.h"
-
-
-
-/* Graphique selon Graphviz */
-typedef struct _graph_layout graph_layout;
-
-
-/* Charge un graphique à partir de sa description. */
-graph_layout *create_graph_layout(char *);
-
-/* Décharge un graphique. */
-void delete_graph_layout(graph_layout *);
-
-/* Place tous les éléments du graphique à l'écran. */
-void place_nodes_of_graph_layout(const graph_layout *, GtkGraphView *, GGraphNode **, size_t);
-
-/* Charge la définition de tous les liens graphiques. */
-GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *, size_t *);
-
-
-
-#endif  /* _GRAPH_DOT_H */
diff --git a/src/graph/layout.c b/src/graph/layout.c
deleted file mode 100644
index f8afad6..0000000
--- a/src/graph/layout.c
+++ /dev/null
@@ -1,219 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * layout.c - mise en place de graphique
- *
- * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "layout.h"
-
-
-#include <malloc.h>
-#include <string.h>
-#include <gtk/gtkfixed.h>
-
-
-#include "dot.h"
-#include "node.h"
-#include "../analysis/binary.h"
-#include "../common/extstr.h"
-#include "../gtkext/gtkbufferview.h"
-
-
-
-/* Taille maximale des descriptions de liens */
-#define LINKS_DESC_LEN 128
-
-
-/* Etablit tous les liens entre les différents morceaux de code. */
-static char *complete_graph_links(const GtkGraphView *, GtkViewPanel **, size_t, char *);
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = support où placer les différents éléments.           *
-*                views = morceaux de code à afficher de façon organisée.      *
-*                count = quantité de ces morceaux de code.                    *
-*                                                                             *
-*  Description : Dispose une série de morceaux d'affichage en graphique.      *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool build_graph_view(GtkGraphView *view, GtkViewPanel **views, size_t count)
-{
-    GGraphNode **nodes;                     /* Intermédiaires en place     */
-    size_t i;                               /* Boucle de parcours          */
-    char *cmds;                             /* Description à envoyer à dot */
-    graph_layout *layout;                   /* Graphique construit         */
-    GtkLinkRenderer **links;                /* Liens graphiques construits */
-    size_t links_count;                     /* Quantité de ces liens       */
-
-    /* Création de la glue */
-
-    nodes = (GGraphNode **)calloc(count, sizeof(GGraphNode *));
-
-    for (i = 0; i < count; 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");
-
-    for (i = 0; i < count; i++)
-        cmds = g_graph_node_register_for_dot(nodes[i], cmds);
-
-    cmds = complete_graph_links(view, views, count, cmds);
-
-    cmds = stradd(cmds, "}");
-
-    layout = create_graph_layout(cmds);
-
-    /* Affichage du graphique */
-
-    place_nodes_of_graph_layout(layout, view,  nodes, count);
-
-    links = create_links_from_graph_layout(layout, &links_count);
-    gtk_graph_view_attach_links(view, links, links_count);
-
-    gtk_widget_queue_draw(GTK_WIDGET(view));
-
-    delete_graph_layout(layout);
-
-    /* TODO : free nodes */
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  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. [OUT]          *
-*                                                                             *
-*  Description : Etablit tous les liens entre les différents morceaux de code.*
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views, size_t count, char *desc)
-{
-    GLoadedBinary *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       */
-    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       */
-    size_t k;                               /* Boucle de parcours #3       */
-    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_loaded_binary_get_instructions(binary);
-
-    for (i = 0; i < count; i++)
-    {
-        buffer = gtk_buffer_view_get_buffer(GTK_BUFFER_VIEW(views[i]));
-        g_buffer_view_get_restrictions(buffer, NULL, &end);
-
-        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_arch_instruction_get_destinations(last, &dests, &types);
-
-            for (j = 0; j < dcount; j++)
-            {
-                g_arch_instruction_get_location(dests[j], NULL, NULL, &addr);
-
-                for (k = 0; k < count; k++)
-                    if (gtk_view_panel_contain_address(views[k], addr))
-                        break;
-
-                if (k < count)
-                    switch (types[j])
-                    {
-                        case ILT_JUMP:
-                            snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
-                            desc = stradd(desc, cmd);
-                            break;
-
-                        case ILT_JUMP_IF_TRUE:
-                            snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
-                            desc = stradd(desc, cmd);
-                            break;
-
-                        case ILT_JUMP_IF_FALSE:
-                            snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
-                            desc = stradd(desc, cmd);
-                            break;
-
-                        default:
-                            break;
-
-                    }
-
-            }
-
-        }
-
-        /* Si la ligne n'est pas la dernière, on suit le flux normal */
-        else if (addr != end)
-        {
-            next = g_arch_instruction_get_next_iter(instrs, last, end);
-            if (next == NULL) continue;
-
-            g_arch_instruction_get_location(next, NULL, NULL, &addr);
-
-            for (k = 0; k < count; k++)
-                if (gtk_view_panel_contain_address(views[k], addr))
-                    break;
-
-            if (k < count)
-            {
-                snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
-                desc = stradd(desc, cmd);
-            }
-
-        }
-
-    }
-
-    return desc;
-
-}
diff --git a/src/graph/layout.h b/src/graph/layout.h
deleted file mode 100644
index 006fa9b..0000000
--- a/src/graph/layout.h
+++ /dev/null
@@ -1,41 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * layout.h - prototypes pour la mise en place de graphique
- *
- * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _GRAPH_LAYOUT_H
-#define _GRAPH_LAYOUT_H
-
-
-#include <stdbool.h>
-
-
-#include "../gtkext/gtkgraphview.h"
-#include "../gtkext/gtkviewpanel.h"
-
-
-
-/* Dispose une série de morceaux d'affichage en graphique. */
-bool build_graph_view(GtkGraphView *, GtkViewPanel **, size_t);
-
-
-
-#endif  /* _GRAPH_LAYOUT_H */
diff --git a/src/graph/node.c b/src/graph/node.c
deleted file mode 100644
index 0d278f3..0000000
--- a/src/graph/node.c
+++ /dev/null
@@ -1,283 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * node.c - éléments de graphiques chez dot
- *
- * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "node.h"
-
-
-#include <malloc.h>
-#include <stdio.h>
-#include <string.h>
-
-
-#include "../common/extstr.h"
-
-
-
-/* -------------------------- GESTION DES NOEUDS A L'UNITE -------------------------- */
-
-
-/* Intermédiaire entre le noeud dot et la bribe de code (instance) */
-struct _GGraphNode
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    GtkWidget *view;                        /* Morceau de code représenté  */
-    char *name;                             /* Adresse sous forme humaine  */
-
-};
-
-
-/* Intermédiaire entre le noeud dot et la bribe de code (classe) */
-struct _GGraphNodeClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-    double dpi_x;                           /* Résolution en abscisse      */
-    double dpi_y;                           /* Résolution en ordonnée      */
-
-};
-
-
-/* Initialise la classe des intermédiaires avec les noeuds dot. */
-static void g_graph_node_class_init(GGraphNodeClass *);
-
-/* Initialise la classe des intermédiaires avec les noeuds dot. */
-static void g_graph_node_init(GGraphNode *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            GESTION DES NOEUDS A L'UNITE                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type définit par la GLib pour le noeud. */
-G_DEFINE_TYPE(GGraphNode, g_graph_node, G_TYPE_OBJECT);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des intermédiaires avec les noeuds dot. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_graph_node_class_init(GGraphNodeClass *klass)
-{
-    GdkScreen *screen;                      /* Ecran par défaut            */
-    gint width;                             /* Largeur d'écran en pixels   */
-    gint height;                            /* Hauteur d'écran en pixels   */
-    gint width_mm;                          /* Largeur d'écran en mm.      */
-    gint height_mm;                         /* Hauteur d'écran en mm.      */
-
-    screen = gdk_screen_get_default();
-
-    width = gdk_screen_get_width(screen);
-    height = gdk_screen_get_height(screen);
-
-    width_mm = gdk_screen_get_width_mm(screen);
-    height_mm = gdk_screen_get_height_mm(screen);
-
-    /**
-     * Il y a 2.54 centimètres, soit 25.4 millimètres, dans un pouce.
-     * On a donc :
-     *
-     *   dpi = N pixels / (M millimètres / (25.4 millimètres / 1 pouce))
-     *       = N pixels / (M pouces / 25.4)
-     *       = N * 25.4 pixels / M pouces
-     *
-     */
- 
-    if (width_mm > 0 && height_mm > 0)
-    {
-        klass->dpi_x = (width  * 25.4) / (double)width_mm;
-        klass->dpi_y = (height * 25.4) / (double)height_mm;
-    }
-    else
-    {
-        klass->dpi_x = 96;
-        klass->dpi_y = 96;
-    }
-
-
-    klass->dpi_x = 72;
-    klass->dpi_y = 72;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : node = instance à initialiser.                               *
-*                                                                             *
-*  Description : Initialise la classe des intermédiaires avec les noeuds dot. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_graph_node_init(GGraphNode *node)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = morceau d'affichage à représenter.                    *
-*                                                                             *
-*  Description : Constitue un intermédiaire entre un noeud dot et du code.    *
-*                                                                             *
-*  Retour      : Adresse de la structure mise en place.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GGraphNode *g_graph_node_new(GtkWidget *view)
-{
-    GGraphNode *result;                     /* Structure à retourner       */
-    size_t len;                             /* Taille du nom               */
-
-    result = g_object_new(G_TYPE_GRAPH_NODE, NULL);
-
-    result->view = view;
-
-    len = 3 + sizeof(GtkWidget *) * 2 + 1;
-
-    result->name = (char *)calloc(len, sizeof(char));
-    snprintf(result->name, len, "_%p", result->view);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : node = intermédiaire à consulter.                            *
-*                cmds = description pour dot à compléter.                     *
-*                                                                             *
-*  Description : Déclare l'intermédiaire en tant que noeud pour dot.          *
-*                                                                             *
-*  Retour      : Description dûment complétée.                                *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-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(node->view, &requisition);
-
-    cmds = stradd(cmds, node->name);
-    cmds = stradd(cmds, " [shape=box, fixedsize ");
-
-    snprintf(buffer, 128, ", width=\"%g\"",
-             requisition.width / G_GRAPH_NODE_GET_CLASS(node)->dpi_x);
-    cmds = stradd(cmds, buffer);
-
-    snprintf(buffer, 128, ", height=\"%g\"",
-             requisition.height / G_GRAPH_NODE_GET_CLASS(node)->dpi_y);
-    cmds = stradd(cmds, buffer);
-
-    cmds = stradd(cmds, "];\n");
-
-    return cmds;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : node = intermédiaire à consulter.                            *
-*                view = support de destination.                               *
-*                x    = abscisse du point d'intégration.                      *
-*                y    = ordonnée du point d'intégration.                      *
-*                                                                             *
-*  Description : Place le morceau de code de l'intermédiaire à l'écran.       *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint y)
-{
-    GtkRequisition requisition;             /* Taille à l'écran actuelle   */
-
-    gtk_widget_size_request(node->view, &requisition);
-
-    x -= requisition.width / 2;
-    y -= requisition.height / 2;
-
-    gtk_graph_view_put(view, node->view, x, y);
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                         MANIPULATION D'ENSEMBLES DE NOEUDS                         */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : nodes  = liste de noeuds à parcourir.                        *
-*                count  = taille de la liste.                                 *
-*                target = nom du noeud recherché.                             *
-*                                                                             *
-*  Description : Recherche un noeud donné dans une série de noeuds.           *
-*                                                                             *
-*  Retour      : Noeud trouvé ou NULL si aucun.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-const GGraphNode *find_graph_node_by_name(GGraphNode **nodes, size_t count, const char *target)
-{
-    const GGraphNode *result;               /* Trouvaille à remonter       */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = NULL;
-
-    for (i = 0; i < count && result == NULL; i++)
-        if (strcmp(nodes[i]->name, target) == 0)
-            result = nodes[i];
-
-    return result;
-
-}
diff --git a/src/graph/node.h b/src/graph/node.h
deleted file mode 100644
index f8d0078..0000000
--- a/src/graph/node.h
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * node.h - prototypes pour les éléments de graphiques chez dot
- *
- * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _GRAPH_NODE_H
-#define _GRAPH_NODE_H
-
-
-#include "../gtkext/gtkgraphview.h"
-
-
-
-/* -------------------------- GESTION DES NOEUDS A L'UNITE -------------------------- */
-
-
-#define G_TYPE_GRAPH_NODE               g_graph_node_get_type()
-#define G_GRAPH_NODE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_graph_node_get_type(), GGraphNode))
-#define G_IS_GRAPH_NODE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_graph_node_get_type()))
-#define G_GRAPH_NODE_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_graph_node_get_type(), GGraphNodeIface))
-#define G_GRAPH_NODE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GRAPH_NODE, GGraphNodeClass))
-
-
-/* Intermédiaire entre le noeud dot et la bribe de code (instance) */
-typedef struct _GGraphNode GGraphNode;
-
-/* Intermédiaire entre le noeud dot et la bribe de code (classe) */
-typedef struct _GGraphNodeClass GGraphNodeClass;
-
-
-/* Indique le type définit par la GLib pour le noeud. */
-GType g_graph_node_get_type(void);
-
-/* Constitue un intermédiaire entre un noeud dot et du code. */
-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 *);
-
-/* Place le morceau de code de l'intermédiaire à l'écran. */
-void g_graph_node_place(const GGraphNode *, GtkGraphView *, gint , gint);
-
-
-
-/* ----------------------- MANIPULATION D'ENSEMBLES DE NOEUDS ----------------------- */
-
-
-/* Recherche un noeud donné dans une série de noeuds. */
-const GGraphNode *find_graph_node_by_name(GGraphNode **, size_t, const char *);
-
-
-
-#endif  /* _GRAPH_NODE_H */
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index f590693..863c7a8 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -18,6 +18,9 @@ libgtkext_la_SOURCES =					\
 	iodamarshal.h iodamarshal.c			\
 	support.h support.c
 
+libgtkext_la_LIBADD = 					\
+	graph/libgtkextgraph.la
+
 libgtkext_la_LDFLAGS = 
 
 
@@ -27,6 +30,8 @@ AM_CPPFLAGS =
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
+SUBDIRS = graph
+
 
 iodamarshal.h: iodamarshal.list
 	glib-genmarshal --header $< > $@
diff --git a/src/gtkext/graph/Makefile.am b/src/gtkext/graph/Makefile.am
new file mode 100755
index 0000000..a631a90
--- /dev/null
+++ b/src/gtkext/graph/Makefile.am
@@ -0,0 +1,18 @@
+
+noinst_LTLIBRARIES  = libgtkextgraph.la
+
+libgtkextgraph_la_SOURCES =				\
+	dot.h dot.c							\
+	layout.h layout.c					\
+	node.h node.c
+
+libgtkextgraph_la_LDFLAGS = 
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBGRAPH_CFLAGS)
+
+AM_CPPFLAGS = 
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = 
diff --git a/src/gtkext/graph/dot.c b/src/gtkext/graph/dot.c
new file mode 100644
index 0000000..396aa93
--- /dev/null
+++ b/src/gtkext/graph/dot.c
@@ -0,0 +1,267 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * dot.c - interactions avec le système dot
+ *
+ * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "dot.h"
+
+
+#include <malloc.h>
+#include <graphviz/gvc.h>
+#include <graphviz/types.h>
+
+
+
+/* Graphique selon Graphviz */
+struct _graph_layout
+{
+    GVC_t *context;                         /* Contexte pour Graphviz      */
+    graph_t *graph;                         /* Graphique construit         */
+
+};
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cmds = description textuelle du graphique à représenter.     *
+*                                                                             *
+*  Description : Charge un graphique à partir de sa description.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+graph_layout *create_graph_layout(char *cmds)
+{
+    graph_layout *result;                   /* Composants à retourner      */
+    int ret;                                /* Bilan d'un appel            */
+
+    result = (graph_layout *)calloc(1, sizeof(graph_layout));
+
+    result->context = gvContext();
+    result->graph = agmemread(cmds);
+
+    if (result->graph == NULL) goto cdl_error;
+
+
+
+    //printf("CMDS =======\n%s\n\n=================\n", cmds);
+
+    ret = gvLayout(result->context, result->graph, "dot");
+    if (ret != 0) goto cdl_error;
+
+
+    //printf("ret = %d\n", ret);
+
+    /*
+    ret = gvLayoutJobs(result->context, result->graph);
+    printf("ret = %d\n", ret);
+    ret = gvRenderJobs(result->context, result->graph);
+    printf("ret = %d\n", ret);
+    */
+
+    ret = gvRender(result->context, result->graph, "dot", NULL);
+    if (ret != 0) goto cdl_error;
+
+
+
+    //ret = gvRender(result->context, result->graph, "plain", NULL);
+
+    //printf("ret = %d\n", ret);
+
+
+
+
+
+    return result;
+
+ cdl_error:
+
+    delete_graph_layout(result);
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : layout = graphique à supprimer de la mémoire.                *
+*                                                                             *
+*  Description : Décharge un graphique.                                       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_graph_layout(graph_layout *layout)
+{
+    if (layout->graph != NULL)
+    {
+        gvFreeLayout(layout->context, layout->graph);
+        agclose(layout->graph);
+    }
+
+    gvFreeContext(layout->context);
+
+    free(layout);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : layout = graphique à supprimer de la mémoire.                *
+*                view   = support de destination.                             *
+*                nodes  = liste de noeuds à traiter.                          *
+*                count  = taille de la liste.                                 *
+*                                                                             *
+*  Description : Place tous les éléments du graphique à l'écran.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view, GGraphNode **nodes, size_t count)
+{
+    int height;                             /* Hauteur du graphique        */
+    node_t *iter;                           /* Boucle de parcours          */
+    GGraphNode *node;                       /* Intermédiaire concerné      */
+
+    height = GD_bb(layout->graph).UR.y;
+
+    for (iter = agfstnode(layout->graph); iter != NULL; iter = agnxtnode(layout->graph, iter))
+    {
+        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);
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : layout = graphique à supprimer de la mémoire.                *
+*                count  = nombre d'éléments mis en place.                     *
+*                nodes  = liste de noeuds à consulter.                        *
+*                ncount = taille de la liste des noeuds.                      *
+*                                                                             *
+*  Description : Charge la définition de tous les liens graphiques.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, size_t *count, GGraphNode **nodes, size_t ncount)
+{
+    GtkLinkRenderer **result;               /* Liste à retourner           */
+    int height;                             /* Hauteur du graphique        */
+    node_t *niter;                          /* Boucle de parcours #1       */
+    edge_t *eiter;                          /* Boucle de parcours #2       */
+    GdkPoint *points;                       /* Points de ligne relus       */
+    size_t points_count;                    /* Nombre de ces points        */
+    splines *lines;                         /* Lignes déjà tracées         */
+    GGraphNode *node;                       /* Noeud rattaché              */
+    int i;                                  /* Boucle de parcours #3       */
+    int k;                                  /* Boucle de parcours #4       */
+    bezier *bez;                            /* Courbe à reproduire         */
+    Agsym_t *attrib;                        /* Couleur d'un lien           */
+    LinkColor color;                        /* Couleur d'impression        */
+
+    result = NULL;
+    *count = 0;
+
+    height = GD_bb(layout->graph).UR.y;
+
+    for (niter = agfstnode(layout->graph); niter != NULL; niter = agnxtnode(layout->graph, niter))
+        for (eiter = agfstout(layout->graph, niter); eiter != NULL; eiter = agnxtout(layout->graph, eiter))
+        {
+            points = NULL;
+            points_count = 0;
+
+            lines = ED_spl(eiter);
+
+            /* Raccordement au point de départ */
+
+            node = find_graph_node_by_name(nodes, ncount, agtail(eiter)->name);
+
+            g_graph_node_connect(node,
+                                 lines->list[0].list[0].x,
+                                 height - lines->list[0].list[0].y,
+                                 &points, &points_count);
+
+            /* Tracé du lien... */
+
+            for (i = 0; i < lines->size; i++)
+            {
+                bez = &lines->list[i];
+
+                points = (GdkPoint *)realloc(points, (points_count + bez->size) * sizeof(GdkPoint));
+
+                for (k = 0; k < bez->size; k++)
+                {
+                    points[points_count + k].x = bez->list[k].x;
+                    points[points_count + k].y = height - bez->list[k].y;
+                }
+
+                points_count += bez->size;
+
+            }
+
+            /* Raccordement au point d'arrivée */
+
+            node = find_graph_node_by_name(nodes, ncount, aghead(eiter)->name);
+
+            g_graph_node_connect(node,
+                                 bez->list[k - 1].x,
+                                 height - bez->list[k - 1].y,
+                                 &points, &points_count);
+
+            /* Détermination de la couleur */
+
+            attrib = agfindedgeattr(agraphof(agtail(eiter)), "color");
+
+            result = (GtkLinkRenderer **)realloc(result, ++(*count) * sizeof(GtkLinkRenderer *));
+
+            if (eiter->attr[attrib->index][0] == 'g')   /* "green" */
+                color = LKC_GREEN;
+            else if (eiter->attr[attrib->index][0] == 'r')   /* "red" */
+                color = LKC_RED;
+            else
+                color = LKC_DEFAULT;
+
+            result[*count - 1] = GTK_LINK_RENDERER(gtk_link_renderer_new(color,
+                                                                         points, points_count));
+
+        }
+
+    return result;
+
+}
diff --git a/src/gtkext/graph/dot.h b/src/gtkext/graph/dot.h
new file mode 100644
index 0000000..d610e1b
--- /dev/null
+++ b/src/gtkext/graph/dot.h
@@ -0,0 +1,51 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * dot.h - prototypes pour les interactions avec le système dot
+ *
+ * Copyright (C) 2009 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GRAPH_DOT_H
+#define _GRAPH_DOT_H
+
+
+#include "node.h"
+#include "../gtklinkrenderer.h"
+
+
+
+/* Graphique selon Graphviz */
+typedef struct _graph_layout graph_layout;
+
+
+/* Charge un graphique à partir de sa description. */
+graph_layout *create_graph_layout(char *);
+
+/* Décharge un graphique. */
+void delete_graph_layout(graph_layout *);
+
+/* Place tous les éléments du graphique à l'écran. */
+void place_nodes_of_graph_layout(const graph_layout *, GtkGraphView *, GGraphNode **, size_t);
+
+/* Charge la définition de tous les liens graphiques. */
+GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *, size_t *, GGraphNode **, size_t);
+
+
+
+#endif  /* _GRAPH_DOT_H */
diff --git a/src/gtkext/graph/layout.c b/src/gtkext/graph/layout.c
new file mode 100644
index 0000000..69e32cc
--- /dev/null
+++ b/src/gtkext/graph/layout.c
@@ -0,0 +1,229 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * layout.c - mise en place de graphique
+ *
+ * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "layout.h"
+
+
+#include <malloc.h>
+#include <string.h>
+#include <gtk/gtkfixed.h>
+
+
+#include "dot.h"
+#include "node.h"
+#include "../gtkbufferview.h"
+#include "../../analysis/binary.h"
+#include "../../common/extstr.h"
+
+
+
+/* Taille maximale des descriptions de liens */
+#define LINKS_DESC_LEN 128
+
+
+/* Etablit tous les liens entre les différents morceaux de code. */
+static char *complete_graph_links(const GtkGraphView *, GtkViewPanel **, size_t, char *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view  = support où placer les différents éléments.           *
+*                views = morceaux de code à afficher de façon organisée.      *
+*                count = quantité de ces morceaux de code.                    *
+*                                                                             *
+*  Description : Dispose une série de morceaux d'affichage en graphique.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool build_graph_view(GtkGraphView *view, GtkViewPanel **views, size_t count)
+{
+    GGraphNode **nodes;                     /* Intermédiaires en place     */
+    size_t i;                               /* Boucle de parcours          */
+    char *cmds;                             /* Description à envoyer à dot */
+    graph_layout *layout;                   /* Graphique construit         */
+    GtkLinkRenderer **links;                /* Liens graphiques construits */
+    size_t links_count;                     /* Quantité de ces liens       */
+
+    /* Création de la glue */
+
+    nodes = (GGraphNode **)calloc(count, sizeof(GGraphNode *));
+
+    for (i = 0; i < count; i++)
+        nodes[i] = g_graph_node_new(GTK_WIDGET(views[i]));
+ 
+    /* Définition du graphique */
+
+    cmds = strdup("digraph G {\noverlap=false;\n  splines=ortho;\n  compound=true;\n");
+
+    for (i = 0; i < count; i++)
+        cmds = g_graph_node_register_for_dot(nodes[i], cmds);
+
+    cmds = complete_graph_links(view, views, count, cmds);
+
+    cmds = stradd(cmds, "}");
+
+    layout = create_graph_layout(cmds);
+
+    /* Affichage du graphique */
+
+    place_nodes_of_graph_layout(layout, view,  nodes, count);
+
+    links = create_links_from_graph_layout(layout, &links_count,  nodes, count);
+    gtk_graph_view_attach_links(view, links, links_count);
+
+    gtk_widget_queue_draw(GTK_WIDGET(view));
+
+    delete_graph_layout(layout);
+
+    /* TODO : free nodes */
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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. [OUT]          *
+*                                                                             *
+*  Description : Etablit tous les liens entre les différents morceaux de code.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views, size_t count, char *desc)
+{
+    GLoadedBinary *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       */
+    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       */
+    size_t k;                               /* Boucle de parcours #3       */
+    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_loaded_binary_get_instructions(binary);
+
+    for (i = 0; i < count; i++)
+    {
+        buffer = gtk_buffer_view_get_buffer(GTK_BUFFER_VIEW(views[i]));
+        g_buffer_view_get_restrictions(buffer, NULL, &end);
+
+        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_arch_instruction_get_destinations(last, &dests, &types);
+
+            for (j = 0; j < dcount; j++)
+            {
+                g_arch_instruction_get_location(dests[j], NULL, NULL, &addr);
+
+                for (k = 0; k < count; k++)
+                    if (gtk_view_panel_contain_address(views[k], addr))
+                        break;
+
+                if (k < count)
+                    switch (types[j])
+                    {
+                        case ILT_JUMP:
+                            snprintf(cmd, LINKS_DESC_LEN,
+                                     "_%p:s -> _%p:n  [ltail=cluster_%p, lhead=cluster_%p];\n",
+                                     views[i], views[k], views[i], views[k]);
+                            desc = stradd(desc, cmd);
+                            break;
+
+                        case ILT_JUMP_IF_TRUE:
+                            snprintf(cmd, LINKS_DESC_LEN,
+                                     "_%p:s -> _%p:n  [ltail=cluster_%p, lhead=cluster_%p, " \
+                                     "color=green];\n",
+                                     views[i], views[k], views[i], views[k]);
+                            desc = stradd(desc, cmd);
+                            break;
+
+                        case ILT_JUMP_IF_FALSE:
+                            snprintf(cmd, LINKS_DESC_LEN,
+                                     "_%p:s -> _%p:n  [ltail=cluster_%p, lhead=cluster_%p, " \
+                                     "color=red];\n",
+                                     views[i], views[k], views[i], views[k]);
+                            desc = stradd(desc, cmd);
+                            break;
+
+                        default:
+                            break;
+
+                    }
+
+            }
+
+        }
+
+        /* Sinon on suit le flux normal */
+        else
+        {
+            next = g_arch_instruction_get_next_iter(instrs, last, VMPA_MAX);
+            if (next == NULL) continue;
+
+            g_arch_instruction_get_location(next, NULL, NULL, &addr);
+
+            for (k = 0; k < count; k++)
+                if (gtk_view_panel_contain_address(views[k], addr))
+                    break;
+
+            if (k < count)
+            {
+                snprintf(cmd, LINKS_DESC_LEN,
+                         "_%p:s -> _%p:n  [ltail=cluster_%p, lhead=cluster_%p];\n",
+                         views[i], views[k], views[i], views[k]);
+                desc = stradd(desc, cmd);
+            }
+
+        }
+
+    }
+
+    return desc;
+
+}
diff --git a/src/gtkext/graph/layout.h b/src/gtkext/graph/layout.h
new file mode 100644
index 0000000..ffb227f
--- /dev/null
+++ b/src/gtkext/graph/layout.h
@@ -0,0 +1,41 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * layout.h - prototypes pour la mise en place de graphique
+ *
+ * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GRAPH_LAYOUT_H
+#define _GRAPH_LAYOUT_H
+
+
+#include <stdbool.h>
+
+
+#include "../gtkgraphview.h"
+#include "../gtkviewpanel.h"
+
+
+
+/* Dispose une série de morceaux d'affichage en graphique. */
+bool build_graph_view(GtkGraphView *, GtkViewPanel **, size_t);
+
+
+
+#endif  /* _GRAPH_LAYOUT_H */
diff --git a/src/gtkext/graph/node.c b/src/gtkext/graph/node.c
new file mode 100644
index 0000000..f3e6352
--- /dev/null
+++ b/src/gtkext/graph/node.c
@@ -0,0 +1,353 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * node.c - éléments de graphiques chez dot
+ *
+ * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "node.h"
+
+
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+
+
+#include "../../common/extstr.h"
+
+
+
+/* -------------------------- GESTION DES NOEUDS A L'UNITE -------------------------- */
+
+
+/* Intermédiaire entre le noeud dot et la bribe de code (instance) */
+struct _GGraphNode
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GtkWidget *view;                        /* Morceau de code représenté  */
+    char *name;                             /* Adresse sous forme humaine  */
+
+    GtkAllocation alloc;                    /* Emplacement du bloc rattaché*/
+
+};
+
+
+/* Intermédiaire entre le noeud dot et la bribe de code (classe) */
+struct _GGraphNodeClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    double dpi_x;                           /* Résolution en abscisse      */
+    double dpi_y;                           /* Résolution en ordonnée      */
+
+};
+
+
+/* Initialise la classe des intermédiaires avec les noeuds dot. */
+static void g_graph_node_class_init(GGraphNodeClass *);
+
+/* Initialise la classe des intermédiaires avec les noeuds dot. */
+static void g_graph_node_init(GGraphNode *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            GESTION DES NOEUDS A L'UNITE                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type définit par la GLib pour le noeud. */
+G_DEFINE_TYPE(GGraphNode, g_graph_node, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des intermédiaires avec les noeuds dot. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_graph_node_class_init(GGraphNodeClass *klass)
+{
+    GdkScreen *screen;                      /* Ecran par défaut            */
+    gint width;                             /* Largeur d'écran en pixels   */
+    gint height;                            /* Hauteur d'écran en pixels   */
+    gint width_mm;                          /* Largeur d'écran en mm.      */
+    gint height_mm;                         /* Hauteur d'écran en mm.      */
+
+    screen = gdk_screen_get_default();
+
+    width = gdk_screen_get_width(screen);
+    height = gdk_screen_get_height(screen);
+
+    width_mm = gdk_screen_get_width_mm(screen);
+    height_mm = gdk_screen_get_height_mm(screen);
+
+    /**
+     * Il y a 2.54 centimètres, soit 25.4 millimètres, dans un pouce.
+     * On a donc :
+     *
+     *   dpi = N pixels / (M millimètres / (25.4 millimètres / 1 pouce))
+     *       = N pixels / (M pouces / 25.4)
+     *       = N * 25.4 pixels / M pouces
+     *
+     */
+ 
+    if (width_mm > 0 && height_mm > 0)
+    {
+        klass->dpi_x = (width  * 25.4) / (double)width_mm;
+        klass->dpi_y = (height * 25.4) / (double)height_mm;
+    }
+    else
+    {
+        klass->dpi_x = 96;
+        klass->dpi_y = 96;
+    }
+
+
+    klass->dpi_x = 72;
+    klass->dpi_y = 72;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise la classe des intermédiaires avec les noeuds dot. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_graph_node_init(GGraphNode *node)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view = morceau d'affichage à représenter.                    *
+*                                                                             *
+*  Description : Constitue un intermédiaire entre un noeud dot et du code.    *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGraphNode *g_graph_node_new(GtkWidget *view)
+{
+    GGraphNode *result;                     /* Structure à retourner       */
+    size_t len;                             /* Taille du nom               */
+
+    result = g_object_new(G_TYPE_GRAPH_NODE, NULL);
+
+    result->view = view;
+
+    len = 3 + sizeof(GtkWidget *) * 2 + 1;
+
+    result->name = (char *)calloc(len, sizeof(char));
+    snprintf(result->name, len, "_%p", result->view);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = intermédiaire à consulter.                            *
+*                cmds = description pour dot à compléter.                     *
+*                                                                             *
+*  Description : Déclare l'intermédiaire en tant que noeud pour dot.          *
+*                                                                             *
+*  Retour      : Description dûment complétée.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+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(node->view, &requisition);
+
+    snprintf(buffer, 128, "  subgraph cluster%s {\n", node->name);
+    cmds = stradd(cmds, buffer);
+
+    cmds = stradd(cmds, "    style=invisible;\n");
+
+    cmds = stradd(cmds, "    ");
+    cmds = stradd(cmds, node->name);
+    cmds = stradd(cmds, " [shape=box, fixedsize ");
+
+    snprintf(buffer, 128, ", width=\"%g\"",
+             requisition.width / G_GRAPH_NODE_GET_CLASS(node)->dpi_x);
+    cmds = stradd(cmds, buffer);
+
+    snprintf(buffer, 128, ", height=\"%g\"",
+             requisition.height / G_GRAPH_NODE_GET_CLASS(node)->dpi_y);
+    cmds = stradd(cmds, buffer);
+
+    cmds = stradd(cmds, "];\n");
+
+    cmds = stradd(cmds, "  }\n");
+
+    return cmds;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = intermédiaire à consulter.                            *
+*                view = support de destination.                               *
+*                x    = abscisse du point d'intégration.                      *
+*                y    = ordonnée du point d'intégration.                      *
+*                                                                             *
+*  Description : Place le morceau de code de l'intermédiaire à l'écran.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_graph_node_place(GGraphNode *node, GtkGraphView *view, gint x, gint y)
+{
+    GtkRequisition requisition;             /* Taille à l'écran actuelle   */
+
+    gtk_widget_size_request(node->view, &requisition);
+
+    x -= requisition.width / 2;
+    y -= requisition.height / 2;
+
+    gtk_graph_view_put(view, node->view, x, y);
+
+    node->alloc.x = x;
+    node->alloc.y = y;
+    node->alloc.width = requisition.width;
+    node->alloc.height = requisition.height;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node   = intermédiaire à consulter.                          *
+*                x      = abscisse du point à relier.                         *
+*                y      = ordonnée du point à relier.                         *
+*                points = liste de points à mettre à jour. [OUT]              *
+*                count  = taille de cette même liste. [OUT]                   *
+*                                                                             *
+*  Description : Etablit une jonction ferme avec un noeud.                    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_graph_node_connect(const GGraphNode *node, gint x, gint y, GdkPoint **points, size_t *count)
+{
+    const GtkAllocation *alloc;             /* Emplacement du bloc rattaché*/
+
+    alloc = &node->alloc;
+
+    *points = (GdkPoint *)realloc(*points, ++(*count) * sizeof(GdkPoint));
+
+    /* Si le point est sur la gauche... */
+    if (alloc->y <= y && y < (alloc->y + alloc->height) && x < alloc->x)
+    {
+        (*points)[*count - 1].x = alloc->x;
+        (*points)[*count - 1].y = y;
+    }
+
+    /* Si le point est sur la droite... */
+    else if (alloc->y <= y && y < (alloc->y + alloc->height) && x > (alloc->x + alloc->width))
+    {
+        (*points)[*count - 1].x = alloc->x + alloc->width;
+        (*points)[*count - 1].y = y;
+    }
+
+    /* Si le point est au dessus... */
+    else if (alloc->x <= x && x < (alloc->x + alloc->width) && y < alloc->y)
+    {
+        (*points)[*count - 1].x = x;
+        (*points)[*count - 1].y = alloc->y;
+    }
+
+    /* Si le point est en dessous... */
+    else if (alloc->x <= x && x < (alloc->x + alloc->width) && y > (alloc->y + alloc->height))
+    {
+        (*points)[*count - 1].x = x;
+        (*points)[*count - 1].y = alloc->y + alloc->height;
+    }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         MANIPULATION D'ENSEMBLES DE NOEUDS                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : nodes  = liste de noeuds à parcourir.                        *
+*                count  = taille de la liste.                                 *
+*                target = nom du noeud recherché.                             *
+*                                                                             *
+*  Description : Recherche un noeud donné dans une série de noeuds.           *
+*                                                                             *
+*  Retour      : Noeud trouvé ou NULL si aucun.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGraphNode *find_graph_node_by_name(GGraphNode **nodes, size_t count, const char *target)
+{
+    GGraphNode *result;                     /* Trouvaille à remonter       */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = NULL;
+
+    for (i = 0; i < count && result == NULL; i++)
+        if (strcmp(nodes[i]->name, target) == 0)
+            result = nodes[i];
+
+    return result;
+
+}
diff --git a/src/gtkext/graph/node.h b/src/gtkext/graph/node.h
new file mode 100644
index 0000000..515c92b
--- /dev/null
+++ b/src/gtkext/graph/node.h
@@ -0,0 +1,74 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * node.h - prototypes pour les éléments de graphiques chez dot
+ *
+ * Copyright (C) 2009-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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GRAPH_NODE_H
+#define _GRAPH_NODE_H
+
+
+#include "../gtkgraphview.h"
+
+
+
+/* -------------------------- GESTION DES NOEUDS A L'UNITE -------------------------- */
+
+
+#define G_TYPE_GRAPH_NODE               g_graph_node_get_type()
+#define G_GRAPH_NODE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_graph_node_get_type(), GGraphNode))
+#define G_IS_GRAPH_NODE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_graph_node_get_type()))
+#define G_GRAPH_NODE_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_graph_node_get_type(), GGraphNodeIface))
+#define G_GRAPH_NODE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GRAPH_NODE, GGraphNodeClass))
+
+
+/* Intermédiaire entre le noeud dot et la bribe de code (instance) */
+typedef struct _GGraphNode GGraphNode;
+
+/* Intermédiaire entre le noeud dot et la bribe de code (classe) */
+typedef struct _GGraphNodeClass GGraphNodeClass;
+
+
+/* Indique le type définit par la GLib pour le noeud. */
+GType g_graph_node_get_type(void);
+
+/* Constitue un intermédiaire entre un noeud dot et du code. */
+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 *);
+
+/* Place le morceau de code de l'intermédiaire à l'écran. */
+void g_graph_node_place(GGraphNode *, GtkGraphView *, gint , gint);
+
+/* Etablit une jonction ferme avec un noeud. */
+void g_graph_node_connect(const GGraphNode *, gint, gint, GdkPoint **, size_t *);
+
+
+
+/* ----------------------- MANIPULATION D'ENSEMBLES DE NOEUDS ----------------------- */
+
+
+/* Recherche un noeud donné dans une série de noeuds. */
+GGraphNode *find_graph_node_by_name(GGraphNode **, size_t, const char *);
+
+
+
+#endif  /* _GRAPH_NODE_H */
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 9fa9135..c0ea347 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -27,7 +27,7 @@
 #include "gtkblockview.h"
 #include "gtkbufferview.h"
 #include "gtkviewpanel-int.h"
-#include "../graph/layout.h"
+#include "graph/layout.h"
 
 
 
@@ -554,8 +554,8 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinar
     list = g_loaded_binary_get_instructions(binary);
     buffer = g_loaded_binary_get_disassembled_buffer(binary);
 
-    addr = g_loaded_binary_display_addresses_in_text(binary);
-    code = g_loaded_binary_display_code_in_text(binary);
+    addr = g_loaded_binary_display_addresses_in_text(binary, BDT_GRAPH);
+    code = g_loaded_binary_display_code_in_text(binary, BDT_GRAPH);
 
     first = start;
     last = first;
@@ -564,7 +564,7 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinar
          iter != NULL;
          iter = g_arch_instruction_get_next_iter(list, iter, end))
     {
-        if (g_arch_instruction_has_sources(iter))
+        if (first != VMPA_MAX && g_arch_instruction_has_sources(iter))
         {
             result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
 
diff --git a/src/gtkext/gtklinkrenderer.c b/src/gtkext/gtklinkrenderer.c
index 9332860..2913c19 100644
--- a/src/gtkext/gtklinkrenderer.c
+++ b/src/gtkext/gtklinkrenderer.c
@@ -24,12 +24,16 @@
 #include "gtklinkrenderer.h"
 
 
+#include <math.h>
+
+
 
 /* Lien entre morceaux de code (instance) */
 struct _GtkLinkRenderer
 {
     GtkObject parent;                       /* A laisser en premier        */
 
+    LinkColor color;                        /* Couleur d'impression        */
     GdkPoint *points;                       /* Points de la ligne dessinée */
     size_t count;                           /* Quantité de ces points      */
 
@@ -44,12 +48,18 @@ struct _GtkLinkRendererClass
 };
 
 
+#define ARROW_LENGHT 10
+#define ARROW_DEGREES 10
+
+
 /* Initialise la classe générique des liens graphiques. */
 static void gtk_link_renderer_class_init(GtkLinkRendererClass *);
 
 /* Initialise une instance de lien graphique entre codes. */
 static void gtk_link_renderer_init(GtkLinkRenderer *);
 
+/* Dessine une flèche au bout du lien représenté. */
+static void draw_link_arrow(cairo_t *, gint, gint, gint, gint);
 
 
 
@@ -95,7 +105,8 @@ static void gtk_link_renderer_init(GtkLinkRenderer *view)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : points = points consituant la ligne à représenter.           *
+*  Paramètres  : color  = couleur d'impression.                               *
+ù                points = points consituant la ligne à représenter.           *
 *                count  = nombre de ces points.                               *
 *                                                                             *
 *  Description : Crée un nouveau moteur de rendu pour les liens graphiques.   *
@@ -106,12 +117,13 @@ static void gtk_link_renderer_init(GtkLinkRenderer *view)
 *                                                                             *
 ******************************************************************************/
 
-GtkObject *gtk_link_renderer_new(GdkPoint *points, size_t count)
+GtkObject *gtk_link_renderer_new(LinkColor color, GdkPoint *points, size_t count)
 {
     GtkLinkRenderer *result;                /* Moteur de rendu à retourner */
 
     result = g_object_new(GTK_TYPE_LINK_RENDERER, NULL);
 
+    result->color = color;
     result->points = points;
     result->count = count;
 
@@ -136,6 +148,88 @@ GtkObject *gtk_link_renderer_new(GdkPoint *points, size_t count)
 
 void gtk_link_renderer_draw(const GtkLinkRenderer *renderer, GdkDrawable *drawable, GdkGC *gc)
 {
-    gdk_draw_lines(drawable, gc, renderer->points, renderer->count);
+    cairo_t *cairo;                         /* Gestionnaire de rendu       */
+    size_t i;                               /* Boucle de parcours          */
+
+    cairo = gdk_cairo_create(drawable);
+
+    switch (renderer->color)
+    {
+        default:
+        case LKC_DEFAULT:
+            cairo_set_source_rgb(cairo, 0, 0, 0);
+            break;
+        case LKC_GREEN:
+            cairo_set_source_rgb(cairo, 0, 0.6, 0);
+            break;
+        case LKC_RED:
+            cairo_set_source_rgb(cairo, 0.8, 0, 0);
+            break;
+    }
+
+    cairo_set_line_width(cairo, 1);
+
+    cairo_move_to(cairo, renderer->points[0].x, renderer->points[0].y);
+
+    for (i = 1; i < renderer->count; i++)
+        cairo_line_to(cairo, renderer->points[i].x, renderer->points[i].y);
+
+    cairo_stroke(cairo);
+
+    draw_link_arrow(cairo,
+                    renderer->points[renderer->count - 2].x,
+                    renderer->points[renderer->count - 2].y,
+                    renderer->points[renderer->count - 1].x,
+                    renderer->points[renderer->count - 1].y);
+
+    cairo_destroy(cairo);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cairo   = gestionnaire de rendu graphique.                   *
+*                start_x = abscisse du début du segment final.                *
+*                start_y = ordonnée du début du segment final.                *
+*                end_x   = abscisse de fin de segment et pointe de flèche.    *
+*                end_y   = ordonnée de fin de segment et pointe de flèche.    *
+*                                                                             *
+*  Description : Dessine une flèche au bout du lien représenté.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void draw_link_arrow(cairo_t *cairo, gint start_x, gint start_y, gint end_x, gint end_y)
+{
+    double angle;                           /* Angle du triangle à remplir */
+    double factor_x;                        /* Direction de la flèche #1   */
+    double factor_y;                        /* Direction de la flèche #2   */
+    double x1;                              /* Abscisse du point n°1       */
+    double y1;                              /* Ordonnée du point n°1       */
+    double x2;                              /* Abscisse du point n°2       */
+    double y2;                              /* Ordonnée du point n°2       */
+
+    angle = atan2(end_y - start_y, end_x - start_x) + M_PI;
+
+    factor_x = -1;
+    factor_y = -1;
+
+    x1 = end_x + factor_x * ARROW_LENGHT * cos(angle - ARROW_DEGREES);
+    y1 = end_y + factor_y * ARROW_LENGHT * sin(angle - ARROW_DEGREES);
+    x2 = end_x + factor_x * ARROW_LENGHT * cos(angle + ARROW_DEGREES);
+    y2 = end_y + factor_y * ARROW_LENGHT * sin(angle + ARROW_DEGREES);
+
+    cairo_move_to(cairo, end_x, end_y);
+
+    cairo_line_to(cairo, x1, y1);
+    cairo_line_to(cairo, x2, y2);
+
+    cairo_move_to(cairo, end_x, end_y);
+
+    cairo_fill(cairo);
 
 }
diff --git a/src/gtkext/gtklinkrenderer.h b/src/gtkext/gtklinkrenderer.h
index d662454..95cdea6 100644
--- a/src/gtkext/gtklinkrenderer.h
+++ b/src/gtkext/gtklinkrenderer.h
@@ -45,11 +45,23 @@ typedef struct _GtkLinkRenderer GtkLinkRenderer;
 typedef struct _GtkLinkRendererClass GtkLinkRendererClass;
 
 
+/* Couleur de représentation */
+typedef enum _LinkColor
+{
+    LKC_DEFAULT,                            /* Noir, par défaut            */
+    LKC_GREEN,                              /* Condition vérifiée          */
+    LKC_RED,                                /* Condition non vérifiée      */
+
+    LKC_COUNT
+
+} LinkColor;
+
+
 /* Détermine le type du moteur de rendu pour les liens graphiques. */
 GType gtk_link_renderer_get_type(void);
 
 /* Crée un nouveau moteur de rendu pour les liens graphiques. */
-GtkObject *gtk_link_renderer_new(GdkPoint *, size_t);
+GtkObject *gtk_link_renderer_new(LinkColor, GdkPoint *, size_t);
 
 /* Dessine les liens graphiques enregistrés dans le moteur. */
 void gtk_link_renderer_draw(const GtkLinkRenderer *, GdkDrawable *, GdkGC *);
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 3ccc0ff..0ab4f72 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -293,8 +293,7 @@ static gboolean gtk_view_panel_expose(GtkWidget *widget, GdkEventExpose *event)
     GtkViewPanel *panel;
     GdkGCValues values;                     /* Propriétés du contexte      */
     GtkStyle *style;                        /* Style associé au composant  */
-    int width;                              /* Largeur de l'élément        */
-    int height;                             /* Hauteur de l'élément        */
+    GtkRequisition req;                     /* Taille allouée à l'élément  */
     GtkStateType state;                     /* Etat du composant           */
 
     panel = GTK_VIEW_PANEL(widget);
@@ -304,13 +303,13 @@ static gboolean gtk_view_panel_expose(GtkWidget *widget, GdkEventExpose *event)
         gdk_gc_get_values(panel->gc, &values);
         style = gtk_widget_get_style(widget);
 
-        gtk_widget_get_size_request(widget, &width, &height);
+        gtk_widget_size_request(widget, &req);
 
         state = gtk_widget_get_state(widget);
         gdk_gc_set_foreground(panel->gc, &style->dark[state]);
 
         gdk_draw_rectangle(GDK_DRAWABLE(widget->window), panel->gc,
-                           FALSE, 0, 0, width - 1, height - 1);
+                           FALSE, 0, 0, req.width - 1, req.height - 1);
 
         gdk_gc_set_foreground(panel->gc, &values.foreground);
 
diff --git a/src/project.c b/src/project.c
index b6526c7..106bf3a 100644
--- a/src/project.c
+++ b/src/project.c
@@ -390,8 +390,8 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina
         loaded->views[i] = GTK_VIEW_PANEL(view);
 
         gtk_view_panel_attach_binary(loaded->views[i], binary,
-                                     g_loaded_binary_display_addresses_in_text(binary),
-                                     g_loaded_binary_display_code_in_text(binary));
+                                     g_loaded_binary_display_addresses_in_text(binary, BDT_ASM),
+                                     g_loaded_binary_display_code_in_text(binary, BDT_ASM));
 
         /* Intégration finale dans un support défilant */
 
-- 
cgit v0.11.2-87-g4458