From 932ea7c83c07d3982fee605c6dd9895fd2753874 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 30 Dec 2016 11:38:52 +0100
Subject: Rewritten the line buffers using generators and on-demand building to
 save memory.

---
 ChangeLog                               |  220 ++++
 configure.ac                            |    5 +-
 plugins/Makefile.am                     |    3 +-
 plugins/pychrysa/analysis/binary.c      |   16 +-
 plugins/pychrysa/glibext/Makefile.am    |    2 +-
 plugins/pychrysa/glibext/buffercache.c  |  165 +++
 plugins/pychrysa/glibext/buffercache.h  |   42 +
 plugins/pychrysa/glibext/codebuffer.c   |  161 ---
 plugins/pychrysa/glibext/codebuffer.h   |   42 -
 plugins/pychrysa/glibext/module.c       |    4 +-
 plugins/pychrysa/gtkext/Makefile.am     |    4 +-
 plugins/pychrysa/gtkext/blockdisplay.c  |  109 ++
 plugins/pychrysa/gtkext/blockdisplay.h  |   42 +
 plugins/pychrysa/gtkext/blockview.c     |  108 --
 plugins/pychrysa/gtkext/blockview.h     |   42 -
 plugins/pychrysa/gtkext/bufferdisplay.c |  109 ++
 plugins/pychrysa/gtkext/bufferdisplay.h |   42 +
 plugins/pychrysa/gtkext/bufferview.c    |  108 --
 plugins/pychrysa/gtkext/bufferview.h    |   42 -
 plugins/pychrysa/gtkext/module.c        |    8 +-
 plugins/ropgadgets/select.c             |   23 +-
 src/analysis/Makefile.am                |    3 +-
 src/analysis/binary.c                   |   29 +-
 src/analysis/binary.h                   |    7 +-
 src/analysis/content.c                  |    2 +-
 src/analysis/db/items/bookmark.c        |    4 +-
 src/analysis/db/items/comment.c         |  335 +++++-
 src/analysis/db/items/comment.h         |    9 -
 src/analysis/db/items/move.h            |    2 +-
 src/analysis/db/items/switcher.c        |    5 +-
 src/analysis/disass/area.h              |    1 +
 src/analysis/disass/disassembler.c      |  127 +--
 src/analysis/disass/disassembler.h      |    2 +-
 src/analysis/disass/output.c            |  183 +---
 src/analysis/disass/output.h            |    8 +-
 src/analysis/human/Makefile.am          |   19 +
 src/analysis/human/asm/Makefile.am      |   17 +
 src/analysis/human/asm/lang.c           |  221 ++++
 src/analysis/human/asm/lang.h           |   58 +
 src/analysis/human/lang-int.h           |   58 +
 src/analysis/human/lang.c               |  167 +++
 src/analysis/human/lang.h               |   58 +
 src/analysis/project.c                  |   18 +-
 src/arch/dalvik/link.c                  |    5 +
 src/arch/instruction-int.h              |    2 +-
 src/arch/instruction.c                  |  293 +++--
 src/arch/instruction.h                  |    4 -
 src/arch/raw.c                          |   45 +-
 src/arch/undefined.c                    |   23 +-
 src/arch/vmpa.h                         |    4 +-
 src/format/dex/dex.c                    |    4 +-
 src/format/dex/pool.h                   |    1 +
 src/format/dwarf/v2/dwarf.h             |    3 +-
 src/format/dwarf/v3/dwarf.h             |    3 +-
 src/format/dwarf/v4/dwarf.h             |    3 +-
 src/format/elf/symbols.h                |    1 +
 src/format/format-int.h                 |    5 +-
 src/format/java/java.h                  |    2 +-
 src/format/pe/pe.h                      |    2 +-
 src/format/symbol.c                     |  221 +++-
 src/format/symbol.h                     |   12 +
 src/glibext/Makefile.am                 |    9 +-
 src/glibext/gbinportion.c               |  345 ++++--
 src/glibext/gbinportion.h               |    4 -
 src/glibext/gbuffercache.c              | 1625 ++++++++++++++++++++++++++++
 src/glibext/gbuffercache.h              |  121 +++
 src/glibext/gbufferline.c               |  176 ++-
 src/glibext/gbufferline.h               |    9 +
 src/glibext/gbufferview.c               |  810 ++++++--------
 src/glibext/gbufferview.h               |   47 +-
 src/glibext/gcodebuffer.c               | 1778 -------------------------------
 src/glibext/gcodebuffer.h               |  155 ---
 src/glibext/generator-int.h             |   52 +
 src/glibext/generators/Makefile.am      |   15 +
 src/glibext/generators/prologue.c       |  359 +++++++
 src/glibext/generators/prologue.h       |   58 +
 src/glibext/generators/rborder.c        |  361 +++++++
 src/glibext/generators/rborder.h        |   60 ++
 src/glibext/gwidthtracker.c             |   59 +-
 src/glibext/gwidthtracker.h             |   10 +-
 src/glibext/linecolumn.c                |    2 +-
 src/glibext/linegen-int.h               |   67 ++
 src/glibext/linegen.c                   |  208 ++++
 src/glibext/linegen.h                   |   68 ++
 src/glibext/linesegment.c               |    9 +
 src/glibext/linesegment.h               |    9 +-
 src/gtkext/Makefile.am                  |   29 +-
 src/gtkext/graph/cluster.c              |   48 +-
 src/gtkext/graph/cluster.h              |    4 +-
 src/gtkext/graph/edge.c                 |   27 +
 src/gtkext/graph/edge.h                 |    3 +
 src/gtkext/gtkblockdisplay.c            |  337 ++++++
 src/gtkext/gtkblockdisplay.h            |   56 +
 src/gtkext/gtkblockview.c               |  289 -----
 src/gtkext/gtkblockview.h               |   56 -
 src/gtkext/gtkbufferdisplay-int.h       |   68 ++
 src/gtkext/gtkbufferdisplay.c           | 1104 +++++++++++++++++++
 src/gtkext/gtkbufferdisplay.h           |   70 ++
 src/gtkext/gtkbufferview-int.h          |   73 --
 src/gtkext/gtkbufferview.c              | 1243 ---------------------
 src/gtkext/gtkbufferview.h              |   70 --
 src/gtkext/gtkdisplaypanel-int.h        |    6 -
 src/gtkext/gtkdisplaypanel.c            |   16 +-
 src/gtkext/gtkgraphdisplay.c            | 1226 +++++++++++++++++++++
 src/gtkext/gtkgraphdisplay.h            |   64 ++
 src/gtkext/gtkgraphview.c               | 1371 ------------------------
 src/gtkext/gtkgraphview.h               |   64 --
 src/gtkext/gtksourceview.c              |  156 ---
 src/gtkext/gtksourceview.h              |   56 -
 src/gui/dialogs/export.c                |   11 +-
 src/gui/dialogs/gotox.c                 |    3 +-
 src/gui/editem-int.h                    |    1 -
 src/gui/editem.c                        |   11 +-
 src/gui/editor.c                        |    6 +-
 src/gui/menus/edition.c                 |    1 -
 src/gui/menus/view.c                    |   75 +-
 src/gui/status.c                        |   15 +-
 src/gui/tb/Makefile.am                  |    1 -
 src/gui/tb/source.c                     |  321 ------
 src/gui/tb/source.h                     |   56 -
 src/plugins/plugin.h                    |    1 +
 121 files changed, 9163 insertions(+), 7454 deletions(-)
 create mode 100644 plugins/pychrysa/glibext/buffercache.c
 create mode 100644 plugins/pychrysa/glibext/buffercache.h
 delete mode 100644 plugins/pychrysa/glibext/codebuffer.c
 delete mode 100644 plugins/pychrysa/glibext/codebuffer.h
 create mode 100644 plugins/pychrysa/gtkext/blockdisplay.c
 create mode 100644 plugins/pychrysa/gtkext/blockdisplay.h
 delete mode 100644 plugins/pychrysa/gtkext/blockview.c
 delete mode 100644 plugins/pychrysa/gtkext/blockview.h
 create mode 100644 plugins/pychrysa/gtkext/bufferdisplay.c
 create mode 100644 plugins/pychrysa/gtkext/bufferdisplay.h
 delete mode 100644 plugins/pychrysa/gtkext/bufferview.c
 delete mode 100644 plugins/pychrysa/gtkext/bufferview.h
 create mode 100755 src/analysis/human/Makefile.am
 create mode 100755 src/analysis/human/asm/Makefile.am
 create mode 100644 src/analysis/human/asm/lang.c
 create mode 100644 src/analysis/human/asm/lang.h
 create mode 100644 src/analysis/human/lang-int.h
 create mode 100644 src/analysis/human/lang.c
 create mode 100644 src/analysis/human/lang.h
 create mode 100644 src/glibext/gbuffercache.c
 create mode 100644 src/glibext/gbuffercache.h
 delete mode 100644 src/glibext/gcodebuffer.c
 delete mode 100644 src/glibext/gcodebuffer.h
 create mode 100644 src/glibext/generator-int.h
 create mode 100644 src/glibext/generators/Makefile.am
 create mode 100644 src/glibext/generators/prologue.c
 create mode 100644 src/glibext/generators/prologue.h
 create mode 100644 src/glibext/generators/rborder.c
 create mode 100644 src/glibext/generators/rborder.h
 create mode 100644 src/glibext/linegen-int.h
 create mode 100644 src/glibext/linegen.c
 create mode 100644 src/glibext/linegen.h
 create mode 100644 src/gtkext/gtkblockdisplay.c
 create mode 100644 src/gtkext/gtkblockdisplay.h
 delete mode 100644 src/gtkext/gtkblockview.c
 delete mode 100644 src/gtkext/gtkblockview.h
 create mode 100644 src/gtkext/gtkbufferdisplay-int.h
 create mode 100644 src/gtkext/gtkbufferdisplay.c
 create mode 100644 src/gtkext/gtkbufferdisplay.h
 delete mode 100644 src/gtkext/gtkbufferview-int.h
 delete mode 100644 src/gtkext/gtkbufferview.c
 delete mode 100644 src/gtkext/gtkbufferview.h
 create mode 100644 src/gtkext/gtkgraphdisplay.c
 create mode 100644 src/gtkext/gtkgraphdisplay.h
 delete mode 100644 src/gtkext/gtkgraphview.c
 delete mode 100644 src/gtkext/gtkgraphview.h
 delete mode 100644 src/gtkext/gtksourceview.c
 delete mode 100644 src/gtkext/gtksourceview.h
 delete mode 100644 src/gui/tb/source.c
 delete mode 100644 src/gui/tb/source.h

diff --git a/ChangeLog b/ChangeLog
index 68ece4c..3130325 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,223 @@
+16-12-30  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Extend AC_CONFIG_COMMANDS. Add the new Makefiles from the
+	'src/analysis/human', 'src/analysis/human/asm' and
+	'src/glibext/generators' directories.
+
+	* plugins/Makefile.am:
+	Remove the 'androhelpers' plugin from the compilation process.
+
+	* plugins/pychrysa/analysis/binary.c:
+	Move from buffer to cache.
+
+	* plugins/pychrysa/glibext/Makefile.am:
+	Replace 'codebuffer.[ch]' by 'buffercache.[ch]' in
+	libpychrysaglibext_la_SOURCES.
+
+	* plugins/pychrysa/glibext/buffercache.c:
+	* plugins/pychrysa/glibext/buffercache.h:
+	* plugins/pychrysa/glibext/codebuffer.c:
+	* plugins/pychrysa/glibext/codebuffer.h:
+	Renamed entries.
+
+	* plugins/pychrysa/glibext/module.c:
+	Update code.
+
+	* plugins/pychrysa/gtkext/Makefile.am:
+	Replace 'blockview.[ch]' by 'blockdisplay.[ch]' and 'bufferview.[ch]'
+	by 'bufferdisplay.[ch]' in libpychrysagtkext_la_SOURCES.
+
+	* plugins/pychrysa/gtkext/blockdisplay.c:
+	* plugins/pychrysa/gtkext/blockdisplay.h:
+	* plugins/pychrysa/gtkext/blockview.c:
+	* plugins/pychrysa/gtkext/blockview.h:
+	* plugins/pychrysa/gtkext/bufferdisplay.c:
+	* plugins/pychrysa/gtkext/bufferdisplay.h:
+	* plugins/pychrysa/gtkext/bufferview.c:
+	* plugins/pychrysa/gtkext/bufferview.h:
+	Renamed entries.
+
+	* plugins/pychrysa/gtkext/module.c:
+	Update code.
+
+	* plugins/ropgadgets/select.c:
+	Print lines using the new generation interface.
+
+	* src/analysis/Makefile.am:
+	Add 'human/libanalysishuman.la' to libanalysis_la_LIBADD and 'human'
+	to SUBDIRS.
+
+	* src/analysis/binary.c:
+	* src/analysis/binary.h:
+	Move from buffer to cache. Remove the source view.
+
+	* src/analysis/content.c:
+	Typo.
+
+	* src/analysis/db/items/bookmark.c:
+	Disable the item action.
+
+	* src/analysis/db/items/comment.c:
+	* src/analysis/db/items/comment.h:
+	Print comments using the new generation interface.
+
+	* src/analysis/db/items/move.h:
+	Typo.
+
+	* src/analysis/db/items/switcher.c:
+	Disable the item action.
+
+	* src/analysis/disass/area.h:
+	* src/analysis/disass/disassembler.c:
+	* src/analysis/disass/disassembler.h:
+	* src/analysis/disass/output.c:
+	* src/analysis/disass/output.h:
+	Use the new defined generators and update the code.
+
+	* src/analysis/human/Makefile.am:
+	* src/analysis/human/asm/Makefile.am:
+	* src/analysis/human/asm/lang.c:
+	* src/analysis/human/asm/lang.h:
+	* src/analysis/human/lang-int.h:
+	* src/analysis/human/lang.c:
+	* src/analysis/human/lang.h:
+	New entries: prepare ASM-like comments.
+
+	* src/analysis/project.c:
+	Update code and remove the source view.
+
+	* src/arch/dalvik/link.c:
+	Fix code to build local comments.
+
+	* src/arch/instruction-int.h:
+	* src/arch/instruction.c:
+	* src/arch/instruction.h:
+	* src/arch/raw.c:
+	* src/arch/undefined.c:
+	Define instructions as generators.
+
+	* src/arch/vmpa.h:
+	Create is_invalid_vmpa().
+
+	* src/format/dex/dex.c:
+	* src/format/dex/pool.h:
+	* src/format/dwarf/v2/dwarf.h:
+	* src/format/dwarf/v3/dwarf.h:
+	* src/format/dwarf/v4/dwarf.h:
+	* src/format/elf/symbols.h:
+	* src/format/format-int.h:
+	* src/format/java/java.h:
+	* src/format/pe/pe.h:
+	Update code.
+
+	* src/format/symbol.c:
+	* src/format/symbol.h:
+	Define symbols as generators.
+
+	* src/glibext/Makefile.am:
+	Replace 'gcodebuffer.[ch]' by 'gbuffercache.[ch]' and add 'linegen*[ch]'
+	in libglibext_la_SOURCES. Add 'generators/libglibextgenerators.la' to
+	libglibext_la_LIBADD and 'generators' to SUBDIRS.
+
+	* src/glibext/gbinportion.c:
+	* src/glibext/gbinportion.h:
+	Define portions as generators.
+
+	* src/glibext/gbuffercache.c:
+	* src/glibext/gbuffercache.h:
+	Renamed entries.
+
+	* src/glibext/gbufferline.c:
+	* src/glibext/gbufferline.h:
+	Update code.
+
+	* src/glibext/gbufferview.c:
+	* src/glibext/gbufferview.h:
+	Rewrite the line buffers using generators and on-demand building to save
+	memory.
+
+	* src/glibext/gcodebuffer.c:
+	* src/glibext/gcodebuffer.h:
+	Renamed entries.
+
+	* src/glibext/generator-int.h:
+	* src/glibext/generators/Makefile.am:
+	* src/glibext/generators/prologue.c:
+	* src/glibext/generators/prologue.h:
+	* src/glibext/generators/rborder.c:
+	* src/glibext/generators/rborder.h:
+	New entries: provide some useful basic generators.
+
+	* src/glibext/gwidthtracker.c:
+	* src/glibext/gwidthtracker.h:
+	Update code.
+
+	* src/glibext/linecolumn.c:
+	Improve one assertion.
+
+	* src/glibext/linegen-int.h:
+	* src/glibext/linegen.c:
+	* src/glibext/linegen.h:
+	New entries: define an interface to deal with line content.
+
+	* src/glibext/linesegment.c:
+	* src/glibext/linesegment.h:
+	Extend CSS definitions.
+
+	* src/gtkext/Makefile.am:
+	Update libgtkext_la_SOURCES.
+
+	* src/gtkext/graph/cluster.c:
+	* src/gtkext/graph/cluster.h:
+	* src/gtkext/graph/edge.c:
+	* src/gtkext/graph/edge.h:
+	Update code.
+
+	* src/gtkext/gtkblockdisplay.c:
+	* src/gtkext/gtkblockdisplay.h:
+	* src/gtkext/gtkblockview.c:
+	* src/gtkext/gtkblockview.h:
+	* src/gtkext/gtkbufferdisplay-int.h:
+	* src/gtkext/gtkbufferdisplay.c:
+	* src/gtkext/gtkbufferdisplay.h:
+	* src/gtkext/gtkbufferview-int.h:
+	* src/gtkext/gtkbufferview.c:
+	* src/gtkext/gtkbufferview.h:
+	* src/gtkext/gtkdisplaypanel-int.h:
+	* src/gtkext/gtkdisplaypanel.c:
+	* src/gtkext/gtkgraphdisplay.c:
+	* src/gtkext/gtkgraphdisplay.h:
+	* src/gtkext/gtkgraphview.c:
+	* src/gtkext/gtkgraphview.h:
+	Renamed entries.
+
+	* src/gtkext/gtksourceview.c:
+	* src/gtkext/gtksourceview.h:
+	Deleted entries.
+
+	* src/gui/dialogs/export.c:
+	* src/gui/dialogs/gotox.c:
+	Disable code.
+
+	* src/gui/editem-int.h:
+	* src/gui/editem.c:
+	* src/gui/editor.c:
+	* src/gui/menus/edition.c:
+	* src/gui/menus/view.c:
+	* src/gui/status.c:
+	Update code.
+
+	* src/gui/tb/Makefile.am:
+	Remove 'source.[ch]' from libguitb_la_SOURCES.
+
+	* src/gui/tb/source.c:
+	* src/gui/tb/source.h:
+	Deleted entries.
+
+	* src/plugins/plugin.h:
+	Update code.
+
 16-12-29  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/limit.c:
diff --git a/configure.ac b/configure.ac
index d6a96b7..04be709 100644
--- a/configure.ac
+++ b/configure.ac
@@ -309,7 +309,7 @@ AC_SUBST(LIBPYGOBJECT_LIBS)
 
 AC_CONFIG_FILES([stamp-h po/Makefile.in], [echo timestamp > stamp-h])
 
-AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM" > src/glibext/chrysamarshal.list])
+AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM\nVOID:BOOLEAN,ULONG,ULONG" > src/glibext/chrysamarshal.list])
 
 AC_CONFIG_FILES([Makefile
                  pixmaps/Makefile
@@ -355,6 +355,8 @@ AC_CONFIG_FILES([Makefile
                  src/analysis/db/misc/Makefile
                  src/analysis/decomp/Makefile
                  src/analysis/disass/Makefile
+                 src/analysis/human/Makefile
+                 src/analysis/human/asm/Makefile
                  src/analysis/types/Makefile
                  src/arch/Makefile
                  src/arch/arm/Makefile
@@ -393,6 +395,7 @@ AC_CONFIG_FILES([Makefile
                  src/format/mangling/itanium/Makefile
                  src/format/pe/Makefile
                  src/glibext/Makefile
+                 src/glibext/generators/Makefile
                  src/gtkext/Makefile
                  src/gtkext/graph/Makefile
                  src/gui/Makefile
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 0500b07..9b5cd17 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -3,4 +3,5 @@ if HAVE_PYTHON3_CONFIG
     PYTHON3_SUBDIRS = pychrysa python
 endif
 
-SUBDIRS = androhelpers devdbg libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets stackvars
+# androhelpers
+SUBDIRS = devdbg libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets stackvars
diff --git a/plugins/pychrysa/analysis/binary.c b/plugins/pychrysa/analysis/binary.c
index 32e4a71..5b857d5 100644
--- a/plugins/pychrysa/analysis/binary.c
+++ b/plugins/pychrysa/analysis/binary.c
@@ -55,7 +55,7 @@ static PyObject *py_loaded_binary_get_format(PyObject *, void *);
 static PyObject *py_loaded_binary_get_processor(PyObject *, void *);
 
 /* Fournit le tampon associé au contenu assembleur d'un binaire. */
-static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *, void *);
+static PyObject *py_loaded_binary_get_disassembled_cache(PyObject *, void *);
 
 
 
@@ -234,16 +234,18 @@ static PyObject *py_loaded_binary_get_processor(PyObject *self, void *closure)
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *self, void *closure)
+static PyObject *py_loaded_binary_get_disassembled_cache(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Trouvailles à retourner     */
     GLoadedBinary *binary;                  /* Version native              */
-    GCodeBuffer *buffer;                    /* Tampon à récupérer          */
+    GBufferCache *cache;                    /* Tampon à récupérer          */
 
     binary = G_LOADED_BINARY(pygobject_get(self));
-    buffer = g_loaded_binary_get_disassembled_buffer(binary);
+    cache = g_loaded_binary_get_disassembled_cache(binary);
 
-    result = pygobject_new(G_OBJECT(buffer));
+    result = pygobject_new(G_OBJECT(cache));
+
+    g_object_unref(G_OBJECT(cache));
 
     return result;
 
@@ -288,8 +290,8 @@ PyTypeObject *get_python_loaded_binary_type(void)
             "Handler for the current binary processor.", NULL
         },
         {
-            "disassembled_buffer", py_loaded_binary_get_disassembled_buffer, NULL,
-            "Disassembled code buffer.", NULL
+            "disassembled_cache", py_loaded_binary_get_disassembled_cache, NULL,
+            "Disassembled buffer cache.", NULL
         },
         { NULL }
     };
diff --git a/plugins/pychrysa/glibext/Makefile.am b/plugins/pychrysa/glibext/Makefile.am
index 74def8a..b53f4b0 100644
--- a/plugins/pychrysa/glibext/Makefile.am
+++ b/plugins/pychrysa/glibext/Makefile.am
@@ -2,8 +2,8 @@
 noinst_LTLIBRARIES = libpychrysaglibext.la
 
 libpychrysaglibext_la_SOURCES =			\
+	buffercache.h buffercache.c			\
 	bufferline.h bufferline.c			\
-	codebuffer.h codebuffer.c			\
 	configuration.h configuration.c		\
 	module.h module.c
 
diff --git a/plugins/pychrysa/glibext/buffercache.c b/plugins/pychrysa/glibext/buffercache.c
new file mode 100644
index 0000000..c79fda2
--- /dev/null
+++ b/plugins/pychrysa/glibext/buffercache.c
@@ -0,0 +1,165 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * buffercache.c - équivalent Python du fichier "glibext/gbuffercache.h"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "buffercache.h"
+
+
+#include <pygobject.h>
+
+
+#include <glibext/gbuffercache.h>
+
+
+#include "../arch/vmpa.h"
+#include "../helpers.h"
+
+
+
+#if 0
+/* Retrouve une ligne au sein d'un tampon avec une adresse. */
+static PyObject *py_code_buffer_find_line_by_addr(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un tampon de code.                *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Retrouve une ligne au sein d'un tampon avec une adresse.     *
+*                                                                             *
+*  Retour      : Instance de la ligne trouvée.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Trouvailles à retourner     */
+    PyObject *py_vmpa;                      /* Localisation version Python */
+    int ret;                                /* Bilan de lecture des args.  */
+    vmpa2t *addr;                           /* Adresse visée par l'opérat° */
+    GBuffercache *buffer;                   /* Version native              */
+    GBufferLine *line;                      /* Ligne trouvée               */
+
+    ret = PyArg_ParseTuple(args, "O", &py_vmpa);
+    if (!ret) return NULL;
+
+    ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type());
+    if (!ret) return NULL;
+
+    addr = get_internal_vmpa(py_vmpa);
+    if (addr == NULL) return NULL;
+
+    buffer = G_CODE_BUFFER(pygobject_get(self));
+
+    line = g_code_buffer_find_line_by_addr(buffer, addr, 0, NULL);
+    if (line == NULL) Py_RETURN_NONE;
+
+    result = pygobject_new(G_OBJECT(line));
+
+    return result;
+
+}
+#endif
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_buffer_cache_type(void)
+{
+    static PyMethodDef py_buffer_cache_methods[] = {
+#if 0
+        {
+            "find_line_by_addr", (PyCFunction)py_buffer_cache_find_line_by_addr,
+            METH_VARARGS,
+            "find_line_by_addr($self, addr, /)\n--\n\nFind a buffer line with a given address."
+        },
+#endif
+        { NULL }
+    };
+
+    static PyGetSetDef py_buffer_cache_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_buffer_cache_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.glibext.Buffercache",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = "PyChrysalide code buffer",
+
+        .tp_methods     = py_buffer_cache_methods,
+        .tp_getset      = py_buffer_cache_getseters,
+
+    };
+
+    return &py_buffer_cache_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.glibext.BufferCache'.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_buffer_cache(PyObject *module)
+{
+    PyTypeObject *py_buffer_cache_type;     /* Type Python 'BufferCache'   */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_buffer_cache_type = get_python_buffer_cache_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, G_TYPE_BUFFER_CACHE, py_buffer_cache_type, &PyGObject_Type))
+        return false;
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/glibext/buffercache.h b/plugins/pychrysa/glibext/buffercache.h
new file mode 100644
index 0000000..6476f5f
--- /dev/null
+++ b/plugins/pychrysa/glibext/buffercache.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * buffercache.h - prototypes pour l'équivalent Python du fichier "glibext/buffercache.h"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_GLIBEXT_BUFFERCACHE_H
+#define _PLUGINS_PYCHRYSA_GLIBEXT_BUFFERCACHE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_buffer_cache_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.glibext.CodeBuffer'. */
+bool register_python_buffer_cache(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_GLIBEXT_BUFFERCACHE_H */
diff --git a/plugins/pychrysa/glibext/codebuffer.c b/plugins/pychrysa/glibext/codebuffer.c
deleted file mode 100644
index 7ca9435..0000000
--- a/plugins/pychrysa/glibext/codebuffer.c
+++ /dev/null
@@ -1,161 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * codebuffer.c - équivalent Python du fichier "glibext/gcodebuffer.h"
- *
- * Copyright (C) 2012 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "codebuffer.h"
-
-
-#include <pygobject.h>
-
-
-#include <glibext/gcodebuffer.h>
-
-
-#include "../arch/vmpa.h"
-#include "../helpers.h"
-
-
-
-/* Retrouve une ligne au sein d'un tampon avec une adresse. */
-static PyObject *py_code_buffer_find_line_by_addr(PyObject *, PyObject *);
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant un tampon de code.                *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Retrouve une ligne au sein d'un tampon avec une adresse.     *
-*                                                                             *
-*  Retour      : Instance de la ligne trouvée.                                *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Trouvailles à retourner     */
-    PyObject *py_vmpa;                      /* Localisation version Python */
-    int ret;                                /* Bilan de lecture des args.  */
-    vmpa2t *addr;                           /* Adresse visée par l'opérat° */
-    GCodeBuffer *buffer;                    /* Version native              */
-    GBufferLine *line;                      /* Ligne trouvée               */
-
-    ret = PyArg_ParseTuple(args, "O", &py_vmpa);
-    if (!ret) return NULL;
-
-    ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type());
-    if (!ret) return NULL;
-
-    addr = get_internal_vmpa(py_vmpa);
-    if (addr == NULL) return NULL;
-
-    buffer = G_CODE_BUFFER(pygobject_get(self));
-
-    line = g_code_buffer_find_line_by_addr(buffer, addr, 0, NULL);
-    if (line == NULL) Py_RETURN_NONE;
-
-    result = pygobject_new(G_OBJECT(line));
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Fournit un accès à une définition de type à diffuser.        *
-*                                                                             *
-*  Retour      : Définition d'objet pour Python.                              *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyTypeObject *get_python_code_buffer_type(void)
-{
-    static PyMethodDef py_code_buffer_methods[] = {
-        {
-            "find_line_by_addr", (PyCFunction)py_code_buffer_find_line_by_addr,
-            METH_VARARGS,
-            "find_line_by_addr($self, addr, /)\n--\n\nFind a buffer line with a given address."
-        },
-        { NULL }
-    };
-
-    static PyGetSetDef py_code_buffer_getseters[] = {
-        { NULL }
-    };
-
-    static PyTypeObject py_code_buffer_type = {
-
-        PyVarObject_HEAD_INIT(NULL, 0)
-
-        .tp_name        = "pychrysalide.glibext.CodeBuffer",
-        .tp_basicsize   = sizeof(PyGObject),
-
-        .tp_flags       = Py_TPFLAGS_DEFAULT,
-
-        .tp_doc         = "PyChrysalide code buffer",
-
-        .tp_methods     = py_code_buffer_methods,
-        .tp_getset      = py_code_buffer_getseters,
-
-    };
-
-    return &py_code_buffer_type;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
-*                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide.glibext.CodeBuffer'.   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool register_python_code_buffer(PyObject *module)
-{
-    PyTypeObject *py_code_buffer_type;      /* Type Python 'CodeBuffer'    */
-    PyObject *dict;                         /* Dictionnaire du module      */
-
-    py_code_buffer_type = get_python_code_buffer_type();
-
-    dict = PyModule_GetDict(module);
-
-    if (!register_class_for_pygobject(dict, G_TYPE_CODE_BUFFER, py_code_buffer_type, &PyGObject_Type))
-        return false;
-
-    return true;
-
-}
diff --git a/plugins/pychrysa/glibext/codebuffer.h b/plugins/pychrysa/glibext/codebuffer.h
deleted file mode 100644
index e806e36..0000000
--- a/plugins/pychrysa/glibext/codebuffer.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * codebuffer.h - prototypes pour l'équivalent Python du fichier "glibext/codebuffer.h"
- *
- * Copyright (C) 2012 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef _PLUGINS_PYCHRYSA_GLIBEXT_CODEBUFFER_H
-#define _PLUGINS_PYCHRYSA_GLIBEXT_CODEBUFFER_H
-
-
-#include <Python.h>
-#include <stdbool.h>
-
-
-
-/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_code_buffer_type(void);
-
-/* Prend en charge l'objet 'pychrysalide.glibext.CodeBuffer'. */
-bool register_python_code_buffer(PyObject *);
-
-
-
-#endif  /* _PLUGINS_PYCHRYSA_GLIBEXT_CODEBUFFER_H */
diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c
index 2306c44..847e6d6 100644
--- a/plugins/pychrysa/glibext/module.c
+++ b/plugins/pychrysa/glibext/module.c
@@ -28,8 +28,8 @@
 #include <assert.h>
 
 
+#include "buffercache.h"
 #include "bufferline.h"
-#include "codebuffer.h"
 #include "configuration.h"
 
 
@@ -80,8 +80,8 @@ bool add_glibext_module_to_python_module(PyObject *super)
 
     result = true;
 
+    result &= register_python_buffer_cache(module);
     result &= register_python_buffer_line(module);
-    result &= register_python_code_buffer(module);
     result &= register_python_config_param(module);
     result &= register_python_config_param_iterator(module);
     result &= register_python_generic_config(module);
diff --git a/plugins/pychrysa/gtkext/Makefile.am b/plugins/pychrysa/gtkext/Makefile.am
index e7303e8..fee2032 100644
--- a/plugins/pychrysa/gtkext/Makefile.am
+++ b/plugins/pychrysa/gtkext/Makefile.am
@@ -2,8 +2,8 @@
 noinst_LTLIBRARIES = libpychrysagtkext.la
 
 libpychrysagtkext_la_SOURCES =			\
-	blockview.h blockview.c				\
-	bufferview.h bufferview.c			\
+	blockdisplay.h blockdisplay.c		\
+	bufferdisplay.h bufferdisplay.c		\
 	displaypanel.h displaypanel.c		\
 	module.h module.c
 
diff --git a/plugins/pychrysa/gtkext/blockdisplay.c b/plugins/pychrysa/gtkext/blockdisplay.c
new file mode 100644
index 0000000..8262aa7
--- /dev/null
+++ b/plugins/pychrysa/gtkext/blockdisplay.c
@@ -0,0 +1,109 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * blockdisplay.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkblockdisplay.c"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "blockdisplay.h"
+
+
+#include <pygobject.h>
+
+
+#include <gtkext/gtkblockdisplay.h>
+
+
+#include "bufferdisplay.h"
+#include "../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_block_display_type(void)
+{
+    static PyMethodDef py_block_display_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_block_display_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_block_display_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.gtkext.BlockDisplay",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = "PyChrysalide block display.",
+
+        .tp_methods     = py_block_display_methods,
+        .tp_getset      = py_block_display_getseters
+
+    };
+
+    return &py_block_display_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.gtkext.BlockDisplay'.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_block_display(PyObject *module)
+{
+    PyTypeObject *py_block_display_type;    /* Type Python 'BlockDisplay'     */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_block_display_type = get_python_block_display_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, GTK_TYPE_BLOCK_DISPLAY,
+                                      py_block_display_type, get_python_buffer_display_type()))
+        return false;
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/gtkext/blockdisplay.h b/plugins/pychrysa/gtkext/blockdisplay.h
new file mode 100644
index 0000000..1a45e15
--- /dev/null
+++ b/plugins/pychrysa/gtkext/blockdisplay.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * blockdisplay.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkblockdisplay.h"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_GTKEXT_BLOCKDISPLAY_H
+#define _PLUGINS_PYCHRYSA_GTKEXT_BLOCKDISPLAY_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_block_display_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.gtkext.BlockDisplay'. */
+bool register_python_block_display(PyObject *module);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_GTKEXT_BLOCKDISPLAY_H */
diff --git a/plugins/pychrysa/gtkext/blockview.c b/plugins/pychrysa/gtkext/blockview.c
deleted file mode 100644
index 73095b2..0000000
--- a/plugins/pychrysa/gtkext/blockview.c
+++ /dev/null
@@ -1,108 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * blockview.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkblockview.c"
- *
- * Copyright (C) 2012 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "blockview.h"
-
-
-#include <pygobject.h>
-
-
-#include <gtkext/gtkblockview.h>
-
-
-#include "bufferview.h"
-#include "../helpers.h"
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Fournit un accès à une définition de type à diffuser.        *
-*                                                                             *
-*  Retour      : Définition d'objet pour Python.                              *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyTypeObject *get_python_block_view_type(void)
-{
-    static PyMethodDef py_block_view_methods[] = {
-        { NULL }
-    };
-
-    static PyGetSetDef py_block_view_getseters[] = {
-        { NULL }
-    };
-
-    static PyTypeObject py_block_view_type = {
-
-        PyVarObject_HEAD_INIT(NULL, 0)
-
-        .tp_name        = "pychrysalide.gtkext.BlockView",
-        .tp_basicsize   = sizeof(PyGObject),
-
-        .tp_flags       = Py_TPFLAGS_DEFAULT,
-
-        .tp_doc         = "PyChrysalide block view.",
-
-        .tp_methods     = py_block_view_methods,
-        .tp_getset      = py_block_view_getseters
-
-    };
-
-    return &py_block_view_type;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
-*                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide.gtkext.BlockView'.     *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool register_python_block_view(PyObject *module)
-{
-    PyTypeObject *py_block_view_type;       /* Type Python 'BlockView'     */
-    PyObject *dict;                         /* Dictionnaire du module      */
-
-    py_block_view_type = get_python_block_view_type();
-
-    dict = PyModule_GetDict(module);
-
-    if (!register_class_for_pygobject(dict, GTK_TYPE_BLOCK_VIEW, py_block_view_type, get_python_buffer_view_type()))
-        return false;
-
-    return true;
-
-}
diff --git a/plugins/pychrysa/gtkext/blockview.h b/plugins/pychrysa/gtkext/blockview.h
deleted file mode 100644
index acb97a9..0000000
--- a/plugins/pychrysa/gtkext/blockview.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * blockview.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkblockview.h"
- *
- * Copyright (C) 2012 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef _PLUGINS_PYCHRYSA_GTKEXT_BLOCKVIEW_H
-#define _PLUGINS_PYCHRYSA_GTKEXT_BLOCKVIEW_H
-
-
-#include <Python.h>
-#include <stdbool.h>
-
-
-
-/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_block_view_type(void);
-
-/* Prend en charge l'objet 'pychrysalide.gtkext.BlockView'. */
-bool register_python_block_view(PyObject *module);
-
-
-
-#endif  /* _PLUGINS_PYCHRYSA_GTKEXT_BLOCKVIEW_H */
diff --git a/plugins/pychrysa/gtkext/bufferdisplay.c b/plugins/pychrysa/gtkext/bufferdisplay.c
new file mode 100644
index 0000000..d26d9d9
--- /dev/null
+++ b/plugins/pychrysa/gtkext/bufferdisplay.c
@@ -0,0 +1,109 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bufferdisplay.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkbufferdisplay.c"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "bufferdisplay.h"
+
+
+#include <pygobject.h>
+
+
+#include <gtkext/gtkbufferdisplay.h>
+
+
+#include "displaypanel.h"
+#include "../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_buffer_display_type(void)
+{
+    static PyMethodDef py_buffer_display_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_buffer_display_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_buffer_display_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.gtkext.BufferDisplay",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = "PyChrysalide buffer display.",
+
+        .tp_methods     = py_buffer_display_methods,
+        .tp_getset      = py_buffer_display_getseters
+
+    };
+
+    return &py_buffer_display_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.gtkext.Bufferdisplay'. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_buffer_display(PyObject *module)
+{
+    PyTypeObject *py_buffer_display_type;   /* Type Python 'Bufferdisplay'    */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_buffer_display_type = get_python_buffer_display_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, GTK_TYPE_BUFFER_DISPLAY,
+                                      py_buffer_display_type, get_python_display_panel_type()))
+        return false;
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/gtkext/bufferdisplay.h b/plugins/pychrysa/gtkext/bufferdisplay.h
new file mode 100644
index 0000000..332f402
--- /dev/null
+++ b/plugins/pychrysa/gtkext/bufferdisplay.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bufferdisplay.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkbufferdisplay.h"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_GTKEXT_BUFFERDISPLAY_H
+#define _PLUGINS_PYCHRYSA_GTKEXT_BUFFERDISPLAY_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_buffer_display_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.gtkext.BufferDisplay'. */
+bool register_python_buffer_display(PyObject *module);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_GTKEXT_BUFFERDISPLAY_H */
diff --git a/plugins/pychrysa/gtkext/bufferview.c b/plugins/pychrysa/gtkext/bufferview.c
deleted file mode 100644
index 3be54fd..0000000
--- a/plugins/pychrysa/gtkext/bufferview.c
+++ /dev/null
@@ -1,108 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * bufferview.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkbufferview.c"
- *
- * Copyright (C) 2012 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "bufferview.h"
-
-
-#include <pygobject.h>
-
-
-#include <gtkext/gtkbufferview.h>
-
-
-#include "displaypanel.h"
-#include "../helpers.h"
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Fournit un accès à une définition de type à diffuser.        *
-*                                                                             *
-*  Retour      : Définition d'objet pour Python.                              *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyTypeObject *get_python_buffer_view_type(void)
-{
-    static PyMethodDef py_buffer_view_methods[] = {
-        { NULL }
-    };
-
-    static PyGetSetDef py_buffer_view_getseters[] = {
-        { NULL }
-    };
-
-    static PyTypeObject py_buffer_view_type = {
-
-        PyVarObject_HEAD_INIT(NULL, 0)
-
-        .tp_name        = "pychrysalide.gtkext.Bufferview",
-        .tp_basicsize   = sizeof(PyGObject),
-
-        .tp_flags       = Py_TPFLAGS_DEFAULT,
-
-        .tp_doc         = "PyChrysalide buffer view.",
-
-        .tp_methods     = py_buffer_view_methods,
-        .tp_getset      = py_buffer_view_getseters
-
-    };
-
-    return &py_buffer_view_type;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
-*                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide.gtkext.Bufferview'.    *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool register_python_buffer_view(PyObject *module)
-{
-    PyTypeObject *py_buffer_view_type;      /* Type Python 'Bufferview'    */
-    PyObject *dict;                         /* Dictionnaire du module      */
-
-    py_buffer_view_type = get_python_buffer_view_type();
-
-    dict = PyModule_GetDict(module);
-
-    if (!register_class_for_pygobject(dict, GTK_TYPE_BUFFER_VIEW, py_buffer_view_type, get_python_display_panel_type()))
-        return false;
-
-    return true;
-
-}
diff --git a/plugins/pychrysa/gtkext/bufferview.h b/plugins/pychrysa/gtkext/bufferview.h
deleted file mode 100644
index d4a1581..0000000
--- a/plugins/pychrysa/gtkext/bufferview.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * bufferview.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkbufferview.h"
- *
- * Copyright (C) 2012 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef _PLUGINS_PYCHRYSA_GTKEXT_BUFFERVIEW_H
-#define _PLUGINS_PYCHRYSA_GTKEXT_BUFFERVIEW_H
-
-
-#include <Python.h>
-#include <stdbool.h>
-
-
-
-/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_buffer_view_type(void);
-
-/* Prend en charge l'objet 'pychrysalide.gtkext.Bufferview'. */
-bool register_python_buffer_view(PyObject *module);
-
-
-
-#endif  /* _PLUGINS_PYCHRYSA_GTKEXT_BUFFERVIEW_H */
diff --git a/plugins/pychrysa/gtkext/module.c b/plugins/pychrysa/gtkext/module.c
index 2230ed0..d826814 100644
--- a/plugins/pychrysa/gtkext/module.c
+++ b/plugins/pychrysa/gtkext/module.c
@@ -28,8 +28,8 @@
 #include <assert.h>
 
 
-#include "blockview.h"
-#include "bufferview.h"
+#include "blockdisplay.h"
+#include "bufferdisplay.h"
 #include "displaypanel.h"
 
 
@@ -81,8 +81,8 @@ bool add_gtkext_module_to_python_module(PyObject *super)
     result = true;
 
     result &= register_python_display_panel(module);
-    result &= register_python_buffer_view(module);
-    result &= register_python_block_view(module);
+    result &= register_python_buffer_display(module);
+    result &= register_python_block_display(module);
 
  agmtpm_exit:
 
diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c
index 881cd39..0fedfb1 100644
--- a/plugins/ropgadgets/select.c
+++ b/plugins/ropgadgets/select.c
@@ -1746,11 +1746,7 @@ static gboolean filter_visible_rop_gadgets(GtkTreeModel *model, GtkTreeIter *ite
 
 static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *combo, GtkTreeStore *store, const char *category, GArchInstruction **gadgets, size_t count)
 {
-    const char *target;                     /* Sous-traitance requise      */
-    GArchProcessor *proc;                   /* Architecture du binaire     */
-    MemoryDataSize msize;                   /* Taille du bus d'adresses    */
     const GBinContent *content;             /* Contenu binaire global      */
-    GCodeBuffer *buffer;                    /* Tampon de rassemblement     */
     size_t i;                               /* Boucle de parcours          */
     GArchInstruction *instr;                /* Elément de liste de gadgets */
     GBufferLine *line;                      /* Ligne présente à l'adresse  */
@@ -1762,21 +1758,10 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
     char *content_markup;                   /* Contenu assemblé de chaîne  */
     GtkTreeIter iter;                       /* Point d'insertion           */
 
-    /* Définition de l'écosystème nécessaire */
-
-    target = g_exe_format_get_target_machine(format);
-    proc = get_arch_processor_for_type(target);
-
-    msize = g_arch_processor_get_memory_size(proc);
-
-    g_object_unref(G_OBJECT(proc));
-
     content = g_binary_format_get_content(G_BIN_FORMAT(format));
 
     /* Conversion en contenu textuel */
 
-    buffer = g_code_buffer_new(BLC_ASSEMBLY);
-
     for (i = 0; i < count; i++)
     {
         /* Parcours des différentes lignes */
@@ -1788,8 +1773,8 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
 
         for (instr = gadgets[i]; instr != NULL; instr = g_arch_instruction_get_next_iter(gadgets[i], instr, ~0))
         {
-            line = g_arch_instruction_print(instr, buffer, msize, content, ASX_INTEL);
-            if (line == NULL) continue;
+            line = g_buffer_line_new(NULL, BLC_ASSEMBLY);
+            g_line_generator_print(G_LINE_GENERATOR(instr), line, -1, 0);
 
             if (instr == gadgets[i])
             {
@@ -1800,6 +1785,8 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
             partial_raw = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, false);
             partial_markup = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true);
 
+            g_object_unref(G_OBJECT(line));
+
             if (content_raw != NULL)
                 content_raw = stradd(content_raw, " ; ");
 
@@ -1836,8 +1823,6 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
 
     }
 
-    g_object_unref(G_OBJECT(buffer));
-
     g_object_unref(G_OBJECT(content));
 
     /* Rajout de la catégorie et filtre au besoin */
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am
index 8b346f9..a8b1538 100755
--- a/src/analysis/Makefile.am
+++ b/src/analysis/Makefile.am
@@ -20,6 +20,7 @@ libanalysis_la_LIBADD =					\
 	db/libanalysisdb.la					\
 	db/libanalysiskeys.la				\
 	disass/libanalysisdisass.la			\
+	human/libanalysishuman.la			\
 	types/libanalysistypes.la
 
 #	decomp/libanalysisdecomp.la
@@ -31,4 +32,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = blocks contents db disass types
+SUBDIRS = blocks contents db disass human types
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 3af62cf..ac8863e 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -37,7 +37,7 @@
 
 #include "routine.h"
 #include "db/client.h"
-#include "decomp/decompiler.h"
+//#include "decomp/decompiler.h"
 #include "disass/disassembler.h"
 #include "../common/extstr.h"
 #include "../common/cpp.h"
@@ -78,8 +78,9 @@ struct _GLoadedBinary
     GDbgFormat *debug;                      /* Informations de débogage    */ //// REMME
     GArchProcessor *proc;                   /* Architecture du binaire     */
 
-    GCodeBuffer *disass_buffer;             /* Instructions lisibles       */
-    GCodeBuffer **dec_buffers;              /* Sources sous forme de texte */
+
+    GBufferCache *disass_cache;             /* Instructions lisibles       */
+    //GCodeBuffer **dec_buffers;              /* Sources sous forme de texte */
     size_t decbuf_count;                    /* Taille des tableaux         */
     size_t defsrc;                          /* Fichier source principal    */
 
@@ -220,9 +221,6 @@ static void g_loaded_binary_init(GLoadedBinary *binary)
     binary->col_display[BVW_GRAPH][BLC_PHYSICAL] = false;
     binary->col_display[BVW_GRAPH][BLC_VIRTUAL] = false;
     binary->col_display[BVW_GRAPH][BLC_BINARY] = false;
-    binary->col_display[BVW_SOURCE][BLC_PHYSICAL] = false;
-    binary->col_display[BVW_SOURCE][BLC_VIRTUAL] = false;
-    binary->col_display[BVW_SOURCE][BLC_BINARY] = false;
 
     binary->lines_display = true;
 
@@ -1377,7 +1375,7 @@ void g_loaded_binary_analyse(GLoadedBinary *binary)
     g_loaded_binary_connect_internal(binary);
 
 
-    disassemble_binary(binary, &binary->disass_buffer, ack_completed_disassembly);
+    disassemble_binary(binary, &binary->disass_cache, ack_completed_disassembly);
 
 
 
@@ -1508,9 +1506,16 @@ GArchProcessor *g_loaded_binary_get_processor(const GLoadedBinary *binary)
 *                                                                             *
 ******************************************************************************/
 
-GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary)
+GBufferCache *g_loaded_binary_get_disassembled_cache(const GLoadedBinary *binary)
 {
-    return binary->disass_buffer;
+    GBufferCache *result;                   /* Instance à retourner        */
+
+    result = binary->disass_cache;
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
 
 }
 
@@ -1527,7 +1532,7 @@ GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
-
+#if 0
 GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *binary, size_t index)
 {
     GCodeBuffer *result;                    /* Tampon à retourner          */
@@ -1544,6 +1549,7 @@ GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *binary,
     return result;
 
 }
+#endif
 
 
 /******************************************************************************
@@ -1659,6 +1665,7 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binar
     files = g_binary_format_get_source_files(G_BIN_FORMAT(binary->format),
                                              &binary->decbuf_count, &binary->defsrc);
 
+#if 0
     if (binary->decbuf_count > 0)
     {
         binary->dec_buffers = (GCodeBuffer **)calloc(binary->decbuf_count, sizeof(GCodeBuffer *));
@@ -1668,7 +1675,7 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binar
             binary->dec_buffers[i] = decompile_all_from_file(binary, files[i]);
         */
     }
-
+#endif
 
 
 
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 41c7f7a..501ffe6 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -36,7 +36,7 @@
 #include "../common/xml.h"
 #include "../format/debuggable.h"
 #include "../format/executable.h"
-#include "../glibext/gcodebuffer.h"
+#include "../glibext/gbuffercache.h"
 
 
 
@@ -76,7 +76,6 @@ typedef enum _BinaryView
 {
     BVW_BLOCK,                              /* Version basique             */
     BVW_GRAPH,                              /* Affichage en graphique      */
-    BVW_SOURCE,                             /* Code décompilé              */
 
     BVW_COUNT
 
@@ -181,10 +180,10 @@ GExeFormat *g_loaded_binary_get_format(const GLoadedBinary *);
 GArchProcessor *g_loaded_binary_get_processor(const GLoadedBinary *);
 
 /* Fournit le tampon associé au contenu assembleur d'un binaire. */
-GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *);
+GBufferCache *g_loaded_binary_get_disassembled_cache(const GLoadedBinary *);
 
 /* Fournit le tampon associé au contenu d'un fichier source. */
-GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *, size_t);
+//GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *, size_t);
 
 /* Définit si une colonne donnée doit apparaître dans le rendu. */
 void g_loaded_binary_set_column_display(GLoadedBinary *, BinaryView, BufferLineColumn, bool);
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 484599f..09f293c 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -47,7 +47,7 @@ G_DEFINE_INTERFACE(GBinContent, g_binary_content, G_TYPE_OBJECT)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : iface = interface GTK à initialiser.                         *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
 *                                                                             *
 *  Description : Procède à l'initialisation de l'interface de rassemblement.  *
 *                                                                             *
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 086b9f2..18e4bb5 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -409,6 +409,8 @@ static void g_db_bookmark_build_label(GDbBookmark *bookmark)
 
 static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool *prev, bool set)
 {
+    return false;
+#if 0
     bool result;                            /* Bilan à faire remonter      */
     GCodeBuffer *buffer;                    /* Tampon de lignes à traiter  */
     GBufferLine *line;                      /* Ligne de tampon à marquer   */
@@ -437,7 +439,7 @@ static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool
  exit:
 
     return result;
-
+#endif
 }
 
 
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 55893d1..3517f38 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -35,7 +35,10 @@
 
 #include "../collection-int.h"
 #include "../item-int.h"
+#include "../../human/asm/lang.h"
 #include "../../../common/io.h"
+#include "../../../common/extstr.h"
+#include "../../../glibext/linegen-int.h"
 
 
 
@@ -52,6 +55,9 @@ struct _GDbComment
 
     rle_string text;                        /* Contenu du commentaire      */
 
+    char **lines;                           /* Lignes brutes à représenter */
+    size_t count;                           /* Quantité de ces lignes      */
+
     bool inlined;                           /* Intégration dans une ligne ?*/
 
     union
@@ -60,7 +66,9 @@ struct _GDbComment
         bool before;                        /* Zone dédiée au dessus ?     */
     };
 
-    GDbComment **oldies;                    /* Commentaires d'origine ?    */
+    GLineGenerator *previous;               /* Commentaire remplacé        */
+
+    GLineGenerator **old_inlined;           /* Commentaires d'origine ?    */
     size_t old_count;                       /* Nombre de places à restaurer*/
 
 };
@@ -112,6 +120,29 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *, bound_value **
 /* Charge les valeurs utiles pour un commentaire. */
 static bool g_db_comment_load(GDbComment *, const bound_value *, size_t);
 
+/* Définit le commentaire associé à un commentaire. */
+static void g_db_comment_set_text(GDbComment *, const char *);
+
+
+
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_db_comment_count_lines(const GDbComment *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_db_comment_compute_addr(const GDbComment *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_db_comment_contains_addr(const GDbComment *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_db_comment_get_flags(const GDbComment *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_db_comment_print(GDbComment *, GBufferLine *, size_t, size_t);
+
 
 
 /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
@@ -138,6 +169,9 @@ static void g_comment_collection_class_init(GCommentCollectionClass *);
 /* Initialise un commentaire sous forme de zone de texte. */
 static void g_comment_collection_init(GCommentCollection *);
 
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_db_comment_interface_init(GLineGeneratorInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_comment_collection_dispose(GCommentCollection *);
 
@@ -161,7 +195,8 @@ static GDbItem *g_comment_collection_has_key(GCommentCollection *, va_list);
 
 
 /* Indique le type défini pour un commentaire à l'intérieur d'une zone de texte. */
-G_DEFINE_TYPE(GDbComment, g_db_comment, G_TYPE_DB_ITEM);
+G_DEFINE_TYPE_WITH_CODE(GDbComment, g_db_comment, G_TYPE_DB_ITEM,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_db_comment_interface_init));
 
 
 /******************************************************************************
@@ -219,6 +254,31 @@ static void g_db_comment_class_init(GDbCommentClass *klass)
 
 static void g_db_comment_init(GDbComment *comment)
 {
+    comment->lines = NULL;
+    comment->count = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_comment_interface_init(GLineGeneratorInterface *iface)
+{
+    iface->count = (linegen_count_lines_fc)g_db_comment_count_lines;
+    iface->compute = (linegen_compute_fc)g_db_comment_compute_addr;
+    iface->contains = (linegen_contains_fc)g_db_comment_contains_addr;
+    iface->get_flags = (linegen_get_flags_fc)g_db_comment_get_flags;
+    iface->print = (linegen_print_fc)g_db_comment_print;
 
 }
 
@@ -239,11 +299,17 @@ static void g_db_comment_dispose(GDbComment *comment)
 {
     size_t i;                               /* Boucle de parcours          */
 
+    for (i = 0; i < comment->count; i++)
+        free(comment->lines[i]);
+
+    if (comment->lines != NULL)
+        free(comment->lines);
+
     for (i = 0; i < comment->old_count; i++)
-        g_object_unref(G_OBJECT(comment->oldies[i]));
+        g_object_unref(G_OBJECT(comment->old_inlined[i]));
 
-    if (comment->oldies != NULL)
-        free(comment->oldies);
+    if (comment->old_inlined != NULL)
+        free(comment->old_inlined);
 
     G_OBJECT_CLASS(g_db_comment_parent_class)->dispose(G_OBJECT(comment));
 
@@ -516,6 +582,134 @@ static void g_db_comment_build_label(GDbComment *comment)
 static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool apply)
 {
     bool result;                            /* Bilan à faire remonter      */
+    GBufferCache *cache;                    /* Ensemble de lignes à traiter*/
+    size_t index;                           /* Point d'insertion           */
+    GArchProcessor *proc;                   /* Propriétaire d'instructions */
+    GArchInstruction *instr;                /* Instruction à traiter       */
+    instr_link_t *sources;                  /* Instructions diverses liées */
+    size_t scount;                          /* Nbre de sources affichées   */
+    size_t i;                               /* Boucle de parcours          */
+    const mrange_t *range;                  /* Emplacement d'instruction   */
+    size_t linked;                          /* Indice lié à traiter        */
+
+    result = true;
+
+    cache = g_loaded_binary_get_disassembled_cache(binary);
+
+    index = g_buffer_cache_find_index_by_addr(cache, &comment->addr, true);
+
+    index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
+
+    if (comment->inlined)
+    {
+
+#define RUN_INLINED_COMMENT(idx, new, old)                                                      \
+        if (apply)                                                                              \
+        {                                                                                       \
+            old = g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false);   \
+                                                                                                \
+            g_buffer_cache_insert_at(cache, idx, G_LINE_GENERATOR(new), false, false);          \
+                                                                                                \
+        }                                                                                       \
+        else                                                                                    \
+        {                                                                                       \
+            g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false);         \
+                                                                                                \
+            if (old != NULL)                                                                    \
+            {                                                                                   \
+                g_buffer_cache_insert_at(cache, idx, old, false, false);                        \
+                g_object_unref(G_OBJECT(old));                                                  \
+            }                                                                                   \
+                                                                                                \
+        }
+
+        /* Commentaire principal */
+
+        RUN_INLINED_COMMENT(index, comment, comment->previous);
+
+        /* Renvois répétés */
+
+        if (comment->repeatable)
+        {
+            proc = g_loaded_binary_get_processor(binary);
+
+            instr = g_arch_processor_find_instr_by_address(proc, &comment->addr);
+            assert(instr != NULL);
+
+            scount = g_arch_instruction_get_sources(instr, &sources);
+
+            if (apply)
+            {
+                comment->old_count = scount;
+                comment->old_inlined = (GLineGenerator **)realloc(comment->old_inlined,
+                                                                  comment->old_count * sizeof(GLineGenerator *));
+            }
+
+            for (i = 0; i < scount && result; i++)
+            {
+                range = g_arch_instruction_get_range(sources[i].linked);
+
+                /**
+                 * On recherche ici une ligne potentiellement BLF_HAS_CODE ou BLF_IS_LABEL.
+                 * Comme on ne peut pas traiter les deux cas, on prend la première qui vient
+                 * avec BLF_NONE.
+                 */
+
+                linked = g_buffer_cache_find_index_by_addr(cache, get_mrange_addr(range), true);
+                assert(linked != g_buffer_cache_count_lines(cache));
+
+                RUN_INLINED_COMMENT(linked, comment, comment->old_inlined[i]);
+
+            }
+
+            if (!apply)
+            {
+                free(comment->old_inlined);
+
+                comment->old_inlined = NULL;
+                comment->old_count = 0;
+
+            }
+
+            g_object_unref(G_OBJECT(proc));
+
+        }
+
+
+
+    }
+
+    else
+    {
+
+
+
+
+
+
+
+
+
+    }
+
+
+    //void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, bool before, bool after)
+
+    //GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after)
+
+
+
+
+    g_object_unref(G_OBJECT(cache));
+
+    return result;
+
+
+
+
+#if 0
+
+    bool result;                            /* Bilan à faire remonter      */
     GCodeBuffer *buffer;                    /* Tampon de lignes à traiter  */
     GBufferLine *line;                      /* Ligne de tampon à marquer   */
     GArchProcessor *proc;                   /* Propriétaire d'instructions */
@@ -658,7 +852,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
     /* TODO g_object_unref(G_OBJECT(buffer));*/
 
     return result;
-
+#endif
 }
 
 
@@ -884,10 +1078,137 @@ const char *g_db_comment_get_text(const GDbComment *comment)
 *                                                                             *
 ******************************************************************************/
 
-void g_db_comment_set_text(GDbComment *comment, const char *text)
+static void g_db_comment_set_text(GDbComment *comment, const char *text)
 {
+    GCodingLanguage *lang;                  /* Langage de sortie préféré   */
+
     set_rle_string(&comment->text, text);
 
+    lang = g_asm_language_new();
+
+    comment->lines = strtoka(text, "\n", &comment->count);
+
+    g_coding_language_encapsulate_comments(lang, &comment->lines, &comment->count);
+
+    g_object_unref(G_OBJECT(lang));
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          OFFRE DE CAPACITES DE GENERATION                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = générateur à consulter.                            *
+*                                                                             *
+*  Description : Indique le nombre de ligne prêtes à être générées.           *
+*                                                                             *
+*  Retour      : Nombre de lignes devant apparaître au final.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t g_db_comment_count_lines(const GDbComment *comment)
+{
+    return comment->count;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = générateur à consulter.                            *
+*                x       = position géographique sur la ligne concernée.      *
+*                addr    = position en mémoire à analyser.                    *
+*                index   = indice de cette même ligne dans le tampon global.  *
+*                repeat  = indice d'utilisations successives du générateur.   *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_comment_compute_addr(const GDbComment *comment, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+    copy_vmpa(addr, &comment->addr);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = générateur à consulter.                            *
+*                addr    = position en mémoire à analyser.                    *
+*                index   = indice de cette même ligne dans le tampon global.  *
+*                repeat  = indice d'utilisations successives du générateur.   *
+*                                                                             *
+*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
+*                                                                             *
+*  Retour      : Bilan de la détermination, utilisable en comparaisons.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int g_db_comment_contains_addr(const GDbComment *comment, const vmpa2t *addr, size_t index, size_t repeat)
+{
+    int result;                             /* Conclusion à retourner      */
+
+    result = cmp_vmpa(addr, &comment->addr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = générateur à consulter.                            *
+*                index   = indice de cette même ligne dans le tampon global.  *
+*                repeat  = indice d'utilisations successives du générateur.   *
+*                                                                             *
+*  Description : Renseigne sur les propriétés liées à un générateur.          *
+*                                                                             *
+*  Retour      : Propriétés particulières associées.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static BufferLineFlags g_db_comment_get_flags(const GDbComment *comment, size_t index, size_t repeat)
+{
+    return BLF_NONE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = générateur à utiliser pour l'impression.           *
+*                line    = ligne de rendu à compléter.                        *
+*                index   = indice de cette même ligne dans le tampon global.  *
+*                repeat  = indice d'utilisations successives du générateur.   *
+*                                                                             *
+*  Description : Imprime dans une ligne de rendu le contenu représenté.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_comment_print(GDbComment *comment, GBufferLine *line, size_t index, size_t repeat)
+{
+    g_buffer_line_append_text(line, BLC_COMMENTS, SL(comment->lines[repeat]), RTT_COMMENT, NULL);
+
 }
 
 
diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h
index c5bd335..16046bc 100644
--- a/src/analysis/db/items/comment.h
+++ b/src/analysis/db/items/comment.h
@@ -69,15 +69,6 @@ const vmpa2t *g_db_comment_get_address(GDbComment *);
 /* Fournit le commentaire associé à un commentaire. */
 const char *g_db_comment_get_text(const GDbComment *);
 
-/* Définit le commentaire associé à un commentaire. */
-void g_db_comment_set_text(GDbComment *, const char *);
-
-
-
-
-
-
-
 
 
 /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
diff --git a/src/analysis/db/items/move.h b/src/analysis/db/items/move.h
index a9d6d8d..115bdc8 100644
--- a/src/analysis/db/items/move.h
+++ b/src/analysis/db/items/move.h
@@ -96,4 +96,4 @@ GMoveCollection *g_move_collection_new(void);
 
 
 
-#endif  /* _ANALYSIS_DB_ITEMS_SWITCH_H */
+#endif  /* _ANALYSIS_DB_ITEMS_MOVE_H */
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 748c934..3d5841c 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -496,6 +496,9 @@ static void g_db_switcher_build_label(GDbSwitcher *switcher)
 
 static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmOperandDisplay *old, ImmOperandDisplay new)
 {
+    return false;
+
+#if 0
     bool result;                            /* Bilan à faire remonter      */
     GArchProcessor *proc;                   /* Propriétaire d'instructions */
     GArchInstruction *instr;                /* Instruction à traiter       */
@@ -568,7 +571,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
     g_object_unref(G_OBJECT(proc));
 
     return result;
-
+#endif
 }
 
 
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index d5f910b..155db7c 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -28,6 +28,7 @@
 #include "../binary.h"
 #include "../../arch/instruction.h"
 #include "../../format/symbol.h"
+#include "../../glibext/delayed.h"
 #include "../../gtkext/gtkstatusstack.h"
 
 
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 5326c36..246a5b2 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -39,11 +39,16 @@
 #include "routines.h"
 #include "../../format/format.h"
 #include "../../glibext/delayed-int.h"
+#include "../../glibext/generators/prologue.h"
 #include "../../gui/panels/log.h"
 #include "../../plugins/pglist.h"
 
 
 
+#include "../human/asm/lang.h" // TODO : REMME -> format !
+
+
+
 /* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
 
 
@@ -54,8 +59,9 @@ struct _GDelayedDisassembly
 
     GLoadedBinary *binary;                  /* Destinataire final          */
     GExeFormat *format;                     /* Format du binaire représenté*/
+    GCodingLanguage *lang;                  /* Traduction en ASM préférée  */
 
-    GCodeBuffer *buffer;                    /* Tampon pour le rendu        */
+    GBufferCache *cache;                    /* Tampon pour le rendu        */
 
 };
 
@@ -80,7 +86,7 @@ static void g_delayed_disassembly_dispose(GDelayedDisassembly *);
 static void g_delayed_disassembly_finalize(GDelayedDisassembly *);
 
 /* Crée une tâche de désassemblage différé. */
-static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GCodeBuffer *);
+static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GBufferCache *);
 
 /* Opère sur toutes les instructions. */
 static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GProcContext *, GExeFormat *);
@@ -97,7 +103,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkStatusStack
 
 
 /* Construit la description d'introduction du désassemblage. */
-static void build_disass_prologue(GCodeBuffer *, const char *, const char *);
+static void build_disass_prologue(GBufferCache *, const GCodingLanguage *, const char *, const char *);
 
 
 
@@ -172,6 +178,7 @@ static void g_delayed_disassembly_init(GDelayedDisassembly *disass)
 static void g_delayed_disassembly_dispose(GDelayedDisassembly *disass)
 {
     g_object_unref(G_OBJECT(disass->format));
+    g_object_unref(G_OBJECT(disass->lang));
 
     G_OBJECT_CLASS(g_delayed_disassembly_parent_class)->dispose(G_OBJECT(disass));
 
@@ -211,7 +218,7 @@ static void g_delayed_disassembly_finalize(GDelayedDisassembly *disass)
 *                                                                             *
 ******************************************************************************/
 
-static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GCodeBuffer *buffer)
+static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GBufferCache *cache)
 {
     GDelayedDisassembly *result;            /* Tâche à retourner           */
 
@@ -219,8 +226,9 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GCo
 
     result->binary = binary;
     result->format = g_loaded_binary_get_format(binary);
+    result->lang = g_asm_language_new();
 
-    result->buffer = buffer;
+    result->cache = cache;
 
     return result;
 
@@ -568,7 +576,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
 
 
 
-    print_disassembled_instructions(disass->buffer, disass->format, proc, status);
+    print_disassembled_instructions(disass->cache, disass->lang, disass->binary, status);
 
 
 
@@ -612,10 +620,10 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : buffer   = tampon de destination pour le texte.              *
+*  Paramètres  : cache    = tampon de destination pour le texte.              *
+*                lang     = trauducteur pour l'impression finale.             *
 *                filename = nom du fichier ciblé à décompiler.                *
-*                data     = données en mémoire pour l'empreinte.              *
-*                length   = quantité de données à prendre en compte.          *
+*                checksum = empreinte identifiant le binaire chargé.          *
 *                                                                             *
 *  Description : Construit la description d'introduction du désassemblage.    *
 *                                                                             *
@@ -625,96 +633,32 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
 *                                                                             *
 ******************************************************************************/
 
-static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, const char *checksum)
+static void build_disass_prologue(GBufferCache *cache, const GCodingLanguage *lang, const char *filename, const char *checksum)
 {
-#if 0
-    GLangOutput *output;                    /* Modèle de sortie adéquat    */
-    GBufferLine *line;                      /* Ligne de destination        */
-    bool managed;                           /* Groupe déjà défini ?        */
-    size_t len;                             /* Taille du texte             */
-    char *content;                          /* Contenu textuel d'une ligne */
-
-    output = g_asm_output_new();
+    char **text;                            /* Contenu brute à imprimer    */
+    GIntroGenerator *generator;             /* Générateur constitué        */
 
-    line = g_lang_output_start_comments(output, buffer);
-    if (line != NULL)
-    {
-        g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-        g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
-
-        g_code_buffer_append_new_line(buffer, line);
-
-    }
-
-    managed = (line != NULL);
+    text = calloc(4, sizeof(char *));
 
     /* Introduction */
 
-    line = g_lang_output_continue_comments(output, buffer,
-                                           SL(_("Disassembly generated by Chrysalide")));
-    g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
-    if (!managed)
-        g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
-
-    g_code_buffer_append_new_line(buffer, line);
-
-    line = g_lang_output_continue_comments(output, buffer,
-                                           SL(_("Chrysalide is free software - © 2008-2015 Cyrille Bagard")));
-    g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
-    g_code_buffer_append_new_line(buffer, line);
-
-    line = g_lang_output_continue_comments(output, buffer, NULL, 0);
-    g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
-    g_code_buffer_append_new_line(buffer, line);
+    text[0] = strdup(_("Disassembly generated by Chrysalide"));
+    text[1] = strdup(_("Chrysalide is free software - © 2008-2016 Cyrille Bagard"));
 
     /* Fichier */
 
-    len = strlen(_("File: ")) + strlen(filename) + 1;
-    content = (char *)calloc(len, sizeof(char));
-
-    snprintf(content, len, "%s%s", _("File: "), filename);
-
-    line = g_lang_output_continue_comments(output, buffer, content, len - 1);
-    g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
-    g_code_buffer_append_new_line(buffer, line);
-
-    free(content);
+    asprintf(&text[2], "%s%s", _("File: "), filename);
 
     /* Checksum SHA256 */
 
-    len = strlen(_("Sha256: ")) + strlen(checksum);
-    content = (char *)calloc(len + 1, sizeof(char));
-
-    snprintf(content, len + 1, "%s%s", _("Sha256: "), checksum);
-
-    line = g_lang_output_continue_comments(output, buffer, content, len - 1);
-    g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-
-    g_code_buffer_append_new_line(buffer, line);
+    asprintf(&text[3], "%s%s", _("Sha256: "), checksum);
 
-    free(content);
+    /* Intégration finale */
 
-    /* Ligne de séparation */
+    generator = g_intro_generator_new(lang, text, 4);
 
-    line = g_lang_output_continue_comments(output, buffer, NULL, 0);
-    g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-    g_code_buffer_append_new_line(buffer, line);
+    g_buffer_cache_append(cache, G_LINE_GENERATOR(generator), BLF_NONE);
 
-    /* Conclusion */
-
-    line = g_lang_output_end_comments(output, buffer);
-    if (line != NULL)
-    {
-        g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
-        g_code_buffer_append_new_line(buffer, line);
-    }
-
-    g_object_unref(G_OBJECT(output));
-#endif
 }
 
 
@@ -724,7 +668,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
 *                parts  = parties binaires à désassembler.                    *
 *                count  = nombre de parties à traiter.                        *
 *                instrs = liste des instructions chargées. [OUT]              *
-*                buffer = tampon de code mis en place. [OUT]                  *
+*                cache  = tampon de code mis en place. [OUT]                  *
 *                ack    = fonction à appeler une fois l'opération terminée.   *
 *                                                                             *
 *  Description : Procède au désassemblage d'un contenu binaire donné.         *
@@ -735,30 +679,35 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
 *                                                                             *
 ******************************************************************************/
 
-void disassemble_binary(GLoadedBinary *binary, GCodeBuffer **buffer, disassembly_ack_fc ack)
+void disassemble_binary(GLoadedBinary *binary, GBufferCache **cache, disassembly_ack_fc ack)
 {
     GBinFormat *format;                     /* Format associé au binaire   */
+    GCodingLanguage *lang;                  /* Langage de sortie préféré   */
     GBinContent *content;                   /* Contenu bianire manipulé    */
     const gchar *checksum;                  /* Identifiant de binaire      */
     GDelayedDisassembly *disass;            /* Désassemblage à mener       */
     GWorkQueue *queue;                      /* Gestionnaire de différés    */
 
-    *buffer = g_code_buffer_new(BLC_ASSEMBLY);
+    *cache = g_buffer_cache_new();
 
     format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
 
+    lang = g_asm_language_new();
+
     content = g_binary_format_get_content(format);
     checksum = g_binary_content_get_checksum(content);
     g_object_unref(G_OBJECT(content));
 
     g_object_unref(G_OBJECT(format));
 
-    build_disass_prologue(*buffer, g_binary_content_describe(content, true), checksum);
+    build_disass_prologue(*cache, lang, g_binary_content_describe(content, true), checksum);
 
-    disass = g_delayed_disassembly_new(binary, *buffer);
+    disass = g_delayed_disassembly_new(binary, *cache);
     g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary);
 
     queue = get_work_queue();
     g_work_queue_schedule_work(queue, G_DELAYED_WORK(disass), DEFAULT_WORK_GROUP);
 
+    g_object_unref(G_OBJECT(lang));
+
 }
diff --git a/src/analysis/disass/disassembler.h b/src/analysis/disass/disassembler.h
index 9151d23..20c7bdd 100644
--- a/src/analysis/disass/disassembler.h
+++ b/src/analysis/disass/disassembler.h
@@ -59,7 +59,7 @@ GType g_delayed_disassembly_get_type(void);
 typedef void (* disassembly_ack_fc) (GDelayedDisassembly *, GLoadedBinary *);
 
 /* Procède à la décompilation des routines d'un fichier donné. */
-void disassemble_binary(GLoadedBinary *, GCodeBuffer **, disassembly_ack_fc);
+void disassemble_binary(GLoadedBinary *, GBufferCache **, disassembly_ack_fc);
 
 
 
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index fe4d705..6c044be 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -27,27 +27,18 @@
 #include <i18n.h>
 
 
-#include "../../arch/processor.h"
-#include "../../common/extstr.h"
 #include "../../format/format.h"
+#include "../../glibext/generators/rborder.h"
 #include "../../gui/panels/log.h"
 
 
 
-#define ROUTINE_INTRO_MSG "; --------------- BEGIN OF PROCEDURE ---------------"
-
-#define ROUTINE_OUTRO_MSG "; ---------------- END OF PROCEDURE ----------------"
-
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : buffer   = tampon de récueil des résultats d'impression.     *
-*                format   = format du binaire traité.                         *
-*                instrs   = ensemble d'instructions à traiter.                *
-*                routines = liste de routines intervenant dans le flot.       *
-*                count    = quantité de ces routines.                         *
-*                status   = barre de statut avec progression à mettre à jour. *
+*  Paramètres  : cache  = tampon de récueil des résultats d'impression.       *
+*                lang   = langage de haut niveau préféré pour l'impression.   *
+*                binary = tampon de récueil des résultats d'impression.       *
+*                status = barre de statut avec progression à mettre à jour.   *
 *                                                                             *
 *  Description : Transcrit du code désassemblé en texte humainement lisible.  *
 *                                                                             *
@@ -57,8 +48,10 @@
 *                                                                             *
 ******************************************************************************/
 
-void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GArchProcessor *proc, GtkStatusStack *status)
+void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, GLoadedBinary *binary, GtkStatusStack *status)
 {
+    GExeFormat *format;                     /* Format associé au binaire   */
+    GArchProcessor *proc;                   /* Processeur de l'architecture*/
     GBinPortion *root;                      /* Couche première de portions */
     GBinPortion **portions;                 /* Morceaux d'encadrement      */
     size_t portions_count;                  /* Taille de cette liste       */
@@ -74,22 +67,21 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
     size_t i;                               /* Boucle de parcours          */
     GArchInstruction *instr;                /* Instruction à traiter       */
     const vmpa2t *iaddr;                    /* Adresse d'instruction       */
-    vmpa2t outro_addr;                      /* Adresse de fin de code      */
-    GBufferLine *line;
+    GBorderGenerator *border;               /* Délimitation de routine     */
     const vmpa2t *paddr;                    /* Adresse de portion          */
+    GLineGenerator *generator;              /* Générateur de contenu ajouté*/
     const vmpa2t *saddr;                    /* Adresse de symbole          */
     int compared;                           /* Bilan d'une comparaison     */
     SymbolType stype;                       /* Type de symbole trouvé      */
-    const char *label;                      /* Etiquette ciblant un symbole*/
-    mrange_t range;                         /* Couverture sans surface     */
+    vmpa2t intro_addr;                      /* Adresse de début de code    */
+    vmpa2t outro_addr;                      /* Adresse de fin de code      */
+    BufferLineFlags flags;                  /* Propriétés pour la ligne    */
+    //mrange_t range;                         /* Couverture sans surface     */
 
     GDbComment *comment;                    /* Commentaire à ajouter       */
 
 
 
-    const char *text;
-
-    char *prefixed;
 
 
 
@@ -98,6 +90,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
 
 
 
+    format = g_loaded_binary_get_format(binary);
+    proc = g_loaded_binary_get_processor(binary);
 
     bool collect_all_portions(GBinPortion *portion, GBinPortion *parent, BinaryPortionVisit visit, void *unused)
     {
@@ -149,29 +143,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
         {
             expect_outro = false;
 
-            init_mrange(&range, &outro_addr, 0);
-
-            line = g_code_buffer_prepare_new_line(buffer, &range);
-            g_buffer_line_add_flag(line, BLF_IS_LABEL);
-            g_buffer_line_fill_mrange(line, msize, msize);
-
-            g_code_buffer_append_new_line(buffer, line);
-
-            line = g_code_buffer_prepare_new_line(buffer, &range);
-            g_buffer_line_add_flag(line, BLF_IS_LABEL);
-            g_buffer_line_fill_mrange(line, msize, msize);
-
-            g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-            g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD,
-                                      ROUTINE_OUTRO_MSG, strlen(ROUTINE_OUTRO_MSG), RTT_COMMENT, NULL);
-
-            g_code_buffer_append_new_line(buffer, line);
-
-            line = g_code_buffer_prepare_new_line(buffer, &range);
-            g_buffer_line_add_flag(line, BLF_IS_LABEL);
-            g_buffer_line_fill_mrange(line, msize, msize);
-
-            g_code_buffer_append_new_line(buffer, line);
+            border = g_border_generator_new(lang, &outro_addr, false, msize);
+            g_buffer_cache_append(cache, G_LINE_GENERATOR(border), BLF_NONE);
 
         }
 
@@ -184,7 +157,11 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
             if (cmp_vmpa_by_phy(iaddr, paddr) != 0)
                 break;
 
-            g_binary_portion_print(portions[portion_index], buffer, msize);
+            generator = G_LINE_GENERATOR(portions[portion_index]);
+
+            /* Si elle comporte une description ! */
+            if (g_line_generator_count_lines(generator) > 0)
+                g_buffer_cache_append(cache, generator, BLF_NONE);
 
             portion_index++;
 
@@ -192,7 +169,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
 
         /* Début d'un nouveau symbole ? */
 
-        if (sym_index < sym_count)
+        if (sym_index == sym_count)
+            compared = -1;
+
+        else
         {
             iaddr = get_mrange_addr(g_arch_instruction_get_range(instr));
             saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]));
@@ -225,29 +205,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
                 {
                     /* Impression de la marque de début */
 
-                    init_mrange(&range, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])), 0);
-
-                    line = g_code_buffer_prepare_new_line(buffer, &range);
-                    g_buffer_line_add_flag(line, BLF_IS_LABEL);
-                    g_buffer_line_fill_mrange(line, msize, msize);
-
-                    g_code_buffer_append_new_line(buffer, line);
-
-                    line = g_code_buffer_prepare_new_line(buffer, &range);
-                    g_buffer_line_add_flag(line, BLF_IS_LABEL);
-                    g_buffer_line_fill_mrange(line, msize, msize);
-
-                    g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-                    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD,
-                                              ROUTINE_INTRO_MSG, strlen(ROUTINE_INTRO_MSG), RTT_COMMENT, NULL);
-
-                    g_code_buffer_append_new_line(buffer, line);
+                    copy_vmpa(&intro_addr, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])));
 
-                    line = g_code_buffer_prepare_new_line(buffer, &range);
-                    g_buffer_line_add_flag(line, BLF_IS_LABEL);
-                    g_buffer_line_fill_mrange(line, msize, msize);
-
-                    g_code_buffer_append_new_line(buffer, line);
+                    border = g_border_generator_new(lang, &intro_addr, true, msize);
+                    g_buffer_cache_append(cache, G_LINE_GENERATOR(border), BLF_NONE);
 
                     /* Mémorisation de la fin */
 
@@ -259,23 +220,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
 
                 /* Etiquette ? */
 
-                label = g_binary_symbol_get_label(symbols[sym_index]);
-
-                if (label != NULL)
-                {
-                    init_mrange(&range, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])), 0);
-
-                    line = g_code_buffer_prepare_new_line(buffer, &range);
-                    g_buffer_line_add_flag(line, BLF_IS_LABEL);
-                    g_buffer_line_fill_mrange(line, msize, msize);
-
-                    g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-                    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_LABEL, NULL);
-                    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL);
-
-                    g_code_buffer_append_new_line(buffer, line);
+                generator = g_binary_symbol_produce_label(symbols[sym_index]);
 
-                }
+                if (generator != NULL)
+                    g_buffer_cache_append(cache, generator, BLF_NONE);
 
             }
 
@@ -283,64 +231,37 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
 
  no_more_symbol_finally:
 
+        flags = BLF_NONE;
 
-
-        line = g_arch_instruction_print(instr, buffer, msize, content, ASX_INTEL);
-
-
-        if (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
-            g_buffer_line_add_flag(line, BLF_BOOKMARK);
-
-
-        if (sym_index < sym_count)
+        if (compared == 0)
         {
-            iaddr = get_mrange_addr(g_arch_instruction_get_range(instr));
-            saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]));
-
-            if (cmp_vmpa(iaddr, saddr) == 0)
-            {
-                /* Point d'entrée ? */
-
-                if (g_binary_symbol_get_target_type(symbols[sym_index]) == STP_ENTRY_POINT)
-                    g_buffer_line_add_flag(line, BLF_ENTRYPOINT);
+            /* Point d'entrée ? */
 
-                /* Début d'un groupe bien cohérent avec les alignements ? */
+            if (g_binary_symbol_get_target_type(symbols[sym_index]) == STP_ENTRY_POINT)
+                flags |= BLF_ENTRYPOINT;
 
-                if (g_binary_symbol_is_block_start(symbols[sym_index]))
-                    g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
+            /* Début d'un groupe bien cohérent avec les alignements ? */
 
-                /* Commentaire ? */
-
-                comment = g_binary_symbol_get_comment(symbols[sym_index]);
-
-                if (comment != NULL)
-                {
+            if (g_binary_symbol_is_block_start(symbols[sym_index]))
+                flags |= BLF_WIDTH_MANAGER;
 
-                    /* FIXME : appliquer ! */
-
-                    text = g_db_comment_get_text(comment);
-
-
-                    prefixed = strdup("; ");
-                    prefixed = stradd(prefixed, text);
-
-
-
-                    g_buffer_line_append_text(line, BLC_COMMENTS, prefixed, strlen(prefixed), RTT_COMMENT, NULL);
+        }
 
+        g_buffer_cache_append(cache, G_LINE_GENERATOR(instr), flags);
 
-                    free(prefixed);
+        if (compared == 0)
+        {
+            /* Commentaire ? */
 
-                }
+            comment = g_binary_symbol_get_comment(symbols[sym_index]);
 
-                sym_index++;
+            if (comment != NULL)
+                g_db_item_apply(G_DB_ITEM(comment), binary);
 
-            }
+            sym_index++;
 
         }
 
-        g_code_buffer_append_new_line(buffer, line);
-
         g_object_unref(G_OBJECT(instr));
 
         gtk_status_stack_update_activity_value(status, id, 1);
@@ -356,6 +277,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
     if (portions != NULL)
         free(portions);
 
+    g_object_unref(G_OBJECT(proc));
+    g_object_unref(G_OBJECT(format));
+
+
     fprintf(stderr, "MISSING :: %u symbols\n", _missing);
 
 
diff --git a/src/analysis/disass/output.h b/src/analysis/disass/output.h
index 801d3f4..35a0108 100644
--- a/src/analysis/disass/output.h
+++ b/src/analysis/disass/output.h
@@ -25,15 +25,15 @@
 #define _ANALYSIS_DISASS_OUTPUT_H
 
 
-#include "../../arch/processor.h"
-#include "../../format/executable.h"
-#include "../../glibext/gcodebuffer.h"
+#include "../binary.h"
+#include "../human/lang.h"
+#include "../../glibext/gbuffercache.h"
 #include "../../gtkext/gtkstatusstack.h"
 
 
 
 /* Transcrit du code désassemblé en texte humainement lisible. */
-void print_disassembled_instructions(GCodeBuffer *, GExeFormat *, GArchProcessor *, GtkStatusStack *);
+void print_disassembled_instructions(GBufferCache *, GCodingLanguage *, GLoadedBinary *, GtkStatusStack *);
 
 
 
diff --git a/src/analysis/human/Makefile.am b/src/analysis/human/Makefile.am
new file mode 100755
index 0000000..0cfc4e3
--- /dev/null
+++ b/src/analysis/human/Makefile.am
@@ -0,0 +1,19 @@
+
+noinst_LTLIBRARIES  = libanalysishuman.la
+
+
+libanalysishuman_la_SOURCES =			\
+	lang-int.h							\
+	lang.h lang.c
+
+libanalysishuman_la_LIBADD =			\
+	asm/libanalysishumanasm.la
+
+libanalysishuman_la_LDFLAGS = 
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = asm
diff --git a/src/analysis/human/asm/Makefile.am b/src/analysis/human/asm/Makefile.am
new file mode 100755
index 0000000..da94071
--- /dev/null
+++ b/src/analysis/human/asm/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES  = libanalysishumanasm.la
+
+
+libanalysishumanasm_la_SOURCES =		\
+	lang.h lang.c
+
+libanalysishumanasm_la_LIBADD = 
+
+libanalysishumanasm_la_LDFLAGS = 
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = 
diff --git a/src/analysis/human/asm/lang.c b/src/analysis/human/asm/lang.c
new file mode 100644
index 0000000..27a26dd
--- /dev/null
+++ b/src/analysis/human/asm/lang.c
@@ -0,0 +1,221 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang.c - traduction en language d'assembleur classique
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "lang.h"
+
+
+#include "../lang-int.h"
+#include "../../../common/extstr.h"
+
+
+
+/* Traduction d'éléments en language d'assembleur (instance) */
+struct _GAsmLanguage
+{
+    GCodingLanguage parent;                 /* A laisser en premier        */
+
+};
+
+/* Traduction d'éléments en language d'assembleur (classe) */
+struct _GAsmLanguageClass
+{
+    GCodingLanguageClass parent;            /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des traductions en langage d'assembleur. */
+static void g_asm_language_class_init(GAsmLanguageClass *);
+
+/* Initialise une traduction d'éléments en langage d'assembleur. */
+static void g_asm_language_init(GAsmLanguage *);
+
+/* Supprime toutes les références externes. */
+static void g_asm_language_dispose(GAsmLanguage *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_asm_language_finalize(GAsmLanguage *);
+
+/* Complète du texte pour en faire un vrai commentaire. */
+static void g_asm_language_encapsulate_comment(const GAsmLanguage *, char **);
+
+/* Complète du texte pour en faire de vrais commentaires. */
+static void g_asm_language_encapsulate_comments(const GAsmLanguage *, char ***, size_t *);
+
+
+
+/* Indique le type défini pour une traduction en langage d'assembleur. */
+G_DEFINE_TYPE(GAsmLanguage, g_asm_language, G_TYPE_CODING_LANGUAGE);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des traductions en langage d'assembleur.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_asm_language_class_init(GAsmLanguageClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GCodingLanguageClass *lang;             /* Encore une autre vision...  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_asm_language_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_asm_language_finalize;
+
+    lang = G_CODING_LANGUAGE_CLASS(klass);
+
+    lang->encaps_comment = (encapsulate_comment_fc)g_asm_language_encapsulate_comment;
+    lang->encaps_comments = (encapsulate_comments_fc)g_asm_language_encapsulate_comments;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une traduction d'éléments en langage d'assembleur.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_asm_language_init(GAsmLanguage *lang)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_asm_language_dispose(GAsmLanguage *lang)
+{
+    G_OBJECT_CLASS(g_asm_language_parent_class)->dispose(G_OBJECT(lang));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_asm_language_finalize(GAsmLanguage *lang)
+{
+    G_OBJECT_CLASS(g_asm_language_parent_class)->finalize(G_OBJECT(lang));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une instance de traduction en langage d'assembleur.     *
+*                                                                             *
+*  Retour      : Instance mis en place et prête à emploi.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GCodingLanguage *g_asm_language_new(void)
+{
+    GAsmLanguage *result;                   /* Instance à retourner        */
+
+    result = g_object_new(G_TYPE_ASM_LANGUAGE, NULL);
+
+    return G_CODING_LANGUAGE(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang  = langage de haut niveau à manipuler.                  *
+*                text  = adresse de la ligne à compléter. [OUT]               *
+*                                                                             *
+*  Description : Complète du texte pour en faire un vrai commentaire.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_asm_language_encapsulate_comment(const GAsmLanguage *lang, char **text)
+{
+    *text = strprep(*text, "; ");
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang  = langage de haut niveau à manipuler.                  *
+*                text  = adresse du tableau de lignes à conserver. [OUT]      *
+*                count = adresse de la taille du tableau fourni. [OUT]        *
+*                                                                             *
+*  Description : Complète du texte pour en faire de vrais commentaires.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_asm_language_encapsulate_comments(const GAsmLanguage *lang, char ***text, size_t *count)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < *count; i++)
+        (*text)[i] = strprep((*text)[i], "; ");
+
+}
diff --git a/src/analysis/human/asm/lang.h b/src/analysis/human/asm/lang.h
new file mode 100644
index 0000000..7381048
--- /dev/null
+++ b/src/analysis/human/asm/lang.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang.h - prototypes pour la traduction en language d'assembleur classique
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _ANALYSIS_HUMAN_ASM_LANG_H
+#define _ANALYSIS_HUMAN_ASM_LANG_H
+
+
+#include <glib-object.h>
+
+
+#include "../lang.h"
+
+
+
+#define G_TYPE_ASM_LANGUAGE             g_asm_language_get_type()
+#define G_ASM_LANGUAGE(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), g_asm_language_get_type(), GAsmLanguage))
+#define G_IS_ASM_LANGUAGE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_asm_language_get_type()))
+#define G_ASM_LANGUAGE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ASM_LANGUAGE, GAsmLanguageClass))
+#define G_IS_ASM_LANGUAGE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ASM_LANGUAGE))
+#define G_ASM_LANGUAGE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ASM_LANGUAGE, GAsmLanguageClass))
+
+
+/* Traduction d'éléments en language d'assembleur (instance) */
+typedef struct _GAsmLanguage GAsmLanguage;
+
+/* Traduction d'éléments en language d'assembleur (classe) */
+typedef struct _GAsmLanguageClass GAsmLanguageClass;
+
+
+/* Indique le type défini pour une traduction en langage d'assembleur. */
+GType g_asm_language_get_type(void);
+
+/* Crée une instance de traduction en langage d'assembleur. */
+GCodingLanguage *g_asm_language_new(void);
+
+
+
+#endif  /* _ANALYSIS_HUMAN_ASM_LANG_H */
diff --git a/src/analysis/human/lang-int.h b/src/analysis/human/lang-int.h
new file mode 100644
index 0000000..c20bc8a
--- /dev/null
+++ b/src/analysis/human/lang-int.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang-int.h - prototypes utiles aux traductions en langages de haut niveau
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _ANALYSIS_HUMAN_LANG_INT_H
+#define _ANALYSIS_HUMAN_LANG_INT_H
+
+
+#include "lang.h"
+
+
+
+/* Complète du texte pour en faire un vrai commentaire. */
+typedef void (* encapsulate_comment_fc) (const GCodingLanguage *, char **);
+
+/* Complète du texte pour en faire de vrais commentaires. */
+typedef void (* encapsulate_comments_fc) (const GCodingLanguage *, char ***, size_t *);
+
+
+/* Traduction générique en langage humain (instance) */
+struct _GCodingLanguage
+{
+    GObject parent;                         /* A laisser en premier        */
+
+};
+
+/* Traduction générique en langage humain (classe) */
+struct _GCodingLanguageClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    encapsulate_comment_fc encaps_comment;  /* Encadrement de commentaire */
+    encapsulate_comments_fc encaps_comments;/* Encadrement de commentaires */
+
+};
+
+
+
+#endif  /* _ANALYSIS_HUMAN_LANG_INT_H */
diff --git a/src/analysis/human/lang.c b/src/analysis/human/lang.c
new file mode 100644
index 0000000..72002d3
--- /dev/null
+++ b/src/analysis/human/lang.c
@@ -0,0 +1,167 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang.c - traduction en langages de haut niveau
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "lang.h"
+
+
+#include "lang-int.h"
+
+
+
+/* Initialise la classe des traductions en langage humain. */
+static void g_coding_language_class_init(GCodingLanguageClass *);
+
+/* Initialise une instance de traduction en langage humain. */
+static void g_coding_language_init(GCodingLanguage *);
+
+/* Supprime toutes les références externes. */
+static void g_coding_language_dispose(GCodingLanguage *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_coding_language_finalize(GCodingLanguage *);
+
+
+
+/* Indique le type défini pour une traduction en langage humain. */
+G_DEFINE_TYPE(GCodingLanguage, g_coding_language, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des traductions en langage humain.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_coding_language_class_init(GCodingLanguageClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_coding_language_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_coding_language_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance de traduction en langage humain.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_coding_language_init(GCodingLanguage *lang)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_coding_language_dispose(GCodingLanguage *lang)
+{
+    G_OBJECT_CLASS(g_coding_language_parent_class)->dispose(G_OBJECT(lang));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_coding_language_finalize(GCodingLanguage *lang)
+{
+    G_OBJECT_CLASS(g_coding_language_parent_class)->finalize(G_OBJECT(lang));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang  = langage de haut niveau à manipuler.                  *
+*                text  = adresse de la ligne à compléter. [OUT]               *
+*                                                                             *
+*  Description : Complète du texte pour en faire un vrai commentaire.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_coding_language_encapsulate_comment(const GCodingLanguage *lang, char **text)
+{
+    G_CODING_LANGUAGE_GET_CLASS(lang)->encaps_comment(lang, text);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang  = langage de haut niveau à manipuler.                  *
+*                text  = adresse du tableau de lignes à conserver. [OUT]      *
+*                count = adresse de la taille du tableau fourni. [OUT]        *
+*                                                                             *
+*  Description : Complète du texte pour en faire de vrais commentaires.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_coding_language_encapsulate_comments(const GCodingLanguage *lang, char ***text, size_t *count)
+{
+    G_CODING_LANGUAGE_GET_CLASS(lang)->encaps_comments(lang, text, count);
+
+}
diff --git a/src/analysis/human/lang.h b/src/analysis/human/lang.h
new file mode 100644
index 0000000..dc8e398
--- /dev/null
+++ b/src/analysis/human/lang.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * lang.h - prototypes pour les traductions en langages de haut niveau
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _ANALYSIS_HUMAN_LANG_H
+#define _ANALYSIS_HUMAN_LANG_H
+
+
+#include <glib-object.h>
+
+
+
+#define G_TYPE_CODING_LANGUAGE              g_coding_language_get_type()
+#define G_CODING_LANGUAGE(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODING_LANGUAGE, GCodingLanguage))
+#define G_IS_CODING_LANGUAGE(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODING_LANGUAGE))
+#define G_CODING_LANGUAGE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODING_LANGUAGE, GCodingLanguageClass))
+#define G_IS_CODING_LANGUAGE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODING_LANGUAGE))
+#define G_CODING_LANGUAGE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODING_LANGUAGE, GCodingLanguageClass))
+
+
+/* Traduction générique en langage humain (instance) */
+typedef struct _GCodingLanguage GCodingLanguage;
+
+/* Traduction générique en langage humain (classe) */
+typedef struct _GCodingLanguageClass GCodingLanguageClass;
+
+
+/* Indique le type défini pour une traduction en langage humain. */
+GType g_coding_language_get_type(void);
+
+/* Complète du texte pour en faire un vrai commentaire. */
+void g_coding_language_encapsulate_comment(const GCodingLanguage *, char **);
+
+/* Complète du texte pour en faire de vrais commentaires. */
+void g_coding_language_encapsulate_comments(const GCodingLanguage *, char ***, size_t *);
+
+
+
+#endif  /* _ANALYSIS_HUMAN_LANG_H */
diff --git a/src/analysis/project.c b/src/analysis/project.c
index dce55b6..4251dcc 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -39,9 +39,8 @@
 #include "../glibext/signal.h"
 #include "../gtkext/easygtk.h"
 #include "../glibext/delayed-int.h"
-#include "../gtkext/gtkblockview.h"
-#include "../gtkext/gtkgraphview.h"
-#include "../gtkext/gtksourceview.h"
+#include "../gtkext/gtkblockdisplay.h"
+#include "../gtkext/gtkgraphdisplay.h"
 #include "../gui/core/panels.h"
 #include "../gui/panels/log.h"
 #include "../gui/panels/panel.h"
@@ -836,13 +835,10 @@ GPanelItem *_setup_new_panel_item_for_binary(GStudyProject *project, GLoadedBina
         switch (i)
         {
             case BVW_BLOCK:
-                display = gtk_block_view_new();
+                display = gtk_block_display_new();
                 break;
             case BVW_GRAPH:
-                display = gtk_graph_view_new();
-                break;
-            case BVW_SOURCE:
-                display = gtk_source_view_new();
+                display = gtk_graph_display_new();
                 break;
             default: /* GCC ! */
                 break;
@@ -894,9 +890,6 @@ GPanelItem *_setup_new_panel_item_for_binary(GStudyProject *project, GLoadedBina
                 case BVW_GRAPH:
                     g_object_set_data(G_OBJECT(displays[i]), "graph_alt_view", displays[j]);
                     break;
-                case BVW_SOURCE:
-                    g_object_set_data(G_OBJECT(displays[i]), "source_alt_view", displays[j]);
-                    break;
                 default: /* GCC ! */
                     break;
             }
@@ -1033,9 +1026,6 @@ GtkDisplayPanel *get_alt_view_for_view_panel(GtkDisplayPanel *panel, BinaryView
         case BVW_GRAPH:
             result = GTK_DISPLAY_PANEL(g_object_get_data(G_OBJECT(panel), "graph_alt_view"));
             break;
-        case BVW_SOURCE:
-            result = GTK_DISPLAY_PANEL(g_object_get_data(G_OBJECT(panel), "source_alt_view"));
-            break;
         default:
             assert(false);
             result = NULL;
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c
index 694ec65..3f9ab8c 100644
--- a/src/arch/dalvik/link.c
+++ b/src/arch/dalvik/link.c
@@ -58,6 +58,9 @@ typedef struct _case_comment
 } case_comment;
 
 
+/* REMME */
+#define COMMENT_LINE_SEP "\n"
+
 
 /******************************************************************************
 *                                                                             *
@@ -262,6 +265,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
                         for (k = 0; k < comment->count; k++)
                         {
                             if (k > 0)
+                                /* FIXME : encapsuler ! */
                                 msg = stradd(msg, COMMENT_LINE_SEP);
 
                             asprintf(&int_val, _("Case %d:"), comment->keys[k]);
@@ -280,6 +284,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
                         msg = strdup(_("Defaut case:"));
                     else
                     {
+                        /* FIXME : encapsuler ! */
                         msg = stradd(msg, COMMENT_LINE_SEP);
                         msg = stradd(msg, _("Defaut case"));
                     }
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index c7f32e7..dbb2f2c 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -38,7 +38,7 @@ typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegi
 typedef const char * (* get_instruction_encoding_fc) (const GArchInstruction *);
 
 /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBufferLine *, size_t, size_t);
 
 /* Fournit le nom humain de l'instruction manipulée. */
 typedef const char * (* get_instruction_keyword_fc) (GArchInstruction *, AsmSyntax );
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 5f35db4..fc474ea 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -30,6 +30,7 @@
 
 
 #include "instruction-int.h"
+#include "../glibext/linegen-int.h"
 
 
 
@@ -39,6 +40,9 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);
 /* Initialise une instance d'opérande d'architecture. */
 static void g_arch_instruction_init(GArchInstruction *);
 
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_arch_instruction_interface_init(GLineGeneratorInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_arch_instruction_dispose(GArchInstruction *);
 
@@ -47,16 +51,32 @@ static void g_arch_instruction_finalize(GArchInstruction *);
 
 
 
-/* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_arch_instruction_count_lines(const GArchInstruction *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_arch_instruction_compute_addr(const GArchInstruction *, gint, vmpa2t *, size_t, size_t);
 
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_arch_instruction_contains_addr(const GArchInstruction *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *, size_t, size_t);
 
 /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static GBufferLine *_g_arch_instruction_print(GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+static void _g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t);
 
 
 
 /* Indique le type défini pour une instruction d'architecture. */
-G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_interface_init));
 
 
 /******************************************************************************
@@ -116,6 +136,29 @@ static void g_arch_instruction_init(GArchInstruction *instr)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arch_instruction_interface_init(GLineGeneratorInterface *iface)
+{
+    iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines;
+    iface->compute = (linegen_compute_fc)g_arch_instruction_compute_addr;
+    iface->contains = (linegen_contains_fc)g_arch_instruction_contains_addr;
+    iface->get_flags = (linegen_get_flags_fc)g_arch_instruction_get_flags2;
+    iface->print = (linegen_print_fc)g_arch_instruction_print;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : instr = instance d'objet GLib à traiter.                     *
 *                                                                             *
 *  Description : Supprime toutes les références externes.                     *
@@ -897,84 +940,6 @@ void g_arch_instruction_set_displayed_max_length(GArchInstruction *instr, phys_t
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr   = instruction d'assemblage à représenter.            *
-*                buffer  = espace où placer ledit contenu.                    *
-*                msize   = taille idéale des positions et adresses;           *
-*                content = contenu binaire global à venir lire.               *
-*                syntax  = type de représentation demandée.                   *
-*                                                                             *
-*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static GBufferLine *_g_arch_instruction_print(GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
-{
-    GBufferLine *result;                    /* Ligne de destination        */
-    const char *key;                        /* Mot clef principal          */
-    size_t klen;                            /* Taille de ce mot clef       */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = g_code_buffer_prepare_new_line(buffer, &instr->range);
-
-    g_buffer_line_add_flag(result, BLF_HAS_CODE);
-
-    g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, instr->max_displayed_len);
-
-    /* Instruction proprement dite */
-
-    key = g_arch_instruction_get_keyword(instr, syntax);
-    klen = strlen(key);
-
-    g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
-
-    if (instr->operands_count > 0)
-    {
-        g_arch_operand_print(instr->operands[0], result, syntax);
-
-        for (i = 1; i < instr->operands_count; i++)
-        {
-            g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
-            g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
-
-            g_arch_operand_print(instr->operands[i], result, syntax);
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr  = instruction d'assemblage à représenter.             *
-*                buffer = espace où placer ledit contenu.                     *
-*                msize  = taille idéale des positions et adresses;            *
-*                content = contenu binaire global à venir lire.               *
-*                syntax = type de représentation demandée.                    *
-*                                                                             *
-*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferLine *g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
-{
-    return G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, buffer, msize, content, syntax);
-
-}
-
 
 /* ---------------------------------------------------------------------------------- */
 /*                      TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE                      */
@@ -1110,3 +1075,169 @@ GArchInstruction *g_arch_instruction_find_by_address(GArchInstruction *list, con
     return result;
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          OFFRE DE CAPACITES DE GENERATION                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = générateur à consulter.                              *
+*                                                                             *
+*  Description : Indique le nombre de ligne prêtes à être générées.           *
+*                                                                             *
+*  Retour      : Nombre de lignes devant apparaître au final.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t g_arch_instruction_count_lines(const GArchInstruction *instr)
+{
+    return 1;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = générateur à consulter.                             *
+*                x      = position géographique sur la ligne concernée.       *
+*                addr   = position en mémoire à analyser.                     *
+*                index  = indice de cette même ligne dans le tampon global.   *
+*                repeat = indice d'utilisations successives du générateur.    *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arch_instruction_compute_addr(const GArchInstruction *instr, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+    copy_vmpa(addr, get_mrange_addr(&instr->range));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = générateur à consulter.                             *
+*                addr   = position en mémoire à analyser.                     *
+*                index  = indice de cette même ligne dans le tampon global.   *
+*                repeat = indice d'utilisations successives du générateur.    *
+*                                                                             *
+*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
+*                                                                             *
+*  Retour      : Bilan de la détermination, utilisable en comparaisons.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int g_arch_instruction_contains_addr(const GArchInstruction *instr, const vmpa2t *addr, size_t index, size_t repeat)
+{
+    int result;                             /* Conclusion à retourner      */
+
+    result = cmp_mrange_with_vmpa(&instr->range, addr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = générateur à consulter.                             *
+*                index  = indice de cette même ligne dans le tampon global.   *
+*                repeat = indice d'utilisations successives du générateur.    *
+*                                                                             *
+*  Description : Renseigne sur les propriétés liées à un générateur.          *
+*                                                                             *
+*  Retour      : Propriétés particulières associées.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *instr, size_t index, size_t repeat)
+{
+    return BLF_HAS_CODE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction d'assemblage à représenter.            *
+*                buffer  = espace où placer ledit contenu.                    *
+*                msize   = taille idéale des positions et adresses;           *
+*                content = contenu binaire global à venir lire.               *
+*                syntax  = type de représentation demandée.                   *
+*                                                                             *
+*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat)
+{
+    const char *key;                        /* Mot clef principal          */
+    size_t klen;                            /* Taille de ce mot clef       */
+    size_t i;                               /* Boucle de parcours          */
+
+    g_buffer_line_fill_vmpa(line, get_mrange_addr(&instr->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
+
+    /* Instruction proprement dite */
+
+    key = g_arch_instruction_get_keyword(instr, 0/*, syntax*/);
+    klen = strlen(key);
+
+    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
+
+    if (instr->operands_count > 0)
+    {
+        g_arch_operand_print(instr->operands[0], line, 0/*syntax*/);
+
+        for (i = 1; i < instr->operands_count; i++)
+        {
+            g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+            g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+
+            g_arch_operand_print(instr->operands[i], line, 0/*syntax*/);
+
+        }
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = générateur à utiliser pour l'impression.            *
+*                line   = ligne de rendu à compléter.                         *
+*                index  = indice de cette même ligne dans le tampon global.   *
+*                repeat = indice d'utilisations successives du générateur.    *
+*                                                                             *
+*  Description : Imprime dans une ligne de rendu le contenu représenté.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat)
+{
+    G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, line, index, repeat);
+
+}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 54778b5..814cc86 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -35,7 +35,6 @@
 #include "../analysis/content.h"
 #include "../analysis/type.h"
 #include "../format/executable.h"
-#include "../glibext/gcodebuffer.h"
 
 
 
@@ -222,9 +221,6 @@ phys_t g_arch_instruction_get_displayed_max_length(const GArchInstruction *);
 /* Définit la quantité maximale de code affiché. */
 void g_arch_instruction_set_displayed_max_length(GArchInstruction *, phys_t);
 
-/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-GBufferLine *g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
-
 
 
 /* -------------------- TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE -------------------- */
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 61a37e0..d0348c9 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -78,7 +78,7 @@ static const char *g_raw_instruction_get_encoding(const GRawInstruction *);
 static const char *g_raw_instruction_get_keyword(const GRawInstruction *, AsmSyntax);
 
 /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static GBufferLine *g_raw_instruction_print(GRawInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+static void g_raw_instruction_print(GRawInstruction *, GBufferLine *, size_t, size_t);
 
 
 
@@ -444,11 +444,11 @@ static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, A
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : instr  = instruction d'assemblage à représenter.             *
-*                buffer = espace où placer ledit contenu.                     *
+*  Paramètres  : instr   = instruction d'assemblage à représenter.            *
+*                buffer  = espace où placer ledit contenu.                    *
 *                msize   = taille idéale des positions et adresses;           *
 *                content = contenu binaire global à venir lire.               *
-*                syntax = type de représentation demandée.                    *
+*                syntax  = type de représentation demandée.                   *
 *                                                                             *
 *  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
 *                                                                             *
@@ -458,9 +458,8 @@ static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, A
 *                                                                             *
 ******************************************************************************/
 
-static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
+static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, size_t index, size_t repeat)
 {
-    GBufferLine *result;                    /* Ligne de destination        */
     GArchInstruction *base;                 /* Autre version de l'instance */
     const char *key;                        /* Mot clef principal          */
     size_t klen;                            /* Taille de ce mot clef       */
@@ -474,25 +473,21 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
     base = G_ARCH_INSTRUCTION(instr);
 
     if (!instr->is_padding && !instr->is_string)
-        result = G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class)->print(base, buffer, msize, content, syntax);
+        G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class)->print(base, line, index, repeat);
 
     else
     {
-        result = g_code_buffer_prepare_new_line(buffer, &base->range);
-
-        g_buffer_line_add_flag(result, BLF_HAS_CODE);
-
-        g_buffer_line_fill_mrange(result, msize/* TODO ! */, msize);
+        g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
 
         /* Instruction proprement dite */
 
-        key = g_arch_instruction_get_keyword(base, syntax);
+        key = g_arch_instruction_get_keyword(base, 0/*, syntax*/);
         klen = strlen(key);
 
-        g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
+        g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
 
         if (instr->is_padding)
-            g_buffer_line_append_text(result, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL);
+            g_buffer_line_append_text(line, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL);
 
         else /*if (instr->is_string)*/
         {
@@ -516,15 +511,15 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
                     {
                         if (!first)
                         {
-                            g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
-                            g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+                            g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+                            g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
                         }
                         else
                             first = false;
 
                         string[iter++] = '"';
 
-                        g_buffer_line_append_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
+                        g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
 
                         iter = 1;
 
@@ -534,13 +529,13 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
 
                     if (!first)
                     {
-                        g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
-                        g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+                        g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+                        g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
                     }
                     else
                         first = false;
 
-                    g_arch_operand_print(base->operands[i], result, syntax);
+                    g_arch_operand_print(base->operands[i], line, 0/*, syntax*/);
 
                 }
 
@@ -554,15 +549,15 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
             {
                 if (!first)
                 {
-                    g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
-                    g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+                    g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+                    g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
                 }
                 else
                     first = false;
 
                 string[iter++] = '"';
 
-                g_buffer_line_append_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
+                g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
 
             }
 
@@ -572,8 +567,6 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer
 
     }
 
-    return result;
-
 }
 
 
diff --git a/src/arch/undefined.c b/src/arch/undefined.c
index 0957764..d239dd5 100644
--- a/src/arch/undefined.c
+++ b/src/arch/undefined.c
@@ -70,7 +70,7 @@ static const char *g_undef_instruction_get_encoding(const GUndefInstruction *);
 static const char *g_undef_instruction_get_keyword(const GUndefInstruction *, AsmSyntax);
 
 /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static GBufferLine *g_undef_instruction_print(GUndefInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
+static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t, size_t);
 
 
 
@@ -262,11 +262,11 @@ const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr, AsmS
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : instr  = instruction d'assemblage à représenter.             *
-*                buffer = espace où placer ledit contenu.                     *
+*  Paramètres  : instr   = instruction d'assemblage à représenter.            *
+*                buffer  = espace où placer ledit contenu.                    *
 *                msize   = taille idéale des positions et adresses;           *
 *                content = contenu binaire global à venir lire.               *
-*                syntax = type de représentation demandée.                    *
+*                syntax  = type de représentation demandée.                   *
 *                                                                             *
 *  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
 *                                                                             *
@@ -276,29 +276,22 @@ const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr, AsmS
 *                                                                             *
 ******************************************************************************/
 
-static GBufferLine *g_undef_instruction_print(GUndefInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax)
+static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *line, size_t index, size_t repeat)
 {
-    GBufferLine *result;                    /* Ligne de destination        */
     GArchInstruction *base;                 /* Version de base             */
     const char *key;                        /* Mot clef principal          */
     size_t klen;                            /* Taille de ce mot clef       */
 
     base = G_ARCH_INSTRUCTION(instr);
 
-    result = g_code_buffer_prepare_new_line(buffer, &base->range);
-
-    g_buffer_line_add_flag(result, BLF_HAS_CODE);
-
-    g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, base->max_displayed_len);
+    g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
 
     /* Instruction proprement dite */
 
-    key = g_arch_instruction_get_keyword(base, syntax);
+    key = g_arch_instruction_get_keyword(base, 0/*, syntax*/);
     klen = strlen(key);
 
-    g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL);
-
-    return result;
+    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL);
 
 }
 
diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h
index 1e17f17..16fada4 100644
--- a/src/arch/vmpa.h
+++ b/src/arch/vmpa.h
@@ -104,7 +104,9 @@ int cmp_vmpa(const vmpa2t *, const vmpa2t *);
 #define has_phys_addr(a) ((a)->physical != VMPA_NO_PHYSICAL)
 #define has_virt_addr(a) ((a)->virtual != VMPA_NO_VIRTUAL)
 
-#define dup_vmpa(src) \
+#define is_invalid_vmpa(a) (!has_phys_addr(a) && !has_virt_addr(a))
+
+#define dup_vmpa(src)                                   \
     make_vmpa(get_phy_addr(src), get_virt_addr(src))
 
 /* Décalle une position d'une certaine quantité. */
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index df920b2..d93346a 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -79,7 +79,7 @@ static bool g_dex_format_get_section_range_by_name(const GDexFormat *, const cha
 //static void g_dex_format_find_all_sources(GDexFormat *);
 
 /* Procède à la décompilation complète du format. */
-static void g_dex_format_decompile(const GDexFormat *, GCodeBuffer *, const char *);
+static void g_dex_format_decompile(const GDexFormat *, void/*GCodeBuffer*/ *, const char *);
 
 
 
@@ -470,7 +470,7 @@ static void g_dex_format_find_all_sources(GDexFormat *format)
 *                                                                             *
 ******************************************************************************/
 
-static void g_dex_format_decompile(const GDexFormat *format, GCodeBuffer *buffer, const char *filename)
+static void g_dex_format_decompile(const GDexFormat *format, void/*GCodeBuffer*/ *buffer, const char *filename)
 {
 
 #if 0
diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h
index 38065fa..b819156 100644
--- a/src/format/dex/pool.h
+++ b/src/format/dex/pool.h
@@ -29,6 +29,7 @@
 #include "dex.h"
 #include "method.h"
 #include "../../analysis/routine.h"
+#include "../../glibext/delayed.h"
 
 
 
diff --git a/src/format/dwarf/v2/dwarf.h b/src/format/dwarf/v2/dwarf.h
index 54c6b37..867ae39 100644
--- a/src/format/dwarf/v2/dwarf.h
+++ b/src/format/dwarf/v2/dwarf.h
@@ -28,8 +28,7 @@
 #include <glib-object.h>
 
 
-#include "../../executable.h"
-#include "../../format.h"
+#include "../../../core/formats.h"
 
 
 
diff --git a/src/format/dwarf/v3/dwarf.h b/src/format/dwarf/v3/dwarf.h
index e95ed16..bac5ccc 100644
--- a/src/format/dwarf/v3/dwarf.h
+++ b/src/format/dwarf/v3/dwarf.h
@@ -28,8 +28,7 @@
 #include <glib-object.h>
 
 
-#include "../../executable.h"
-#include "../../format.h"
+#include "../../../core/formats.h"
 
 
 
diff --git a/src/format/dwarf/v4/dwarf.h b/src/format/dwarf/v4/dwarf.h
index 29059b5..6eda64e 100644
--- a/src/format/dwarf/v4/dwarf.h
+++ b/src/format/dwarf/v4/dwarf.h
@@ -28,8 +28,7 @@
 #include <glib-object.h>
 
 
-#include "../../executable.h"
-#include "../../format.h"
+#include "../../../core/formats.h"
 
 
 
diff --git a/src/format/elf/symbols.h b/src/format/elf/symbols.h
index d1b0fae..90e2f61 100644
--- a/src/format/elf/symbols.h
+++ b/src/format/elf/symbols.h
@@ -28,6 +28,7 @@
 #include "elf.h"
 
 
+#include "../../glibext/delayed.h"
 #include "../../gtkext/gtkstatusstack.h"
 
 
diff --git a/src/format/format-int.h b/src/format/format-int.h
index e11e378..ea6b770 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -28,6 +28,9 @@
 #include "format.h"
 
 
+#include "../gtkext/gtkstatusstack.h"
+
+
 
 /* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */
 
@@ -36,7 +39,7 @@
 typedef SourceEndian (* format_get_endian_fc) (const GBinFormat *);
 
 /* Procède à la décompilation complète du format. */
-typedef void (* format_decompile_fc) (const GBinFormat *, GCodeBuffer *, const char *);
+typedef void (* format_decompile_fc) (const GBinFormat *, void/*GCodeBuffer*/ *, const char *);
 
 
 /* Rythme des allocations pour les entrées de code */
diff --git a/src/format/java/java.h b/src/format/java/java.h
index 074c797..a33870f 100755
--- a/src/format/java/java.h
+++ b/src/format/java/java.h
@@ -30,7 +30,7 @@
 #include <sys/types.h>
 
 
-#include "../format.h"
+#include "../../core/formats.h"
 
 
 
diff --git a/src/format/pe/pe.h b/src/format/pe/pe.h
index 3ac5f49..d6c8dde 100644
--- a/src/format/pe/pe.h
+++ b/src/format/pe/pe.h
@@ -30,7 +30,7 @@
 #include <sys/types.h>
 
 
-#include "../format.h"
+#include "../../core/formats.h"
 
 
 
diff --git a/src/format/symbol.c b/src/format/symbol.c
index 97ff114..82321c2 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -28,6 +28,12 @@
 #include <string.h>
 
 
+#include "../glibext/linegen-int.h"
+
+
+
+/* --------------------- FONCTIONNALITES BASIQUES POUR SYMBOLES --------------------- */
+
 
 /* Symbole d'exécutable (instance) */
 struct _GBinSymbol
@@ -64,6 +70,9 @@ static void g_binary_symbol_class_init(GBinSymbolClass *);
 /* Initialise une instance de symbole d'exécutable. */
 static void g_binary_symbol_init(GBinSymbol *);
 
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_binary_symbol_interface_init(GLineGeneratorInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_binary_symbol_dispose(GBinSymbol *);
 
@@ -72,8 +81,34 @@ static void g_binary_symbol_finalize(GBinSymbol *);
 
 
 
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_binary_symbol_count_lines(const GBinSymbol *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_binary_symbol_compute_addr(const GBinSymbol *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_binary_symbol_contains_addr(const GBinSymbol *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_binary_symbol_get_flags(const GBinSymbol *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_binary_symbol_print(GBinSymbol *, GBufferLine *, size_t, size_t);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       FONCTIONNALITES BASIQUES POUR SYMBOLES                       */
+/* ---------------------------------------------------------------------------------- */
+
+
 /* Indique le type défini pour un symbole d'exécutable. */
-G_DEFINE_TYPE(GBinSymbol, g_binary_symbol, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GBinSymbol, g_binary_symbol, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_binary_symbol_interface_init));
 
 
 /******************************************************************************
@@ -120,6 +155,29 @@ static void g_binary_symbol_init(GBinSymbol *symbol)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_symbol_interface_init(GLineGeneratorInterface *iface)
+{
+    iface->count = (linegen_count_lines_fc)g_binary_symbol_count_lines;
+    iface->compute = (linegen_compute_fc)g_binary_symbol_compute_addr;
+    iface->contains = (linegen_contains_fc)g_binary_symbol_contains_addr;
+    iface->get_flags = (linegen_get_flags_fc)g_binary_symbol_get_flags;
+    iface->print = (linegen_print_fc)g_binary_symbol_print;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : symbol = instance d'objet GLib à traiter.                    *
 *                                                                             *
 *  Description : Supprime toutes les références externes.                     *
@@ -665,3 +723,164 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *symbol)
     return symbol->comment;
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          OFFRE DE CAPACITES DE GENERATION                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = générateur à consulter pour futur usage.            *
+*                                                                             *
+*  Description : Détermine si un symbole pour faire office de générateur.     *
+*                                                                             *
+*  Retour      : Instance de générateur si les capacités sont là.             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GLineGenerator *g_binary_symbol_produce_label(GBinSymbol *symbol)
+{
+    GLineGenerator *result;                 /* Instance à retourner        */
+    const char *label;                      /* Etiquette à insérer         */
+
+    label = g_binary_symbol_get_label(symbol);
+
+    result = (label != NULL ? G_LINE_GENERATOR(symbol) : NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = générateur à consulter.                             *
+*                                                                             *
+*  Description : Indique le nombre de ligne prêtes à être générées.           *
+*                                                                             *
+*  Retour      : Nombre de lignes devant apparaître au final.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t g_binary_symbol_count_lines(const GBinSymbol *symbol)
+{
+    return 1;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = générateur à consulter.                             *
+*                x      = position géographique sur la ligne concernée.       *
+*                addr   = position en mémoire à analyser.                     *
+*                index  = indice de cette même ligne dans le tampon global.   *
+*                repeat = indice d'utilisations successives du générateur.    *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_symbol_compute_addr(const GBinSymbol *symbol, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+    const mrange_t *range;                  /* Emplacement à manipuler     */
+
+    range = g_binary_symbol_get_range(symbol);
+
+    copy_vmpa(addr, get_mrange_addr(range));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = générateur à consulter.                             *
+*                addr   = position en mémoire à analyser.                     *
+*                index  = indice de cette même ligne dans le tampon global.   *
+*                repeat = indice d'utilisations successives du générateur.    *
+*                                                                             *
+*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
+*                                                                             *
+*  Retour      : Bilan de la détermination, utilisable en comparaisons.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int g_binary_symbol_contains_addr(const GBinSymbol *symbol, const vmpa2t *addr, size_t index, size_t repeat)
+{
+    int result;                             /* Conclusion à retourner      */
+    const mrange_t *range;                  /* Emplacement à manipuler     */
+
+    range = g_binary_symbol_get_range(symbol);
+
+    result = cmp_mrange_with_vmpa(range, addr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = générateur à consulter.                             *
+*                index  = indice de cette même ligne dans le tampon global.   *
+*                repeat = indice d'utilisations successives du générateur.    *
+*                                                                             *
+*  Description : Renseigne sur les propriétés liées à un générateur.          *
+*                                                                             *
+*  Retour      : Propriétés particulières associées.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static BufferLineFlags g_binary_symbol_get_flags(const GBinSymbol *symbol, size_t index, size_t repeat)
+{
+    return BLF_IS_LABEL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = générateur à utiliser pour l'impression.            *
+*                line   = ligne de rendu à compléter.                         *
+*                index  = indice de cette même ligne dans le tampon global.   *
+*                repeat = indice d'utilisations successives du générateur.    *
+*                                                                             *
+*  Description : Imprime dans une ligne de rendu le contenu représenté.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_symbol_print(GBinSymbol *symbol, GBufferLine *line, size_t index, size_t repeat)
+{
+    const mrange_t *range;                  /* Emplacement à manipuler     */
+    const char *label;                      /* Etiquette à insérer         */
+
+    range = g_binary_symbol_get_range(symbol);
+
+    g_buffer_line_fill_vmpa(line, get_mrange_addr(range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
+
+    label = g_binary_symbol_get_label(symbol);
+
+    g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(label), RTT_LABEL, NULL);
+    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL);
+
+}
diff --git a/src/format/symbol.h b/src/format/symbol.h
index 78741cb..e73bb27 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -32,9 +32,13 @@
 #include "../analysis/db/item.h"
 #include "../analysis/db/items/comment.h"
 #include "../arch/instruction.h"
+#include "../glibext/linegen.h"
 
 
 
+/* --------------------- FONCTIONNALITES BASIQUES POUR SYMBOLES --------------------- */
+
+
 /* Types de symbole */
 typedef enum _SymbolType
 {
@@ -164,4 +168,12 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *);
 
 
 
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Détermine si un symbole pour faire office de générateur. */
+GLineGenerator *g_binary_symbol_produce_label(GBinSymbol *);
+
+
+
 #endif  /* _FORMAT_SYMBOL_H */
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index aa7a9a3..fe7565a 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -9,16 +9,21 @@ libglibext_la_SOURCES =					\
 	delayed-int.h						\
 	delayed.h delayed.c					\
 	gbinportion.h gbinportion.c			\
+	gbuffercache.h gbuffercache.c		\
 	gbufferline.h gbufferline.c			\
 	gbufferview.h gbufferview.c			\
-	gcodebuffer.h gcodebuffer.c			\
 	gnhash.h gnhash.c					\
 	gwidthtracker.h gwidthtracker.c		\
 	linecolumn.h linecolumn.c			\
+	linegen-int.h						\
+	linegen.h linegen.c					\
 	linesegment.h linesegment.c			\
 	proto.h								\
 	signal.h signal.c
 
+libglibext_la_LIBADD = 					\
+	generators/libglibextgenerators.la
+
 libglibext_la_LDFLAGS = 
 
 
@@ -26,7 +31,7 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = 
+SUBDIRS = generators
 
 
 chrysamarshal.h: chrysamarshal.list
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index 4137763..eec9651 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -26,6 +26,7 @@
 
 #include <assert.h>
 #include <malloc.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -33,8 +34,10 @@
 #include <i18n.h>
 
 
+#include "../analysis/human/asm/lang.h" // TODO : REMME -> format !
 #include "../common/extstr.h"
 #include "../common/sort.h"
+#include "../glibext/linegen-int.h"
 
 
 
@@ -49,6 +52,8 @@ struct _GBinPortion
     char *code;                             /* Code de la couleur de fond  */
 
     char *desc;                             /* Désignation humaine         */
+    char **text;                            /* Lignes brutes à représenter */
+    size_t lcount;                          /* Quantité de ces lignes      */
 
     mrange_t range;                         /* Emplacement dans le code    */
 
@@ -73,6 +78,9 @@ static void g_binary_portion_class_init(GBinPortionClass *);
 /* Initialise une instance de portion de données binaires. */
 static void g_binary_portion_init(GBinPortion *);
 
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_binary_portion_interface_init(GLineGeneratorInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_binary_portion_dispose(GBinPortion *);
 
@@ -84,6 +92,26 @@ static bool g_binary_portion_compute_sub_area(const GBinPortion *, phys_t, const
 
 
 
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_binary_portion_count_lines(const GBinPortion *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_binary_portion_compute_addr(const GBinPortion *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_binary_portion_contains_addr(const GBinPortion *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_binary_portion_get_flags(const GBinPortion *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_binary_portion_print(GBinPortion *, GBufferLine *, size_t, size_t);
+
+
+
 /* ------------------------ PARCOURS D'ENSEMBLES DE PORTIONS ------------------------ */
 
 
@@ -98,7 +126,8 @@ static bool g_portion_layer_contains_addr(const GBinPortion *, const vmpa2t *);
 
 
 /* Indique le type défini par la GLib pour les portions de données binaires. */
-G_DEFINE_TYPE(GBinPortion, g_binary_portion, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GBinPortion, g_binary_portion, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_binary_portion_interface_init));
 
 
 /******************************************************************************
@@ -140,6 +169,32 @@ static void g_binary_portion_class_init(GBinPortionClass *klass)
 
 static void g_binary_portion_init(GBinPortion *portion)
 {
+    portion->desc = NULL;
+    portion->text = NULL;
+    portion->lcount = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_portion_interface_init(GLineGeneratorInterface *iface)
+{
+    iface->count = (linegen_count_lines_fc)g_binary_portion_count_lines;
+    iface->compute = (linegen_compute_fc)g_binary_portion_compute_addr;
+    iface->contains = (linegen_contains_fc)g_binary_portion_contains_addr;
+    iface->get_flags = (linegen_get_flags_fc)g_binary_portion_get_flags;
+    iface->print = (linegen_print_fc)g_binary_portion_print;
 
 }
 
@@ -177,11 +232,19 @@ static void g_binary_portion_dispose(GBinPortion *portion)
 
 static void g_binary_portion_finalize(GBinPortion *portion)
 {
+    size_t i;                               /* Boucle de parcours          */
+
     free(portion->code);
 
     if (portion->desc != NULL)
         free(portion->desc);
 
+    for (i = 0; i < portion->lcount; i++)
+        free(portion->text[i]);
+
+    if (portion->text != NULL)
+        free(portion->text);
+
     G_OBJECT_CLASS(g_binary_portion_parent_class)->finalize(G_OBJECT(portion));
 
 }
@@ -260,9 +323,66 @@ int g_binary_portion_compare(const GBinPortion **a, const GBinPortion **b)
 
 void g_binary_portion_set_desc(GBinPortion *portion, const char *desc)
 {
-    if (portion->desc != NULL) free(portion->desc);
+    size_t i;                               /* Boucle de parcours          */
+    GCodingLanguage *lang;                  /* Langage de sortie préféré   */
+
+    if (portion->desc != NULL)
+    {
+        free(portion->desc);
+
+        for (i = 0; i < portion->lcount; i++)
+            free(portion->text[i]);
+
+        if (portion->text != NULL)
+        {
+            free(portion->text);
+            portion->text = NULL;
+        }
+
+    }
+
+    if (desc == NULL)
+        portion->desc = NULL;
+
+    else
+    {
+        portion->desc = strdup(desc);
+
+        /* Constitution du rendu */
+
+        portion->text = calloc(4, sizeof(char *));
+        portion->lcount = 4;
+
+        portion->text[0] = strdup("======================================================");
+        portion->text[1] = strdup("");
+
+        asprintf(&portion->text[2], "%s (%s%s%s%s)", portion->desc, _("rights: "),
+                 portion->rights & PAC_READ ? "r" : "-",
+                 portion->rights & PAC_WRITE ? "w" : "-",
+                 portion->rights & PAC_EXEC ? "x" : "-");
 
-    portion->desc = strdup(desc);
+        portion->text[3] = strdup("");
+        portion->text[4] = strdup("======================================================");
+
+        /* Ajout de la touche "commentaires" */
+
+        lang = g_asm_language_new();
+
+        g_coding_language_encapsulate_comments(lang, &portion->text, &portion->lcount);
+
+        g_object_unref(G_OBJECT(lang));
+
+        /* Ajout de deux bordures vides */
+
+        portion->lcount += 2;
+        portion->text = realloc(portion->text, portion->lcount * sizeof(char *));
+
+        memmove(&portion->text[1], &portion->text[0], (portion->lcount - 2) * sizeof(char *));
+
+        portion->text[0] = NULL;
+        portion->text[portion->lcount - 1] = NULL;
+
+    }
 
 }
 
@@ -346,98 +466,6 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : portion = description de partie à consulter.                 *
-*                buffer  = espace où placer ledit contenu.                    *
-*                msize   = taille idéale des positions et adresses;           *
-*                                                                             *
-*  Description : Insère dans un tampon une description de portion.            *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, MemoryDataSize msize)
-{
-    mrange_t range;                         /* Couverture à fournir        */
-    GBufferLine *line;                      /* Nouvelle ligne à éditer     */
-    char rights[64];                        /* Traduction en texte         */
-
-    /* On ne traite pas les portions anonymes ! */
-    if (portion->desc == NULL) return;
-
-    init_mrange(&range, get_mrange_addr(&portion->range), 0);
-
-    line = g_code_buffer_prepare_new_line(buffer, &range);
-    g_buffer_line_fill_mrange(line, msize, msize);
-
-    g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
-
-    g_code_buffer_append_new_line(buffer, line);
-
-    /* Séparation */
-
-    line = g_code_buffer_prepare_new_line(buffer, &range);
-    g_buffer_line_fill_mrange(line, msize, msize);
-
-    g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD,
-                              "; ======================================================", 56, RTT_COMMENT, NULL);
-
-    g_code_buffer_append_new_line(buffer, line);
-
-    /* Retour à la ligne */
-
-    line = g_code_buffer_prepare_new_line(buffer, &range);
-    g_buffer_line_fill_mrange(line, msize, msize);
-
-    g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL);
-
-    g_code_buffer_append_new_line(buffer, line);
-
-    /* Description */
-
-    line = g_code_buffer_prepare_new_line(buffer, &range);
-    g_buffer_line_fill_mrange(line, msize, msize);
-
-    g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-
-    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL);
-
-    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, portion->desc, strlen(portion->desc), RTT_COMMENT, NULL);
-
-    snprintf(rights, sizeof(rights), " (%s%s%s%s)",
-             _("rights: "),
-             portion->rights & PAC_READ ? "r" : "-",
-             portion->rights & PAC_WRITE ? "w" : "-",
-             portion->rights & PAC_EXEC ? "x" : "-");
-
-    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, rights, strlen(rights), RTT_COMMENT, NULL);
-
-    g_code_buffer_append_new_line(buffer, line);
-
-    /* Retour à la ligne */
-
-    line = g_code_buffer_prepare_new_line(buffer, &range);
-    g_buffer_line_fill_mrange(line, msize, msize);
-
-    g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT, NULL);
-
-    g_code_buffer_append_new_line(buffer, line);
-
-    line = g_code_buffer_prepare_new_line(buffer, &range);
-    g_buffer_line_fill_mrange(line, msize, msize);
-    g_code_buffer_append_new_line(buffer, line);
-
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : portion = description de partie à mettre à jour.             *
 *                tooltip = astuce à compléter. [OUT]                          *
 *                                                                             *
@@ -724,6 +752,133 @@ bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void
 
 
 /* ---------------------------------------------------------------------------------- */
+/*                          OFFRE DE CAPACITES DE GENERATION                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = générateur à consulter.                            *
+*                                                                             *
+*  Description : Indique le nombre de ligne prêtes à être générées.           *
+*                                                                             *
+*  Retour      : Nombre de lignes devant apparaître au final.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t g_binary_portion_count_lines(const GBinPortion *portion)
+{
+    return portion->lcount;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = générateur à consulter.                            *
+*                x       = position géographique sur la ligne concernée.      *
+*                addr    = position en mémoire à analyser.                    *
+*                index   = indice de cette même ligne dans le tampon global.  *
+*                repeat  = indice d'utilisations successives du générateur.   *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_portion_compute_addr(const GBinPortion *portion, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+    copy_vmpa(addr, get_mrange_addr(&portion->range));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = générateur à consulter.                            *
+*                addr    = position en mémoire à analyser.                    *
+*                index   = indice de cette même ligne dans le tampon global.  *
+*                repeat  = indice d'utilisations successives du générateur.   *
+*                                                                             *
+*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
+*                                                                             *
+*  Retour      : Bilan de la détermination, utilisable en comparaisons.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int g_binary_portion_contains_addr(const GBinPortion *portion, const vmpa2t *addr, size_t index, size_t repeat)
+{
+    int result;                             /* Conclusion à retourner      */
+
+    result = cmp_vmpa(addr, get_mrange_addr(&portion->range));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = générateur à consulter.                            *
+*                index   = indice de cette même ligne dans le tampon global.  *
+*                repeat  = indice d'utilisations successives du générateur.   *
+*                                                                             *
+*  Description : Renseigne sur les propriétés liées à un générateur.          *
+*                                                                             *
+*  Retour      : Propriétés particulières associées.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static BufferLineFlags g_binary_portion_get_flags(const GBinPortion *portion, size_t index, size_t repeat)
+{
+    return (repeat == 0 ? BLF_WIDTH_MANAGER : BLF_HAS_CODE);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = générateur à utiliser pour l'impression.           *
+*                line    = ligne de rendu à compléter.                        *
+*                index   = indice de cette même ligne dans le tampon global.  *
+*                repeat  = indice d'utilisations successives du générateur.   *
+*                                                                             *
+*  Description : Imprime dans une ligne de rendu le contenu représenté.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_portion_print(GBinPortion *portion, GBufferLine *line, size_t index, size_t repeat)
+{
+    assert(repeat < portion->lcount);
+
+    g_buffer_line_fill_vmpa(line, get_mrange_addr(&portion->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
+
+    if (portion->text[repeat] != NULL)
+    {
+        g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+
+        g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(portion->text[repeat]), RTT_COMMENT, NULL);
+
+    }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
 /*                          PARCOURS D'ENSEMBLES DE PORTIONS                          */
 /* ---------------------------------------------------------------------------------- */
 
diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h
index 2aa5e1a..4f4b3be 100644
--- a/src/glibext/gbinportion.h
+++ b/src/glibext/gbinportion.h
@@ -30,7 +30,6 @@
 #include <gtk/gtk.h>
 
 
-#include "gcodebuffer.h"
 #include "../arch/vmpa.h"
 #include "../common/fnv1a.h"
 
@@ -100,9 +99,6 @@ void g_binary_portion_set_rights(GBinPortion *, PortionAccessRights);
 /* Fournit les droits associés à une partie de code. */
 PortionAccessRights g_binary_portion_get_rights(const GBinPortion *);
 
-/* Insère dans un tampon une description de portion. */
-void g_binary_portion_print(const GBinPortion *, GCodeBuffer *, MemoryDataSize);
-
 /* Prépare une astuce concernant une portion pour son affichage. */
 void g_binary_portion_query_tooltip(GBinPortion *, GtkTooltip *);
 
diff --git a/src/glibext/gbuffercache.c b/src/glibext/gbuffercache.c
new file mode 100644
index 0000000..57a9487
--- /dev/null
+++ b/src/glibext/gbuffercache.c
@@ -0,0 +1,1625 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gbuffercache.c - affichage à la demande d'un ensemble de lignes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "gbuffercache.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+
+#include "chrysamarshal.h"
+
+
+
+/* --------------------- FONCTIONS AUXILIAIRES DE MANIPULATIONS --------------------- */
+
+
+/* Informations rattachées à la génération d'une ligne */
+typedef struct _generator_link
+{
+    GLineGenerator *instance;               /* Fournisseur de contenu      */
+    size_t repeat;                          /* Compteur de successions     */
+
+} generator_link;
+
+/* Suivi interne de l'état d'une ligne */
+typedef struct _cache_info
+{
+    union
+    {
+        generator_link generator;           /* Générateur unique           */
+        generator_link *generators;         /* Liste de générateurs        */
+    };
+    size_t count;                           /* Taille de cette liste       */
+
+    GBufferLine *line;                      /* Ligne en place ou NULL      */
+
+    BufferLineFlags extra_flags;            /* Propriétés supplémentaires  */
+
+} cache_info;
+
+
+/* Gros verrou global pour alléger les structures... */
+G_LOCK_DEFINE_STATIC(_line_update);
+
+
+/* Met en place un nouvel ensemble d'information sur une ligne. */
+static void init_cache_info(cache_info *, GLineGenerator *, size_t, BufferLineFlags);
+
+/* Libère la mémoire occupée par des informations sur une ligne. */
+static void release_cache_info(cache_info *);
+
+/* Ajoute un générateur aux informations sur une ligne. */
+static void extend_cache_info(cache_info *, GLineGenerator *);
+
+/* Retire un générateur aux informations d'une ligne. */
+static void remove_from_cache_info(cache_info *, GLineGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position de ligne. */
+static void get_cache_info_addr(const cache_info *, size_t, gint, vmpa2t *);
+
+/* Suivit les variations du compteur de références d'une ligne. */
+static void on_line_ref_toggle(cache_info *, GBufferLine *, gboolean);
+
+/* Fournit la ligne de tampon correspondant aux générateurs. */
+static GBufferLine *get_cache_info_line(cache_info *, size_t);
+
+/* Force la réinitialisation d'une éventuelle ligne cachée. */
+static void reset_cache_info_line(cache_info *);
+
+
+
+/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
+
+
+/* Tampon pour gestion de lignes optimisée (instance) */
+struct _GBufferCache
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    cache_info *lines;                      /* Liste des lignes intégrées  */
+    size_t count;                           /* Quantité en cache           */
+    size_t used;                            /* Quantité utilisée           */
+
+    GWidthTracker *tracker;                 /* Suivi des largeurs          */
+
+};
+
+/* Tampon pour gestion de lignes optimisée (classe) */
+struct _GBufferCacheClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    gint line_height;                       /* Hauteur maximale des lignes */
+    gint left_margin;                       /* Marge gauche + espace       */
+    gint text_pos;                          /* Début d'impression du code  */
+
+    /* Signaux */
+
+    void (* size_changed) (GBufferCache *, bool, size_t, size_t);
+
+};
+
+
+/* Taille des allocations de masse */
+#define LINE_ALLOC_BULK 1000
+
+
+/* Procède à l'initialisation d'une classe de tampon de lignes. */
+static void g_buffer_cache_class_init(GBufferCacheClass *);
+
+/* Procède à l'initialisation d'un tampon de gestion de lignes. */
+static void g_buffer_cache_init(GBufferCache *);
+
+/* Supprime toutes les références externes. */
+static void g_buffer_cache_dispose(GBufferCache *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_buffer_cache_finalize(GBufferCache *);
+
+/* Calcule l'indice d'apparition d'un générateur dans le tampon. */
+static size_t g_buffer_cache_compute_repetition(GBufferCache *, size_t, GLineGenerator *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       FONCTIONS AUXILIAIRES DE MANIPULATIONS                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info      = informations concernant une ligne à constituer.  *
+*                generator = générateur à associer à toutes les lignes.       *
+*                repeat    = compteur de répétition entre les lignes.         *
+*                flags     = propriétés supplémentaires à associer à la ligne.*
+*                                                                             *
+*  Description : Met en place un nouvel ensemble d'information sur une ligne. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void init_cache_info(cache_info *info, GLineGenerator *generator, size_t repeat, BufferLineFlags flags)
+{
+    info->generator.instance = generator;
+    info->generator.repeat = repeat;
+
+    g_object_ref(G_OBJECT(generator));
+
+    info->count = 1;
+
+    info->line = NULL;
+
+    info->extra_flags = flags;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info = informations concernant une ligne à constituer.       *
+*                                                                             *
+*  Description : Libère la mémoire occupée par des informations sur une ligne.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void release_cache_info(cache_info *info)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    if (info->count == 1)
+        g_object_unref(G_OBJECT(info->generator.instance));
+
+    else
+        for (i = 0; i < info->count; i++)
+            g_object_unref(G_OBJECT(info->generators[i].instance));
+
+    reset_cache_info_line(info);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info      = informations concernant une ligne à actualiser.  *
+*                generator = générateur à associer à toutes les lignes.       *
+*                                                                             *
+*  Description : Ajoute un générateur aux informations sur une ligne.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void extend_cache_info(cache_info *info, GLineGenerator *generator)
+{
+    generator_link first;                   /* Générateur déjà en place    */
+    generator_link *new;                    /* Nouveau générateur placé    */
+
+    if (info->count == 1)
+    {
+        first = info->generator;
+
+        info->generators = (generator_link *)calloc(2, sizeof(generator_link));
+
+        info->generators[0] = first;
+        info->count = 2;
+
+        new = &info->generators[1];
+
+    }
+    else
+    {
+        info->generators = (generator_link *)realloc(info->generators,
+                                                     ++info->count * sizeof(generator_link));
+
+        new = &info->generators[info->count - 1];
+
+    }
+
+    new->instance = generator;
+    new->repeat = 0;
+
+    g_object_ref(G_OBJECT(generator));
+
+    reset_cache_info_line(info);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info      = informations concernant une ligne à actualiser.  *
+*                generator = générateur à dissocier de toutes les lignes.     *
+*                                                                             *
+*  Description : Retire un générateur aux informations d'une ligne.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void remove_from_cache_info(cache_info *info, GLineGenerator *generator)
+{
+    generator_link *link;                   /* Accès simplifié             */
+    size_t i;                               /* Boucle de parcours          */
+    generator_link *old;                    /* Mémorisation avant opérat°  */
+
+    if (info->count == 1)
+    {
+        link = &info->generator;
+
+        assert(link->instance == generator);
+
+        g_object_unref(G_OBJECT(generator));
+
+        info->count = 0;
+
+    }
+
+    else
+    {
+        for (i = 0; i < info->count; i++)
+        {
+            link = &info->generators[i];
+
+            if (link->instance == generator)
+            {
+                if ((i + 1) < info->count)
+                    memmove(&info->generators[i], &info->generators[i + 1],
+                            (info->count - i - 1) * sizeof(generator_link));
+
+                if (info->count == 2)
+                {
+                    old = info->generators;
+
+                    info->count = 1;
+                    info->generator = info->generators[0];
+
+                    free(old);
+
+                }
+                else
+                    info->generators = (generator_link *)realloc(info->generators,
+                                                                 --info->count * sizeof(generator_link));
+
+                break;
+
+            }
+
+        }
+
+#ifndef NDEBUG
+
+        /**
+         * Attention : si l'élément était en dernière position,
+         * l'indice de parcours est désormais égal au nombre de générateurs présents !
+         */
+        assert(i <= info->count);
+
+        for ( ; i < info->count; i++)
+        {
+            link = &info->generators[i];
+
+            assert(link->instance != generator);
+
+        }
+
+#endif
+
+    }
+
+    reset_cache_info_line(info);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info  = informations sur une ligne à venir consulter.        *
+*                index = indice de la ligne visée par la consultation.        *
+*                x     = position géographique sur la ligne concernée.        *
+*                addr  = adresse à renseigner. [OUT]                          *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position de ligne.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void get_cache_info_addr(const cache_info *info, size_t index, gint x, vmpa2t *addr)
+{
+    const generator_link *generator;        /* Générateur retenu           */
+
+    if (info->count == 1)
+        generator = &info->generator;
+    else
+        generator = &info->generators[0];
+
+    g_line_generator_compute_addr(generator->instance, x, addr, index, generator->repeat);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info = informations sur une ligne à venir manipuler.         *
+*                line = tampon de lignes à venir supprimer au besoin.         *
+*                last = indication sur la valeur du compteur de références.   *
+*                                                                             *
+*  Description : Suivit les variations du compteur de références d'une ligne. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void on_line_ref_toggle(cache_info *info, GBufferLine *line, gboolean last)
+{
+    if (last)
+    {
+        G_LOCK(_line_update);
+
+        assert(info->line != NULL);
+
+        info->line = NULL;
+
+        G_UNLOCK(_line_update);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info  = informations sur une ligne à venir manipuler.        *
+*                index = indice de la ligne à constituer.                     *
+*                                                                             *
+*  Description : Fournit la ligne de tampon correspondant aux générateurs.    *
+*                                                                             *
+*  Retour      : Ligne déjà en place ou créée pour le besoin.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GBufferLine *get_cache_info_line(cache_info *info, size_t index)
+{
+    GBufferLine *result;                    /* Construction à retourner    */
+    size_t i;                               /* Boucle de parcours          */
+
+    G_LOCK(_line_update);
+
+    result = info->line;
+
+    if (result == NULL)
+    {
+        result = g_buffer_line_new((mrange_t []){ { { 0 }, 0 } }, 0/* !! */);
+
+        g_object_add_toggle_ref(G_OBJECT(result), (GToggleNotify)on_line_ref_toggle, info);
+
+        if (info->count == 1)
+            g_line_generator_print(info->generator.instance, result, index, info->generator.repeat);
+
+        else
+            for (i = 0; i < info->count; i++)
+                g_line_generator_print(info->generators[i].instance, result, index, info->generators[i].repeat);
+
+        info->line = result;
+
+    }
+
+    else
+        g_object_ref(G_OBJECT(result));
+
+    G_UNLOCK(_line_update);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info = informations sur une ligne à venir manipuler.         *
+*                                                                             *
+*  Description : Force la réinitialisation d'une éventuelle ligne cachée.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void reset_cache_info_line(cache_info *info)
+{
+    G_LOCK(_line_update);
+
+    if (info->line != NULL)
+    {
+        g_object_remove_toggle_ref(G_OBJECT(info->line), (GToggleNotify)on_line_ref_toggle, info);
+
+        g_object_unref(G_OBJECT(info->line));
+
+        info->line = NULL;
+
+    }
+
+    G_UNLOCK(_line_update);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            TAMPON POUR CODE DESASSEMBLE                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type du composant de tampon pour gestion de lignes optimisée. */
+G_DEFINE_TYPE(GBufferCache, g_buffer_cache, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe de composant GLib à initialiser.              *
+*                                                                             *
+*  Description : Procède à l'initialisation d'une classe de tampon de lignes. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_buffer_cache_class_init(GBufferCacheClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_cache_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_buffer_cache_finalize;
+
+    class->line_height = 17;
+    class->left_margin = 2 * class->line_height;
+    class->text_pos = 2.5 * class->line_height;
+
+    /* Signaux */
+
+    g_signal_new("size-changed",
+                 G_TYPE_BUFFER_CACHE,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GBufferCacheClass, size_changed),
+                 NULL, NULL,
+                 g_cclosure_user_marshal_VOID__BOOLEAN_ULONG_ULONG,
+                 G_TYPE_NONE, 3, G_TYPE_BOOLEAN, G_TYPE_ULONG, G_TYPE_ULONG);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = composant GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation d'un tampon de gestion de lignes. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_buffer_cache_init(GBufferCache *cache)
+{
+    cache->tracker = g_width_tracker_new(cache);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_buffer_cache_dispose(GBufferCache *cache)
+{
+    size_t i;                               /* Boucle de parcours #1       */
+    cache_info *info;                       /* Accès directe à une ligne   */
+    size_t j;                               /* Boucle de parcours #2       */
+
+    for (i = 0; i < cache->used; i++)
+    {
+        info = &cache->lines[i];
+
+        if (info->count == 1)
+            g_object_unref(G_OBJECT(info->generator.instance));
+
+        else
+            for (j = 0; j < info->count; j++)
+                g_object_unref(G_OBJECT(info->generators[j].instance));
+
+        if (info->line)
+            g_object_unref(G_OBJECT(info->line));
+
+    }
+
+    g_object_unref(G_OBJECT(cache->tracker));
+
+    G_OBJECT_CLASS(g_buffer_cache_parent_class)->dispose(G_OBJECT(cache));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_buffer_cache_finalize(GBufferCache *cache)
+{
+    size_t i;                               /* Boucle de parcours          */
+    cache_info *info;                       /* Accès directe à une ligne   */
+
+    for (i = 0; i < cache->used; i++)
+    {
+        info = &cache->lines[i];
+
+        if (info->count > 1)
+            free(info->generators);
+
+    }
+
+    if (cache->lines != NULL)
+        free(cache->lines);
+
+    G_OBJECT_CLASS(g_buffer_cache_parent_class)->finalize(G_OBJECT(cache));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un nouveau composant de tampon pour code désassemblé.   *
+*                                                                             *
+*  Retour      : Composant GLib créé.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBufferCache *g_buffer_cache_new(void)
+{
+    GBufferCache *result;                   /* Composant à retourner       */
+
+    result = g_object_new(G_TYPE_BUFFER_CACHE, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à consulter.                        *
+*                                                                             *
+*  Description : Fournit la hauteur d'impression d'une ligne visualisée.      *
+*                                                                             *
+*  Retour      : Hauteur de ligne en pixels.                                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+gint g_buffer_cache_get_line_height(const GBufferCache *cache)
+{
+    GBufferCacheClass *class;               /* Classe des tampons          */
+
+    class = G_BUFFER_CACHE_GET_CLASS(cache);
+
+    return class->line_height;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à consulter.                        *
+*                                                                             *
+*  Description : Fournit la taille réservée pour la marge gauche.             *
+*                                                                             *
+*  Retour      : Largeur en pixels.                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+gint g_buffer_cache_get_left_margin(const GBufferCache *cache)
+{
+    GBufferCacheClass *class;               /* Classe des tampons          */
+
+    class = G_BUFFER_CACHE_GET_CLASS(cache);
+
+    return class->left_margin;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à consulter.                        *
+*                                                                             *
+*  Description : Fournit la position de départ pour l'impression de texte.    *
+*                                                                             *
+*  Retour      : Position en pixels.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+gint g_buffer_cache_get_text_position(const GBufferCache *cache)
+{
+    GBufferCacheClass *class;               /* Classe des tampons          */
+
+    class = G_BUFFER_CACHE_GET_CLASS(cache);
+
+    return class->text_pos;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = instance GLib à consulter.                           *
+*                                                                             *
+*  Description : Compte le nombre de lignes rassemblées dans un tampon.       *
+*                                                                             *
+*  Retour      : Nombre de lignes constituant le tampon.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_buffer_cache_count_lines(const GBufferCache *cache)
+{
+    return cache->used;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = composant GLib à consulter.                          *
+*                                                                             *
+*  Description : Fournit un lien vers la structure de suivi de largeurs.      *
+*                                                                             *
+*  Retour      : Gestionnaire de largeurs de lignes.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache)
+{
+    return cache->tracker;
+
+}
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache     = instance GLib à consulter.                       *
+*                index     = indice de la ligne où se trouve le générateur.   *
+*                generator = générateur associé à au moins une ligne.         *
+*                                                                             *
+*  Description : Calcule l'indice d'apparition d'un générateur dans le tampon.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t index, GLineGenerator *generator)
+{
+    size_t result;                          /* Compteur à retourner        */
+    cache_info *info;                       /* Accès directe à une ligne   */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = 0;
+
+    if (index > 0)
+    {
+        info = &cache->lines[index - 1];
+
+        if (info->count == 1)
+        {
+            if (info->generator.instance == generator)
+                result = info->generator.repeat + 1;
+
+        }
+
+        else
+            for (i = 0; i < info->count; i++)
+                if (info->generators[i].instance == generator)
+                {
+                    result = info->generators[i].repeat + 1;
+                    break;
+                }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache     = instance GLib à modifier.                        *
+*                index     = point d'insertion, puis de sauvegarde.           *
+*                generator = générateur à insérer dans les lignes.            *
+*                before    = précise l'emplacement final des nouvelles lignes.*
+*                after     = précise l'emplacement final des nouvelles lignes.*
+*                                                                             *
+*  Description : Insère un générateur dans des lignes à une position donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, bool before, bool after)
+{
+#ifndef NDEBUG
+    vmpa2t gen_addr;                        /* Position du générateur      */
+    vmpa2t line_addr;                       /* Position de la ligne        */
+#endif
+    size_t needed;                          /* Emplacements nécessaires    */
+    size_t i;                               /* Boucle de parcours          */
+
+    assert(index < cache->used);
+
+    assert(!(before && after));
+
+#ifndef NDEBUG
+
+    g_line_generator_compute_addr(generator, 0, &gen_addr, index, 0);
+
+    get_cache_info_addr(&cache->lines[index], index, 0, &line_addr);
+
+    ///////////////////////////////////////
+    if (cmp_vmpa(&gen_addr, &line_addr) != 0) return;
+
+    assert(cmp_vmpa(&gen_addr, &line_addr) == 0);
+
+#endif
+
+    /* Cas particulier d'ajout en fin de cache... */
+    if (after && (index + 1) == cache->used)
+    {
+        g_buffer_cache_append(cache, generator, BLF_NONE);
+        goto gbcia_done;
+    }
+
+    /* Adaptation de l'espace */
+
+    needed = g_line_generator_count_lines(generator);
+
+    if (before || after)
+    {
+        if ((cache->used + needed) >= cache->count)
+        {
+            cache->count += needed + LINE_ALLOC_BULK;
+            cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
+        }
+    }
+#ifndef NDEBUG
+    else
+        assert(needed == 1);
+#endif
+
+    /* Insertion du générateur */
+
+    if (after)
+        index++;
+
+    if (before || after)
+    {
+        memmove(&cache->lines[index], &cache->lines[index + needed], (cache->used - index) * sizeof(cache_info));
+
+        for (i = 0; i < needed; i++)
+            init_cache_info(&cache->lines[index + i], generator, i, BLF_NONE);
+
+        cache->used += needed;
+
+        g_width_tracker_update_added(cache->tracker, index, needed);
+
+        g_signal_emit_by_name(cache, "size-changed", true, index, needed);
+
+    }
+
+    else
+    {
+        extend_cache_info(&cache->lines[index], generator);
+
+        g_width_tracker_update(cache->tracker, index);
+
+        g_signal_emit_by_name(cache, "size-changed", true, index, 1);
+
+    }
+
+ gbcia_done:
+
+    ;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache  = instance GLib à modifier.                           *
+*                index  = point d'insertion, puis de sauvegarde.              *
+*                type   = type de générateurs à retirer des lignes visées.    *
+*                before = précise l'emplacement final de l'élément visé.      *
+*                after  = précise l'emplacement final de l'élément visé.      *
+*                                                                             *
+*  Description : Retire un type de générateur de lignes.                      *
+*                                                                             *
+*  Retour      : Générateur éventuellement trouvé ou NULL si aucun.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after)
+{
+    GLineGenerator *result;                 /* Prédécesseur à retourner    */
+    cache_info *info;                       /* Accès directe à une ligne   */
+    generator_link *link;                   /* Accès simplifié             */
+    size_t i;                               /* Boucle de parcours          */
+    size_t count;                           /* Emplacements occupés        */
+    size_t delete;                          /* Indice de suppression       */
+
+    assert(index < cache->used);
+
+    assert(!(before && after));
+
+    result = NULL;
+
+    /* Recherche d'un générateur correspondant */
+
+    if (before)
+        info = &cache->lines[index - 1];
+    else if (after)
+        info = &cache->lines[index + 1];
+    else
+        info = &cache->lines[index];
+
+    if (info->count == 1)
+    {
+        link = &info->generator;
+
+        if (G_OBJECT_TYPE(link->instance) == type)
+            result = link->instance;
+
+    }
+
+    else
+        for (i = 0; i < info->count && result == NULL; i++)
+        {
+            link = &info->generators[i];
+
+            if (G_OBJECT_TYPE(link->instance) == type)
+                result = link->instance;
+
+        }
+
+    /* Retrait de l'instance trouvée */
+
+    if (result != NULL)
+    {
+        count = g_line_generator_count_lines(result);
+
+#ifndef NDEBUG
+        if (!before && !after)
+            assert(count == 1);
+#endif
+
+        g_object_ref(G_OBJECT(result));
+
+        /* Suppression de l'élément */
+
+        for (i = 0; i < count; i++)
+        {
+            if (before)
+                info = &cache->lines[index - 1 - i];
+            else if (after)
+                info = &cache->lines[index + 1 + i];
+            else
+                info = &cache->lines[index];
+
+            remove_from_cache_info(info, result);
+
+        }
+
+        /* Suppression des lignes associées */
+
+        for (i = 0; i < count; i++)
+        {
+            if (before)
+                delete = index - 1;
+            else if (after)
+                delete = index + 1;
+            else
+                delete = index;
+
+            info = &cache->lines[delete];
+
+            if (info->count == 0)
+            {
+                release_cache_info(info);
+
+                if ((delete + 1) < cache->used)
+                    memmove(&cache->lines[delete], &cache->lines[delete + 1],
+                            (cache->used - delete - 1) * sizeof(cache_info));
+
+                cache->used--;
+
+                g_width_tracker_update_deleted(cache->tracker, delete, delete);
+
+                g_signal_emit_by_name(cache, "size-changed", false, delete, 1);
+
+            }
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache     = instance GLib à modifier.                        *
+*                generator = générateur à associer à toutes les lignes.       *
+*                flags     = propriétés supplémentaires à associer à la ligne.*
+*                                                                             *
+*  Description : Ajoute en fin de tampon un générateur de lignes.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, BufferLineFlags flags)
+{
+    size_t count;                           /* Nombre de lignes générées   */
+    size_t index;                           /* Point d'insertion           */
+    size_t i;                               /* Boucle de parcours          */
+    cache_info *info;                       /* Accès directe à une ligne   */
+
+    count = g_line_generator_count_lines(generator);
+
+    assert(count > 0);
+
+    assert((flags != BLF_NONE && count == 1) || flags == BLF_NONE);
+
+    if ((cache->used + count) > cache->count)
+    {
+        cache->count += count + LINE_ALLOC_BULK;
+        cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
+    }
+
+    index = cache->used;
+
+    for (i = 0; i < count; i++)
+    {
+        info = &cache->lines[index + i];
+
+        info->generator.instance = generator;
+        info->generator.repeat = g_buffer_cache_compute_repetition(cache, index + i, generator);
+
+        g_object_ref(G_OBJECT(generator));
+
+        info->count = 1;
+
+        info->line = NULL;
+
+        info->extra_flags = flags;
+
+    }
+
+    cache->used += count;
+
+    g_object_unref(G_OBJECT(generator));
+
+    g_width_tracker_update_added(cache->tracker, index, count);
+
+    g_signal_emit_by_name(cache, "size-changed", true, index, count);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache     = instance GLib à modifier.                        *
+*                count     = quantité totale de lignes à avoir à disposition. *
+*                generator = générateur à associer à toutes les lignes.       *
+*                                                                             *
+*  Description : Etend un tampon avec un générateur de lignes unique.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GLineGenerator *generator)
+{
+    size_t index;                           /* Point d'insertion           */
+    size_t i;                               /* Boucle de parcours          */
+    cache_info *info;                       /* Accès directe à une ligne   */
+    size_t added;                           /* Nombre d'ajouts effectués   */
+
+    assert(count >= cache->used);
+
+    if (count > cache->count)
+    {
+        cache->lines = (cache_info *)realloc(cache->lines, count * sizeof(cache_info));
+        cache->count = count;
+    }
+
+    index = cache->used;
+
+    for (i = index; i < count; i++)
+    {
+        info = &cache->lines[i];
+
+        info->generator.instance = generator;
+        info->generator.repeat = g_buffer_cache_compute_repetition(cache, i, generator);
+
+        g_object_ref(G_OBJECT(generator));
+
+        info->count = 1;
+
+        info->line = NULL;
+
+    }
+
+    added = count - cache->used;
+
+    cache->used = count;
+
+    g_object_unref(G_OBJECT(generator));
+
+    if (added > 0)
+    {
+        g_width_tracker_update_added(cache->tracker, index, added);
+
+        g_signal_emit_by_name(cache, "size-changed", true, index, added);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = instance GLib à modifier.                            *
+*                max   = nombre maximal de lignes à conserver.                *
+*                                                                             *
+*  Description : Réduit le tampon à une quantité de lignes précise.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_cache_truncate(GBufferCache *cache, size_t max)
+{
+    size_t i;                               /* Boucle de parcours #1       */
+    cache_info *info;                       /* Accès directe à une ligne   */
+    size_t j;                               /* Boucle de parcours #2       */
+    size_t removed;                         /* Nombre de retraits effectués*/
+
+    assert(max <= cache->used);
+
+    for (i = max; i < cache->used; i++)
+    {
+        info = &cache->lines[i];
+
+        if (info->count == 1)
+            g_object_unref(G_OBJECT(info->generator.instance));
+
+        else
+        {
+            for (j = 0; j < info->count; j++)
+                g_object_unref(G_OBJECT(info->generators[j].instance));
+
+            free(info->generators);
+
+        }
+
+        reset_cache_info_line(info);
+
+    }
+
+    removed = cache->used - max;
+
+    cache->used = max - 1;
+
+    if (removed > 0)
+    {
+        g_width_tracker_update_deleted(cache->tracker, max, max + removed - 1);
+
+        g_signal_emit_by_name(cache, "size-changed", false, max, removed);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à venir consulter.                  *
+*                index = indice de la ligne visée par la consultation.        *
+*                x     = position géographique sur la ligne concernée.        *
+*                addr  = adresse à renseigner. [OUT]                          *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position de ligne.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_cache_get_line_addr(const GBufferCache *cache, size_t index, gint x, vmpa2t *addr)
+{
+    assert(index < cache->used);
+
+    get_cache_info_addr(&cache->lines[index], index, x, addr);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à venir consulter.                  *
+*                index = indice de la ligne visée par la consultation.        *
+*                                                                             *
+*  Description : Détermine l'ensemble des propriétés attachées à une ligne.   *
+*                                                                             *
+*  Retour      : Somme de toutes les propriétés enregistrées.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *cache, size_t index)
+{
+    BufferLineFlags result;                 /* Somme à renvoyer            */
+    cache_info *info;                       /* Accès directe à une ligne   */
+    const generator_link *generator;        /* Générateur retenu           */
+    size_t i;                               /* Boucle de parcours          */
+
+    assert(index < cache->used);
+
+    info = &cache->lines[index];
+
+    result = info->extra_flags;
+
+    if (info->count == 1)
+    {
+        generator = &info->generator;
+        result |= g_line_generator_get_flags(generator->instance, index, generator->repeat);
+    }
+
+    else
+        for (i = 0; i < info->count; i++)
+        {
+            generator = &info->generators[i];
+            result |= g_line_generator_get_flags(generator->instance, index, generator->repeat);
+        }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à consulter.                        *
+*                index = indice de la ligne recherchée.                       *
+*                                                                             *
+*  Description : Retrouve une ligne au sein d'un tampon avec un indice.       *
+*                                                                             *
+*  Retour      : Line retrouvée ou NULL en cas d'échec.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBufferLine *g_buffer_cache_find_line_by_index(const GBufferCache *cache, size_t index)
+{
+    GBufferLine *result;                    /* Ligne trouvée à retourner   */
+
+    if (index < cache->used)
+        result = get_cache_info_line(&cache->lines[index], index);
+    else
+        result = NULL;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache   = tampon de lignes à venir consulter.                *
+*                index   = indice de la ligne à mesurer.                      *
+*                summary = largeurs maximales à faire évoluer.                *
+*                                                                             *
+*  Description : Fait remonter les largeurs requises par une ligne donnée.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_cache_collect_widths(GBufferCache *cache, size_t index, line_width_summary *summary)
+{
+    GBufferLine *line;                      /* Ligne éphémère à mesurer    */
+
+    line = get_cache_info_line(&cache->lines[index], index);
+
+    g_buffer_line_collect_widths(line, summary);
+
+    g_object_unref(G_OBJECT(line));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache    = visualisation à représenter.                      *
+*                cr       = contexte graphique dédié à la procédure.          *
+*                first    = première ligne à dessiner.                        *
+*                last     = dernière ligne à dessiner.                        *
+*                area     = position et surface à traiter.                    *
+*                display  = règles d'affichage des colonnes modulables.       *
+*                selected = ordonnée d'une ligne sélectionnée ou NULL.        *
+*                list     = liste de contenus à mettre en évidence.           *
+*                                                                             *
+*  Description : Imprime une partie choisie du tampon contenant des lignes.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, size_t last, const cairo_rectangle_int_t *area, const bool *display, const gint *selected, const segcnt_list *list)
+{
+    GBufferCacheClass *class;               /* Classe des tampons          */
+    gint y;                                 /* Point de départ en ordonnée */
+    bool wait_selection;                    /* Sélection déjà passée ?     */
+    size_t i;                               /* Boucle de parcours          */
+    cache_info *info;                       /* Accès directe à une ligne   */
+    line_width_summary summary;             /* Résumé concis des largeurs  */
+    GBufferLine *line;                      /* Ligne à venir dessiner      */
+
+    class = G_BUFFER_CACHE_GET_CLASS(cache);
+
+    y = 0;
+
+    wait_selection = true;
+
+    if (cache->used > 0)
+        for (i = first; i <= last; i++)
+        {
+            /* Si sélection, on sousligne la ligne concernée */
+            if (wait_selection && selected != NULL && *selected == y)
+            {
+                cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.05);
+
+                cairo_rectangle(cr, area->x, y, area->width, class->line_height);
+                cairo_fill(cr);
+
+                wait_selection = false;
+
+            }
+
+            info = &cache->lines[i];
+
+            if (i == first || (g_buffer_cache_get_line_flags(cache, i) & BLF_WIDTH_MANAGER))
+                g_width_tracker_get_local_width_summary(cache->tracker, i, &summary);
+
+            line = get_cache_info_line(info, i);
+
+            g_buffer_line_draw(line, cr, &summary, class->text_pos, y, display, list);
+
+            g_object_unref(G_OBJECT(line));
+
+            y += class->line_height;
+
+        }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à consulter.                        *
+*                addr  = adresse à retrouver dans le tampon.                  *
+*                first = indique si on l'arrête à la première ou la dernière. *
+*                start = borne inférieure des recherches (incluse).           *
+*                end   = borne supérieure des recherches (incluse).           *
+*                                                                             *
+*  Description : Indique l'indice correspondant à une adresse donnée.         *
+*                                                                             *
+*  Retour      : Indice des infos à l'adresse demandée, ou nombre de lignes.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t _g_buffer_cache_find_index_by_addr(const GBufferCache *cache, const vmpa2t *addr, bool first, size_t start, size_t end)
+{
+    size_t result;                          /* Indice à retourner          */
+    cache_info *found;                      /* Eventuel élément trouvé     */
+
+    int find_containing_generator(const vmpa2t *a, const cache_info *i)
+    {
+        const generator_link *generator;    /* Générateur retenu           */
+
+        if (i->count == 1)
+            generator = &i->generator;
+        else
+            generator = &i->generators[0];
+
+        return g_line_generator_contains_addr(generator->instance, addr,
+                                              i - cache->lines, generator->repeat);
+
+    }
+
+    found = (cache_info *)bsearch(addr, &cache->lines[start], end - start + 1,
+                                  sizeof(cache_info), (__compar_fn_t)find_containing_generator);
+
+    if (found == NULL)
+        result = cache->used;
+
+    else
+    {
+        result = (found - cache->lines);
+        assert(start <= result && result <= end);
+
+        /* On s'assure d'un arrêt sur la bonne ligne */
+
+        if (first)
+            for (; result > start; result--)
+            {
+                found = &cache->lines[result - 1];
+
+                if (find_containing_generator(addr, found) != 0)
+                    break;
+
+            }
+
+        else
+            for (; result < end; result++)
+            {
+                found = &cache->lines[result + 1];
+
+                if (find_containing_generator(addr, found) != 0)
+                    break;
+
+            }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à consulter.                        *
+*                addr  = adresse à retrouver dans le tampon.                  *
+*                first = indique si on l'arrête à la première ou la dernière. *
+*                                                                             *
+*  Description : Indique l'indice correspondant à une adresse donnée.         *
+*                                                                             *
+*  Retour      : Indice des infos à l'adresse demandée, ou nombre de lignes.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_buffer_cache_find_index_by_addr(const GBufferCache *cache, const vmpa2t *addr, bool first)
+{
+    size_t result;                          /* Indice à retourner          */
+
+    if (cache->used == 0)
+        result = 0;
+    else
+        result = _g_buffer_cache_find_index_by_addr(cache, addr, first, 0, cache->used - 1);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à consulter.                        *
+*                start = point de départ du parcours.                         *
+*                flag  = propriétés à retrouver si possible.                  *
+*                                                                             *
+*  Description : Avance autant que possible vers une ligne idéale.            *
+*                                                                             *
+*  Retour      : Indice de la ligne recherchée, si elle existe.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_buffer_cache_look_for_flag(const GBufferCache *cache, size_t start, BufferLineFlags flag)
+{
+    size_t result;                          /* Indice de ligne à retourner */
+    vmpa2t start_addr;                      /* Localisation de départ      */
+    size_t i;                               /* Boucle de parcours          */
+    vmpa2t addr;                            /* Localisation suivante       */
+
+    assert(start < cache->used);
+
+    result = start;
+
+    get_cache_info_addr(&cache->lines[start], start, 0, &start_addr);
+
+    for (i = start + 1; i < cache->used; i++)
+    {
+        get_cache_info_addr(&cache->lines[i], i, 0, &addr);
+
+        if (cmp_vmpa(&start_addr, &addr) != 0)
+            break;
+
+        if ((g_buffer_cache_get_line_flags(cache, i) & flag) != 0)
+        {
+            result = i;
+            break;
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cache = tampon de lignes à consulter.                        *
+*                addr  = adresse à présenter à l'écran.                       *
+*                first = borne inférieure des recherches (incluse).           *
+*                last  = borne supérieure des recherches (incluse).           *
+*                code  = s'arrête si possible à une ligne avec code.          *
+*                x     = position horizontale au sein du composant. [OUT]     *
+*                y     = position verticale au sein du composant. [OUT]       *
+*                                                                             *
+*  Description : Indique la position d'affichage d'une adresse donnée.        *
+*                                                                             *
+*  Retour      : true si l'adresse fait partie du composant, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_buffer_cache_get_address_coordinates(const GBufferCache *cache, const vmpa2t *addr, size_t first, size_t last, bool code, gint *x, gint *y)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t index;                           /* Indice de correspondance    */
+    gint lheight;                           /* Hauteur d'une ligne         */
+    const cache_info *info;                 /* Infos sur une ligne donnée  */
+    const generator_link *generator;        /* Générateur retenu           */
+
+    index = _g_buffer_cache_find_index_by_addr(cache, addr, true, first, last);
+
+    result = (index < cache->used);
+
+    if (result)
+    {
+        lheight = G_BUFFER_CACHE_GET_CLASS(cache)->line_height;
+
+        *x = 0;
+        *y = (index - first) * G_BUFFER_CACHE_GET_CLASS(cache)->line_height;
+
+        for (; code && index <= last; index++)
+        {
+            if (g_buffer_cache_get_line_flags(cache, index) & BLF_HAS_CODE)
+                break;
+
+            if (index == last)
+                break;
+
+            info = &cache->lines[index + 1];
+
+            if (info->count == 1)
+                generator = &info->generator;
+            else
+                generator = &info->generators[0];
+
+            if (!g_line_generator_contains_addr(generator->instance, addr, index + 1, generator->repeat))
+                break;
+
+            *y += lheight;
+
+        }
+
+    }
+
+    return result;
+
+}
diff --git a/src/glibext/gbuffercache.h b/src/glibext/gbuffercache.h
new file mode 100644
index 0000000..6e9c314
--- /dev/null
+++ b/src/glibext/gbuffercache.h
@@ -0,0 +1,121 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gbuffercache.h - prototypes pour l'affichage à la demande d'un ensemble de lignes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GLIBEXT_GBUFFERCACHE_H
+#define _GLIBEXT_GBUFFERCACHE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <gdk/gdk.h>
+
+
+#include "gwidthtracker.h"
+#include "linegen.h"
+
+
+
+/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
+
+
+#define G_TYPE_BUFFER_CACHE             (g_buffer_cache_get_type())
+#define G_BUFFER_CACHE(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GBufferCache))
+#define G_BUFFER_CACHE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GBufferCacheClass))
+#define G_IS_BUFFER_CACHE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
+#define G_IS_BUFFER_CACHE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
+#define G_BUFFER_CACHE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GBufferCacheClass))
+
+
+/* Tampon pour gestion de lignes optimisée (instance) */
+typedef struct _GBufferCache GBufferCache;
+
+/* Tampon pour gestion de lignes optimisée (classe) */
+typedef struct _GBufferCacheClass GBufferCacheClass;
+
+
+/* Détermine le type du composant de tampon pour gestion de lignes optimisée. */
+GType g_buffer_cache_get_type(void);
+
+/* Crée un nouveau composant de tampon pour code désassemblé. */
+GBufferCache *g_buffer_cache_new(void);
+
+/* Fournit la hauteur d'impression d'une ligne visualisée. */
+gint g_buffer_cache_get_line_height(const GBufferCache *);
+
+/* Fournit la taille réservée pour la marge gauche. */
+gint g_buffer_cache_get_left_margin(const GBufferCache *);
+
+/* Fournit la position de départ pour l'impression de texte. */
+gint g_buffer_cache_get_text_position(const GBufferCache *);
+
+/* Compte le nombre de lignes rassemblées dans un tampon. */
+size_t g_buffer_cache_count_lines(const GBufferCache *);
+
+/* Fournit un lien vers la structure de suivi de largeurs. */
+const GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *);
+
+/* Insère un générateur dans des lignes à une position donnée. */
+void g_buffer_cache_insert_at(GBufferCache *, size_t, GLineGenerator *, bool, bool);
+
+/* Retire un type de générateur de lignes. */
+GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *, size_t, GType, bool, bool);
+
+/* Ajoute en fin de tampon un générateur de lignes. */
+void g_buffer_cache_append(GBufferCache *, GLineGenerator *, BufferLineFlags);
+
+/* Etend un tampon avec un générateur de lignes unique. */
+void g_buffer_cache_extend_with(GBufferCache *, size_t, GLineGenerator *);
+
+/* Réduit le tampon à une quantité de lignes précise. */
+void g_buffer_cache_truncate(GBufferCache *, size_t);
+
+/* Retrouve l'emplacement correspondant à une position de ligne. */
+void g_buffer_cache_get_line_addr(const GBufferCache *, size_t, gint, vmpa2t *);
+
+/* Détermine l'ensemble des propriétés attachées à une ligne. */
+BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *, size_t);
+
+/* Retrouve une ligne au sein d'un tampon avec un indice. */
+GBufferLine *g_buffer_cache_find_line_by_index(const GBufferCache *, size_t);
+
+/* Fait remonter les largeurs requises par une ligne donnée. */
+void g_buffer_cache_collect_widths(GBufferCache *, size_t, line_width_summary *);
+
+/* Imprime une partie choisie du tampon contenant des lignes. */
+void g_buffer_cache_draw(const GBufferCache *, cairo_t *, size_t, size_t, const cairo_rectangle_int_t *, const bool *, const gint *, const segcnt_list *);
+
+/* Indique l'indice correspondant à une adresse donnée. */
+size_t _g_buffer_cache_find_index_by_addr(const GBufferCache *, const vmpa2t *, bool, size_t, size_t);
+
+/* Indique l'indice correspondant à une adresse donnée. */
+size_t g_buffer_cache_find_index_by_addr(const GBufferCache *, const vmpa2t *, bool);
+
+/* Avance autant que possible vers une ligne idéale. */
+size_t g_buffer_cache_look_for_flag(const GBufferCache *, size_t, BufferLineFlags);
+
+/* Indique la position d'affichage d'une adresse donnée. */
+bool g_buffer_cache_get_address_coordinates(const GBufferCache *, const vmpa2t *, size_t, size_t, bool, gint *, gint *);
+
+
+
+#endif  /* _GLIBEXT_GBUFFERCACHE_H */
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 5f1756d..768cbca 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -56,7 +56,7 @@ struct _GBufferLine
     mrange_t range;                         /* Couverture geographique     */
     BufferLineColumn main_column;           /* Colonne principale          */
 
-    line_column columns[BLC_COUNT];  /* Répartition du texte        */
+    line_column columns[BLC_COUNT];         /* Répartition du texte        */
     BufferLineColumn merge_start;           /* Début de la zone globale    */
     BufferLineColumn last_used;             /* Dernière colonne utilisée   */
 
@@ -72,7 +72,6 @@ struct _GBufferLine
             gint max_widths[BLC_COUNT];     /* Taille cachée des colonnes  */
             gint merged_width;              /* Largeur cumulée avant fusion*/
         };
-        GBufferLine *manager;               /* Représentante d'un groupe   */
     };
 
 };
@@ -214,9 +213,6 @@ static void g_buffer_line_dispose(GBufferLine *line)
 {
     size_t i;                               /* Boucle de parcours          */
 
-    if (line->flags & BLF_WIDTH_MANAGER)
-        g_object_unref(G_OBJECT(line->manager));
-
     for (i = 0; i < line->ocount; i++)
         g_object_unref(G_OBJECT(line->origins[i].creator));
 
@@ -298,9 +294,9 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *line)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : line  = ligne à venir compléter.                             *
-*                psize = taille souhaitée de l'impression des positions.      *
-*                vsize = taille souhaitée de l'impression des adresses.       *
+*  Paramètres  : line = ligne à venir compléter.                              *
+*                size = taille souhaitée de l'impression des positions.       *
+*                addr = localisation physique à venir représenter.            *
 *                                                                             *
 *  Description : Construit le tronc commun d'une ligne autour de sa position. *
 *                                                                             *
@@ -310,61 +306,105 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *line)
 *                                                                             *
 ******************************************************************************/
 
-void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize)
+void g_buffer_line_fill_phys(GBufferLine *line, MemoryDataSize size, const vmpa2t *addr)
 {
+    VMPA_BUFFER(position);                  /* Emplacement au format texte */
     size_t len;                             /* Taille de l'élément inséré  */
-    VMPA_BUFFER(address);                   /* Adresse au format texte     */
-    size_t i;                               /* Boucle de parcours          */
+    size_t i;                               /* Boucle de parcours #1       */
 
-    /* Position physique */
+    vmpa2_phys_to_string(addr, size, position, &len);
 
-	if (has_phys_addr(get_mrange_addr(&line->range)))
-	{
-		mrange_phys_to_string(&line->range, psize, true, address, &len);
+    for (i = 2; i < len; i++)
+        if (position[i] != '0') break;
 
-		for (i = 2; i < len; i++)
-			if (address[i] != '0') break;
+    if (i == len)
+        i = len - 1;
 
-		if (i == len)
-			g_buffer_line_append_text(line, BLC_PHYSICAL, address, len, RTT_PHYS_ADDR_PAD, NULL);
+    if (i > 0)
+        g_buffer_line_append_text(line, BLC_PHYSICAL, position, i, RTT_PHYS_ADDR_PAD, NULL);
 
-		else
-		{
-			g_buffer_line_append_text(line, BLC_PHYSICAL, address, 2, RTT_PHYS_ADDR, NULL);
+    g_buffer_line_append_text(line, BLC_PHYSICAL, &position[i], len - i, RTT_PHYS_ADDR, NULL);
 
-            if (i > 2)
-                g_buffer_line_append_text(line, BLC_PHYSICAL, &address[2], i - 2, RTT_PHYS_ADDR_PAD, NULL);
+}
 
-            g_buffer_line_append_text(line, BLC_PHYSICAL, &address[i], len - i, RTT_PHYS_ADDR, NULL);
 
-		}
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line = ligne à venir compléter.                              *
+*                size = taille souhaitée de l'impression des positions.       *
+*                addr = localisation virtuelle à venir représenter.           *
+*                                                                             *
+*  Description : Construit le tronc commun d'une ligne autour de sa position. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-	}
+void g_buffer_line_fill_virt(GBufferLine *line, MemoryDataSize size, const vmpa2t *addr)
+{
+    VMPA_BUFFER(position);                  /* Emplacement au format texte */
+    size_t len;                             /* Taille de l'élément inséré  */
+    size_t i;                               /* Boucle de parcours #1       */
+
+    vmpa2_virt_to_string(addr, size, position, &len);
+
+    for (i = 2; i < len; i++)
+        if (position[i] != '0') break;
+
+    if (i == len)
+        i = len - 1;
+
+    if (i > 0)
+        g_buffer_line_append_text(line, BLC_VIRTUAL, position, i, RTT_PHYS_ADDR_PAD, NULL);
 
-    /* Adresse virtuelle */
+    g_buffer_line_append_text(line, BLC_VIRTUAL, &position[i], len - i, RTT_PHYS_ADDR, NULL);
+
+}
 
-	if (has_virt_addr(get_mrange_addr(&line->range)))
-	{
-		mrange_virt_to_string(&line->range, vsize, true, address, &len);
 
-		for (i = 2; i < len; i++)
-			if (address[i] != '0') break;
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line  = ligne à venir compléter.                             *
+*                addr  = localisation à afficher.                             *
+*                psize = taille souhaitée de l'impression des positions.      *
+*                vsize = taille souhaitée de l'impression des adresses.       *
+*                                                                             *
+*  Description : Construit le tronc commun d'une ligne autour de sa position. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-		if (i == len)
-			g_buffer_line_append_text(line, BLC_VIRTUAL, address, len, RTT_VIRT_ADDR_PAD, NULL);
+void g_buffer_line_fill_vmpa(GBufferLine *line, const vmpa2t *addr, MemoryDataSize psize, MemoryDataSize vsize)
+{
+    g_buffer_line_fill_phys(line, psize, addr);
 
-		else
-		{
-			g_buffer_line_append_text(line, BLC_VIRTUAL, address, 2, RTT_VIRT_ADDR, NULL);
+    g_buffer_line_fill_virt(line, vsize, addr);
 
-            if (i > 2)
-                g_buffer_line_append_text(line, BLC_VIRTUAL, &address[2], i - 2, RTT_VIRT_ADDR_PAD, NULL);
+}
 
-            g_buffer_line_append_text(line, BLC_VIRTUAL, &address[i], len - i, RTT_VIRT_ADDR, NULL);
 
-		}
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line  = ligne à venir compléter.                             *
+*                psize = taille souhaitée de l'impression des positions.      *
+*                vsize = taille souhaitée de l'impression des adresses.       *
+*                                                                             *
+*  Description : Construit le tronc commun d'une ligne autour de sa position. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-	}
+void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize)
+{
+    g_buffer_line_fill_vmpa(line, get_mrange_addr(&line->range), psize, vsize);
 
 }
 
@@ -531,7 +571,7 @@ void g_buffer_line_append_text(GBufferLine *line, BufferLineColumn column, const
     assert(length > 0);
 
     if (column == BLC_MAIN)
-        column = line->main_column;
+        column = BLC_ASSEMBLY;//line->main_column;
 
     if (column == BLC_LAST_USED)
         column = line->last_used;
@@ -938,6 +978,13 @@ void g_buffer_line_collect_widths(GBufferLine *line, line_width_summary *summary
     {
         width = get_column_width(&line->columns[i]);
 
+
+        /*
+        if (i == BLC_ASSEMBLY_HEAD)
+            assert(width > 0);
+        */
+
+
         if (i < line->merge_start)
             summary->max_widths[i] = MAX(summary->max_widths[i], width);
 
@@ -1008,7 +1055,10 @@ const line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *line
 {
     line_segment *result;                   /* Trouvaille à retourner      */
 
-    result = get_line_column_content_from_index(&line->columns[coord->column], coord->index);
+    if (coord->column < BLC_COUNT)
+        result = get_line_column_content_from_index(&line->columns[coord->column], coord->index);
+    else
+        result = false;
 
     return result;
 
@@ -1069,6 +1119,9 @@ bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summar
         {
             width = g_buffer_line_compute_max_width(line, i, summary);
 
+            /* Si la colonne n'est absolument pas visible, on ne s'arrête pas dessus ! */
+            if (width == 0) continue;
+
             if ((i + 1) < BLC_COUNT) limit = width + COL_MARGIN / 2;
             else limit = width;
 
@@ -1139,7 +1192,10 @@ bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summar
                     if ((i - 1) < line->merge_start)
                     {
                         width = g_buffer_line_compute_max_width(line, i - 1, summary);
-                        *base += (width + COL_MARGIN);
+
+                        if (width > 0)
+                            *base += (width + COL_MARGIN);
+
                     }
                     else
                         *base += get_column_width(&line->columns[i - 1]);
@@ -1183,8 +1239,19 @@ bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summar
                 }
 
             }
+
+            /* Il n'y a rien sur la ligne ! */
             else
-                result = false;
+            {
+                result = true;
+
+                *base = 0;
+                *offset = 0;
+
+                coord->column = BLC_COUNT;
+                coord->index = -1;
+
+            }
 
         }
         else
@@ -1305,6 +1372,7 @@ bool g_buffer_line_find_near_coord(const GBufferLine *line, col_coord_t *coord,
     BufferLineColumn i;                     /* Boucle de parcours #1       */
     bool displayed;                         /* Confort de lecture          */
     BufferLineColumn k;                     /* Boucle de parcours #2       */
+    gint width;                             /* Largeur d'une colonne donnée*/
 
     result = false;
 
@@ -1381,8 +1449,14 @@ bool g_buffer_line_find_near_coord(const GBufferLine *line, col_coord_t *coord,
 
             if (displayed)
             {
-                *offset += g_buffer_line_compute_max_width(line, k, summary);
-                if (k < line->merge_start) *offset += COL_MARGIN;
+                width = g_buffer_line_compute_max_width(line, k, summary);
+
+                if (width > 0)
+                {
+                    *offset += width;
+                    if (k < line->merge_start) *offset += COL_MARGIN;
+                }
+
             }
 
         }
@@ -1469,10 +1543,8 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const line_width_summ
         {
             max_width = g_buffer_line_compute_max_width(line, i, summary);
 
-            x += max_width;
-
             if (max_width > 0)
-                x += COL_MARGIN;
+                x += max_width + COL_MARGIN;
 
         }
 
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index be7e138..a8d2f3f 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -109,6 +109,15 @@ GBufferLine *g_buffer_line_new(const mrange_t *, BufferLineColumn);
 const mrange_t *g_buffer_line_get_range(const GBufferLine *);
 
 /* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_phys(GBufferLine *, MemoryDataSize, const vmpa2t *);
+
+/* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_virt(GBufferLine *, MemoryDataSize, const vmpa2t *);
+
+/* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_vmpa(GBufferLine *, const vmpa2t *, MemoryDataSize, MemoryDataSize);
+
+/* Construit le tronc commun d'une ligne autour de sa position. */
 void g_buffer_line_fill_mrange(GBufferLine *, MemoryDataSize, MemoryDataSize);
 
 /* Construit le tronc commun d'une ligne d'instruction. */
diff --git a/src/glibext/gbufferview.c b/src/glibext/gbufferview.c
index 20d60ed..cd17191 100644
--- a/src/glibext/gbufferview.c
+++ b/src/glibext/gbufferview.c
@@ -24,14 +24,21 @@
 #include "gbufferview.h"
 
 
+#include <assert.h>
+
+
 
 /* Vue d'un tampon pour code désassemblé (instance) */
 struct _GBufferView
 {
     GObject parent;                         /* A laisser en premier        */
 
-    GCodeBuffer *buffer;                    /* Tampon de code visualisé    */
+    GBufferCache *cache;                    /* Tampon du contenu visualisé */
+
+    segcnt_list *highlighted;               /* Segments mis en évidence    */
+    bool external;                          /* Note l'origine de la liste  */
 
+    bool unrestricted;                      /* Validité des informations   */
     vmpa2t start;                           /* Première ligne intégrée     */
     vmpa2t end;                             /* Dernière ligne intégrée     */
 
@@ -45,11 +52,6 @@ struct _GBufferView
         GWidthTracker *tracker;             /* Suivi pour usage interne    */
     };
 
-    bool unrestricted;                      /* Validité des informations   */
-
-    segcnt_list *highlighted;               /* Segments mis en évidence    */
-    bool external;                          /* Note l'origine de la liste  */
-
 };
 
 /* Vue d'un tampon pour code désassemblé (classe) */
@@ -57,10 +59,6 @@ struct _GBufferViewClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
-    gint line_height;                       /* Hauteur maximale des lignes */
-    gint left_margin;                       /* Marge gauche + espace       */
-    gint left_text;                         /* Début d'impression du code  */
-
     /* Signaux */
 
     void (* need_redraw) (GBufferView *);
@@ -81,15 +79,23 @@ static void g_buffer_view_dispose(GBufferView *);
 static void g_buffer_view_finalize(GBufferView *);
 
 /* Accompagne une variation de la quantité de lignes du tampon. */
-static void on_buffer_size_changed(const GCodeBuffer *, bool, size_t, size_t, GBufferView *);
+static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, GBufferView *);
 
-/* Réagit à un changement de contenu d'une ligne donnée. */
-static void on_buffer_line_changed(GCodeBuffer *, GBufferLine *, line_segment *, GBufferView *);
+/* Calcule la position idéale de curseur pour un point donné. */
+bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const bool *, GdkRectangle *, vmpa2t *);
 
 /* Déplace le curseur au sein d'une vue de tampon. */
 static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, GdkRectangle *, bool, GdkScrollDirection, const bool *);
 
 
+/* Fournit la ligne présente à une ordonnée donnée. */
+static GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *);
+
+
+
+
+
+
 
 /* Détermine le type de la vue d'un tampon pour code désassemblé. */
 G_DEFINE_TYPE(GBufferView, g_buffer_view, G_TYPE_OBJECT);
@@ -116,10 +122,7 @@ static void g_buffer_view_class_init(GBufferViewClass *class)
     object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_view_dispose;
     object->finalize = (GObjectFinalizeFunc)g_buffer_view_finalize;
 
-    class->line_height = 17;
-    class->left_margin = 2 * class->line_height;
-    class->left_text = 2.5 * class->line_height;
-
+    /* Sigaux */
 
     g_signal_new("need-redraw",
                  G_TYPE_BUFFER_VIEW,
@@ -146,7 +149,10 @@ static void g_buffer_view_class_init(GBufferViewClass *class)
 
 static void g_buffer_view_init(GBufferView *view)
 {
-    view->unrestricted = true;
+    /**
+     * Inversion du statut pour forcer l'actualisation lors de la création.
+     */
+    view->unrestricted = false;
 
 }
 
@@ -165,7 +171,10 @@ static void g_buffer_view_init(GBufferView *view)
 
 static void g_buffer_view_dispose(GBufferView *view)
 {
-    g_object_unref(G_OBJECT(view->buffer));
+    g_object_unref(G_OBJECT(view->cache));
+
+    if (!view->unrestricted)
+        g_object_unref(G_OBJECT(view->int_tracker));
 
     G_OBJECT_CLASS(g_buffer_view_parent_class)->dispose(G_OBJECT(view));
 
@@ -207,22 +216,17 @@ static void g_buffer_view_finalize(GBufferView *view)
 *                                                                             *
 ******************************************************************************/
 
-GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
+GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted)
 {
     GBufferView *result;                    /* Composant à retourner       */
 
     result = g_object_new(G_TYPE_BUFFER_VIEW, NULL);
 
-    g_object_ref(G_OBJECT(buffer));
-    result->buffer = buffer;
+    result->cache = cache;
 
     g_buffer_view_restrict(result, NULL, NULL);
 
-    g_code_buffer_register_view_callback(buffer,
-                                         (buffer_size_changed_cb)on_buffer_size_changed,
-                                         G_OBJECT(result));
-
-    g_signal_connect(buffer, "line-changed", G_CALLBACK(on_buffer_line_changed), result);
+    g_signal_connect(cache, "size-changed", G_CALLBACK(on_buffer_cache_size_changed), result);
 
     if (highlighted != NULL)
         result->highlighted = highlighted;
@@ -238,11 +242,11 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : buffer = tampon de lignes cohérentes à manipuler.            *
-*                added  = indication sur la variation de la taille du tampon. *
-*                index  = indice de la première ligne à traiter.              *
-*                count  = nombre de lignes à traiter.                         *
-*                view   = vue active du tampon de lignes concerné.            *
+*  Paramètres  : cache = tampon de lignes cohérentes à manipuler.             *
+*                added = indication sur la variation de la taille du tampon.  *
+*                index = indice de la première ligne à traiter.               *
+*                count = nombre de lignes à traiter.                          *
+*                view  = vue active du tampon de lignes concerné.             *
 *                                                                             *
 *  Description : Accompagne une variation de la quantité de lignes du tampon. *
 *                                                                             *
@@ -252,11 +256,11 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
 *                                                                             *
 ******************************************************************************/
 
-static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t index, size_t count, GBufferView *view)
+static void on_buffer_cache_size_changed(const GBufferCache *cache, bool added, size_t index, size_t count, GBufferView *view)
 {
-    size_t i;                               /* Boucle de parcours          */
-    GBufferLine *line;                      /* Ligne à manipuler           */
-    const vmpa2t *addr;                     /* Localisation de ligne       */
+    //size_t i;                               /* Boucle de parcours          */
+    //GBufferLine *line;                      /* Ligne à manipuler           */
+    //const vmpa2t *addr;                     /* Localisation de ligne       */
 
     /**
      * Il n'y a pas besoin de verrou ici car la fonction est appelée directement par le tampon.
@@ -270,6 +274,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
 
         else
         {
+#if 0
+
             /* Avant la zone représentée ? */
             if (index < view->first)
             {
@@ -281,6 +287,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
             else if (view->first == index)
                 for (i = 0; i < count; i++)
                 {
+                    g_buffer_cache_get_line_addr(const GBufferCache *, size_t, gint, vmpa2t *);
+
                     line = g_code_buffer_find_line_by_index(buffer, index + i);
                     addr = get_mrange_addr(g_buffer_line_get_range(line));
 
@@ -302,6 +310,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
             else if ((view->last + 1) == index)
                 for (i = 0; i < count; i++)
                 {
+                    g_buffer_cache_get_line_addr(const GBufferCache *, size_t, gint, vmpa2t *);
+
                     line = g_code_buffer_find_line_by_index(buffer, index + i);
                     addr = get_mrange_addr(g_buffer_line_get_range(line));
 
@@ -312,7 +322,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
 
                 }
 
-            g_width_tracker_update_added(view->int_tracker, index, count);
+            //g_width_tracker_update_added(view->int_tracker, index, count);
+#endif
 
         }
 
@@ -338,38 +349,36 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
 
         }
 
-        g_width_tracker_update_deleted(view->int_tracker, index, index + count - 1);
+        //g_width_tracker_update_deleted(view->int_tracker, index, index + count - 1);
 
     }
 
-    g_signal_emit_by_name(view, "need-redraw");
+    //g_signal_emit_by_name(view, "need-redraw");
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : buffer  = tampon de lignes cohérentes à manipuler.           *
-*                line    = ligne dont la définition vient d'évoluer.          *
-*                segment = éventuel segment qui vient d'évoluer ou NULL.      *
-*                view    = vue active du tampon de lignes concerné.           *
+*  Paramètres  : view = visualisateur à consulter.                            *
 *                                                                             *
-*  Description : Réagit à un changement de contenu d'une ligne donnée.        *
+*  Description : Fournit le tampon de code lié à un visualisateur donné.      *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Tampon de code associé au gestionnaire d'affichage.          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, line_segment *segment, GBufferView *view)
+GBufferCache *g_buffer_view_get_cache(const GBufferView *view)
 {
-    const vmpa2t *addr;                     /* Localisation de ligne       */
+    GBufferCache *result;                   /* Instance à retourner        */
 
-    addr = get_mrange_addr(g_buffer_line_get_range(line));
+    result = view->cache;
 
-    if (cmp_vmpa(&view->start, addr) <= 0 && cmp_vmpa(addr, &view->end) <= 0)
-        g_signal_emit_by_name(view, "need-redraw");
+    g_object_ref(G_OBJECT(result));
+
+    return result;
 
 }
 
@@ -390,33 +399,41 @@ static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, line_
 
 void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t *end)
 {
+    bool state;                             /* Nouvel état à proclamer     */
     const GWidthTracker *template;          /* Suivi déjà en place         */
 
-    if (!view->unrestricted)
-        g_object_unref(G_OBJECT(view->int_tracker));
+    state = (start == NULL || end == NULL);
 
-    view->unrestricted = (start == NULL || end == NULL);
+    if (view->unrestricted != state)
+    {
+        view->unrestricted = state;
 
-    template = g_code_buffer_get_width_tracker(view->buffer);
+        template = g_buffer_cache_get_width_tracker(view->cache);
 
-    if (view->unrestricted)
-    {
-        view->first = 0;
-        view->last = g_code_buffer_count_lines(view->buffer) - 1;
+        if (view->unrestricted)
+        {
+            /* Vérification pour le cas particulier du démarrage */
+            if (view->int_tracker != NULL)
+                g_object_unref(G_OBJECT(view->int_tracker));
 
-        view->ext_tracker = template;
+            view->first = 0;
+            view->last = g_buffer_cache_count_lines(view->cache) - 1;
 
-    }
+            view->ext_tracker = template;
 
-    else
-    {
-        copy_vmpa(&view->start, start);
-        copy_vmpa(&view->end, end);
+        }
+
+        else
+        {
+            copy_vmpa(&view->start, start);
+            copy_vmpa(&view->end, end);
+
+            view->first = g_buffer_cache_find_index_by_addr(view->cache, start, true);
+            view->last = g_buffer_cache_find_index_by_addr(view->cache, end, false);
 
-        view->first = g_code_buffer_get_index_from_address(view->buffer, start, true);
-        view->last = g_code_buffer_get_index_from_address(view->buffer, end, false);
+            view->ext_tracker = g_width_tracker_new_restricted(template, view->first, view->last);
 
-        view->ext_tracker = g_width_tracker_new_restricted(template, view->first, view->last);
+        }
 
     }
 
@@ -425,7 +442,7 @@ void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : view  = visualisateur à mettre à jour.                       *
+*  Paramètres  : view  = visualisateur à consulter.                           *
 *                first = première ligne à imprimer ou NULL. [OUT]             *
 *                last  = première ligne hors cadre ou NULL. [OUT]             *
 *                                                                             *
@@ -437,7 +454,7 @@ void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t
 *                                                                             *
 ******************************************************************************/
 
-bool g_buffer_view_get_restrictions(GBufferView *view, vmpa2t *start, vmpa2t *end)
+bool g_buffer_view_get_restrictions(const GBufferView *view, vmpa2t *start, vmpa2t *end)
 {
     if (!view->unrestricted)
     {
@@ -450,44 +467,11 @@ bool g_buffer_view_get_restrictions(GBufferView *view, vmpa2t *start, vmpa2t *en
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = visualisateur à consulter.                            *
-*                                                                             *
-*  Description : Fournit le tampon de code lié à un visualisateur donné.      *
-*                                                                             *
-*  Retour      : Tampon de code associé au gestionnaire d'affichage.          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *view)
-{
-    g_object_ref(G_OBJECT(view->buffer));
-
-    return view->buffer;
 
-}
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = visualisation à consulter.                            *
-*                                                                             *
-*  Description : Fournit la hauteur d'impression d'une ligne visualisée.      *
-*                                                                             *
-*  Retour      : Hauteur de ligne en pixel.                                   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
 
-gint g_buffer_view_get_line_height(GBufferView *view)
-{
-    return G_BUFFER_VIEW_GET_CLASS(view)->line_height;
 
-}
 
 
 /******************************************************************************
@@ -507,7 +491,7 @@ gint g_buffer_view_get_width(GBufferView *view, const bool *display)
 {
     gint result;                            /* Taille à retourner          */
 
-    result = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
+    result = g_buffer_cache_get_text_position(view->cache);
 
     result += g_width_tracker_get_width(view->tracker, display);
 
@@ -533,7 +517,7 @@ gint g_buffer_view_get_margin(GBufferView *view, const bool *display)
 {
     gint result;                            /* Taille à retourner          */
 
-    result = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
+    result = g_buffer_cache_get_text_position(view->cache);
 
     result += g_width_tracker_get_margin(view->tracker, display);
 
@@ -558,7 +542,7 @@ gint g_buffer_view_get_height(const GBufferView *view)
 {
     gint result;                            /* Taille à retourner          */
 
-    result = G_BUFFER_VIEW_GET_CLASS(view)->line_height;
+    result = g_buffer_cache_get_line_height(view->cache);
 
     result *= (view->last - view->first + 1);
 
@@ -567,50 +551,66 @@ gint g_buffer_view_get_height(const GBufferView *view)
 }
 
 
+
+
+
+
+
+
+
+
+
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : view    = vue de tampon à mettre à jour.                     *
-*                x       = abscisse de la zone principale à traiter.          *
-*                y       = ordonnée de la zone principale à traiter.          *
+*                x       = abscisse proposée pour le nouvel emplacement.      *
+*                y       = ordonnée proposée pour le nouvel emplacement.      *
 *                display = règles d'affichage des colonnes modulables.        *
 *                caret   = position du curseur à construire. [OUT]            *
+*                addr    = adresse correspondant à cette même position. [OUT] *
 *                                                                             *
 *  Description : Calcule la position idéale de curseur pour un point donné.   *
 *                                                                             *
-*  Retour      : Adresse si une a pu être déterminée, NULL sinon.             *
+*  Retour      : true si les deux derniers arguments ont pu être constitués.  *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, const bool *display, GdkRectangle *caret)
+bool g_buffer_view_compute_caret_full(GBufferView *view, gint x, gint y, const bool *display, GdkRectangle *caret, vmpa2t *addr)
 {
-    gint remaining;                         /* Copie de travail modifiable */
+    bool result;                            /* Bilan à retourner           */
+    gint lheight;                           /* Hauteur d'une ligne         */
     size_t index;                           /* Indice de ligne de tampon   */
     GBufferLine *line;                      /* Ligne à la position courante*/
-    const line_segment *segment;            /* Segment présent sur la place*/
-    GBufferViewClass *class;                /* Classe pour les vues        */
 
-    remaining = x;
+    result = false;
 
-    line = g_buffer_view_find_line_and_segment_at(view, &remaining, y, &index, display, &segment);
+    /* Détermination de la ligne courante */
 
-    /* FIXME : unref() ! */
-    if (line == NULL) return NULL;
-    if (segment == NULL) printf(" -- no segment\n");
-    if (segment == NULL) return NULL;
+    lheight = g_buffer_cache_get_line_height(view->cache);
+    index = y / lheight;
 
+    index += view->first;
 
-    class = G_BUFFER_VIEW_GET_CLASS(view);
+    if (index > view->last)
+        goto gbvccf_done;
 
-    caret->x = /*view->left_text +*/ (x - remaining) + get_caret_position_from_line_segment(segment, remaining);
+    line = g_buffer_cache_find_line_by_index(view->cache, index);
 
-    caret->y = (index - view->first) * class->line_height;
+    assert(line != NULL);
 
-    caret->width = 2;
-    caret->height = class->line_height;
+    /* Calcul d'une position */
+
+    result = _g_buffer_view_compute_caret_full(view, x, line, index, display, caret, addr);
+
+    g_object_unref(G_OBJECT(line));
+
+ gbvccf_done:
 
-    return get_mrange_addr(g_buffer_line_get_range(line));
+    return result;
 
 }
 
@@ -618,50 +618,69 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, con
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : view    = vue de tampon à mettre à jour.                     *
+*                x       = abscisse proposée pour le nouvel emplacement.      *
 *                line    = ligne correspondant à la position.                 *
 *                index   = indice de cette même ligne dans le tampon.         *
-*                x       = abscisse de la zone principale à traiter.          *
 *                display = règles d'affichage des colonnes modulables.        *
 *                caret   = position du curseur à construire. [OUT]            *
+*                addr    = adresse correspondant à cette même position. [OUT] *
 *                                                                             *
 *  Description : Calcule la position idéale de curseur pour un point donné.   *
 *                                                                             *
-*  Retour      : Adresse si une a pu être déterminée, NULL sinon.             *
+*  Retour      : true si les deux derniers arguments ont pu être constitués.  *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *line, size_t index, gint x, const bool *display, GdkRectangle *caret)
+bool _g_buffer_view_compute_caret_full(GBufferView *view, gint x, GBufferLine *line, size_t index, const bool *display, GdkRectangle *caret, vmpa2t *addr)
 {
-    GBufferViewClass *class;                /* Classe pour les vues        */
-    gint offset;                            /* Point de travail modifiable */
+    bool result;                            /* Bilan à retourner           */
+    gint text_pos;                          /* Abscisse de départ du texte */
     line_width_summary summary;             /* Résumé concis des largeurs  */
     gint base;                              /* Position absolue de segment */
     bool status;                            /* Bilan de la localisation    */
+    gint lheight;                           /* Hauteur d'une ligne         */
 
-    class = G_BUFFER_VIEW_GET_CLASS(view);
+    result = false;
 
-    offset = x;
+    /* Zone d'intervention bornée ! */
 
-    offset -= class->left_text;
-    if (offset < 0) return NULL;
+    text_pos = g_buffer_cache_get_text_position(view->cache);
+
+    if (x < text_pos)
+        goto gbvccf_done;
+
+    /* Calcul d'une position */
 
     g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
 
-    /* Traitement pour mise à jour de l'abscisse uniquement */
-    status = g_buffer_line_get_coord_at(line, &summary, display, &base, &offset,
+    x -= text_pos;
+
+    status = g_buffer_line_get_coord_at(line, &summary, display, &base, &x,
                                         GDK_SCROLL_LEFT, true, (col_coord_t []) { { 0 } });
-    if (!status) return NULL;
 
-    caret->x = class->left_text + base + offset;
+    if (!status)
+        goto gbvccf_done;
+
+    /* Transmission des informations */
+
+    lheight = g_buffer_cache_get_line_height(view->cache);
 
-    caret->y = (index - view->first) * class->line_height;
+    caret->x = text_pos + base + x;
+
+    caret->y = (index - view->first) * lheight;
 
     caret->width = 2;
-    caret->height = class->line_height;
+    caret->height = lheight;
+
+    g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+
+    result = true;
 
-    return get_mrange_addr(g_buffer_line_get_range(line));
+ gbvccf_done:
+
+    return result;
 
 }
 
@@ -687,16 +706,24 @@ const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *l
 static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line, size_t index, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display)
 {
     bool result;                            /* Bilan à retourner           */
+    gint text_pos;                          /* Abscisse de départ du texte */
     gint offset;                            /* Point de travail modifiable */
     line_width_summary summary;             /* Résumé concis des largeurs  */
     gint base;                              /* Position absolue de segment */
     col_coord_t coord;                      /* Coordonnées en interne      */
     const line_segment *segment;            /* Bribe de texte trouvée      */
 
-    offset = caret->x;
 
-    offset -= G_BUFFER_VIEW_GET_CLASS(view)->left_text;
-    if (offset < 0) return false;
+    result = false;
+
+    /* Zone d'intervention bornée ! */
+
+    text_pos = g_buffer_cache_get_text_position(view->cache);
+
+    if (caret->x < text_pos)
+        goto gbvmc_done;
+
+    offset = caret->x - text_pos;
 
     g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
 
@@ -725,7 +752,9 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
     /* Mise à jour éventuelle */
 
     if (result)
-        caret->x = G_BUFFER_VIEW_GET_CLASS(view)->left_text + base + offset;
+        caret->x = text_pos + base + offset;
+
+ gbvmc_done:
 
     return result;
 
@@ -735,82 +764,35 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : view    = vue de tampon à mettre à jour.                     *
-*                caret   = position du curseur à faire évoluer.               *
 *                ctrl    = indique la demande d'un parcours rapide.           *
 *                dir     = direction du parcours.                             *
 *                display = règles d'affichage des colonnes modulables.        *
+*                caret   = position du curseur à faire évoluer. [OUT]         *
+*                addr    = adresse correspondant à cette même position. [OUT] *
 *                                                                             *
 *  Description : Déplace le curseur au sein d'une vue de tampon.              *
 *                                                                             *
-*  Retour      : Adresse si une a pu être déterminée, VMPA_INVALID sinon.     *
+*  Retour      : true si les deux derniers arguments ont pu être constitués.  *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display)
+bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection dir, const bool *display, GdkRectangle *caret, vmpa2t *addr)
 {
-    const vmpa2t *result;                   /* Actualisation à renvoyer    */
+    bool result;                            /* Bilan à retourner           */
     size_t index;                           /* Indice de ligne de tampon   */
     GBufferLine *line;                      /* Ligne sous le pointeur      */
-
-
-    line_width_summary summary;             /* Résumé concis des largeurs  */
-    gint left_pos;                          /* Retour à la ligne           */
-    gint right_pos;                         /* Position d'extrème droite   */
-    BufferLineColumn i;                     /* Boucle de parcours          */
     size_t first;                           /* Première ligne intégrée     */
     size_t last;                            /* Dernière ligne intégrée     */
-
-
-
-
+    GBufferLine *other;                     /* Ligne voisine à visiter     */
     bool moved;                             /* Mémorisation d'une évolut°  */
+    gint text_pos;                          /* Abscisse de départ du texte */
 
-
-
-
-
-
-
-
-
-    result = NULL;
-
-
+    result = false;
 
     line = g_buffer_view_find_line_at(view, caret->y, &index);
-    if (line == NULL) return NULL;
-
-    g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
-
-    switch (dir)
-    {
-        case GDK_SCROLL_UP:
-        case GDK_SCROLL_DOWN:
-            break;
-        case GDK_SCROLL_LEFT:
-        case GDK_SCROLL_RIGHT:
-            left_pos = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
-            if (display[BLC_PHYSICAL]) left_pos += summary.max_widths[BLC_PHYSICAL] + COL_MARGIN;
-            if (display[BLC_VIRTUAL]) left_pos += summary.max_widths[BLC_VIRTUAL] + COL_MARGIN;
-            if (display[BLC_BINARY]) left_pos += summary.max_widths[BLC_BINARY] + COL_MARGIN;
-            right_pos = left_pos;
-            for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++)
-                right_pos += summary.max_widths[i] + COL_MARGIN;
-
-            /*
-gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn index, const gint *max_widths)
-
-BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
-            */
-
-            left_pos = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
-
-            break;
-        default:    /* GDK_SCROLL_SMOOTH */
-            break;
-    }
+    if (line == NULL) goto gbvmc_done;
 
     first = view->first;
     last = view->last;
@@ -821,8 +803,12 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
 
             if (index > first)
             {
-                line = g_code_buffer_find_line_by_index(view->buffer, index - 1);
-                result = g_buffer_view_compute_caret_full(view, line, index - 1, caret->x, display, caret);
+                index--;
+
+                other = g_buffer_cache_find_line_by_index(view->cache, index);
+                result = _g_buffer_view_compute_caret_full(view, caret->x, other, index, display, caret, addr);
+                g_object_unref(G_OBJECT(other));
+
             }
 
             break;
@@ -831,48 +817,58 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
 
             if (index < last)
             {
-                line = g_code_buffer_find_line_by_index(view->buffer, index + 1);
-                result = g_buffer_view_compute_caret_full(view, line, index + 1, caret->x, display, caret);
+                index++;
+
+                other = g_buffer_cache_find_line_by_index(view->cache, index);
+                result = _g_buffer_view_compute_caret_full(view, caret->x, other, index, display, caret, addr);
+                g_object_unref(G_OBJECT(other));
+
             }
 
             break;
 
         case GDK_SCROLL_LEFT:
 
-            /*
-            line = g_buffer_view_find_line_at(view, caret->y, &index);
-            if (line == NULL) break;
-            */
-
             moved = _g_buffer_view_move_caret(view, line, index, caret, ctrl, GDK_SCROLL_LEFT, display);
 
             if (moved)
-                result = get_mrange_addr(g_buffer_line_get_range(line));
+            {
+                g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+                result = true;
+            }
 
             else if (index > first)
             {
-                line = g_code_buffer_find_line_by_index(view->buffer, index - 1);
-                result = g_buffer_view_compute_caret_full(view, line, index - 1, INT_MAX, display, caret);
+                index--;
+
+                other = g_buffer_cache_find_line_by_index(view->cache, index);
+                result = _g_buffer_view_compute_caret_full(view, INT_MAX, other, index, display, caret, addr);
+                g_object_unref(G_OBJECT(other));
+
             }
 
             break;
 
         case GDK_SCROLL_RIGHT:
 
-            /*
-            line = g_buffer_view_find_line_at(view, caret->y, &index);
-            if (line == NULL) break;
-            */
-
             moved = _g_buffer_view_move_caret(view, line, index, caret, ctrl, GDK_SCROLL_RIGHT, display);
 
             if (moved)
-                result = get_mrange_addr(g_buffer_line_get_range(line));
+            {
+                g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+                result = true;
+            }
 
             else if (index < last)
             {
-                line = g_code_buffer_find_line_by_index(view->buffer, index + 1);
-                result = g_buffer_view_compute_caret_full(view, line, index + 1, left_pos, display, caret);
+                index++;
+
+                text_pos = g_buffer_cache_get_text_position(view->cache);
+
+                other = g_buffer_cache_find_line_by_index(view->cache, index);
+                result = _g_buffer_view_compute_caret_full(view, text_pos, other, index, display, caret, addr);
+                g_object_unref(G_OBJECT(other));
+
             }
 
             break;
@@ -882,11 +878,27 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
 
     }
 
+    g_object_unref(G_OBJECT(line));
+
+ gbvmc_done:
+
     return result;
 
 }
 
 
+
+
+
+
+
+
+
+
+
+
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : view = vue de tampon à mettre à jour.                        *
@@ -927,23 +939,64 @@ bool g_buffer_view_unhighlight_segments(GBufferView *view)
 
 bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const bool *display)
 {
-    bool need_redraw;                       /* Besoin d'actualisation ?    */
+    bool result;                            /* Besoin à faire remonter     */
+    gint text_pos;                          /* Abscisse de départ du texte */
+    gint lheight;                           /* Hauteur d'une ligne         */
+    size_t index;                           /* Indice de ligne de tampon   */
+    GBufferLine *line;                      /* Ligne à la position courante*/
+    line_width_summary summary;             /* Résumé concis des largeurs  */
     const line_segment *segment;            /* Segment sélectionnable      */
 
+    /* Réinitialisation */
+
     if (view->highlighted != NULL)
-        need_redraw = g_buffer_view_unhighlight_segments(view);
+        result = g_buffer_view_unhighlight_segments(view);
     else
-        need_redraw = false;
+        result = false;
+
+    /* Zone d'intervention bornée ! */
+
+    text_pos = g_buffer_cache_get_text_position(view->cache);
+
+    if (x < text_pos)
+        goto gbvhs_done;
+
+    /* Détermination de la ligne concernée */
 
-    g_buffer_view_find_line_and_segment_at(view, &x, y, NULL, display, &segment);
+    lheight = g_buffer_cache_get_line_height(view->cache);
+    index = y / lheight;
+
+    index += view->first;
+
+    if (index > view->last)
+        goto gbvhs_done;
+
+    line = g_buffer_cache_find_line_by_index(view->cache, index);
+
+    assert(line != NULL);
+
+    /* Recherche d'un segment et de son empreinte */
+
+    g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
+
+    x -= text_pos;
+
+    segment = g_buffer_line_get_segment_at(line, &summary, display,
+                                           (gint []) { 0 }, &x, GDK_SCROLL_LEFT, true);
 
-    if (segment)
-        need_redraw |= add_segment_content_to_selection_list(view->highlighted, segment);
+    g_object_unref(G_OBJECT(line));
 
-    if (need_redraw)
+    /* Conclusion */
+
+    if (segment != NULL)
+        result |= add_segment_content_to_selection_list(view->highlighted, segment);
+
+    if (result)
         g_signal_emit_by_name(view, "need-redraw");
 
-    return true;
+ gbvhs_done:
+
+    return result;
 
 }
 
@@ -952,13 +1005,12 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const b
 *                                                                             *
 *  Paramètres  : view     = visualisation à représenter.                      *
 *                cr       = contexte graphique dédié à la procédure.          *
-*                fake_x   = abscisse réelle du point 0 à l'écran.             *
-*                fake_y   = ordonnée réelle du point 0 à l'écran.             *
+*                virt_y   = ordonnée réelle du point 0 à l'écran.             *
 *                area     = position et surface à traiter.                    *
 *                display  = règles d'affichage des colonnes modulables.       *
 *                selected = ordonnée d'une ligne sélectionnée ou NULL.        *
 *                                                                             *
-*  Description : Imprime la visualisation du tampon de code désassemblé.      *
+*  Description : Imprime la visualisation du tampon de lignes quelconques.    *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -966,148 +1018,57 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const b
 *                                                                             *
 ******************************************************************************/
 
-void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint fake_x, gint fake_y, const cairo_rectangle_int_t *area, const bool *display, const gint *selected)
+void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint virt_y, const cairo_rectangle_int_t *area, const bool *display, gint *selected)
 {
-    GBufferViewClass *class;                /* Classe pour les vues        */
-    gint real_x;                            /* Abscisse réelle pour tampon */
-    gint real_y;                            /* Ordonnée réelle pour tampon */
+    gint line_height;                       /* Hauteur d'une ligne         */
+    gint cr_y;                              /* Ordonnée pour le dessin     */
     size_t first;                           /* Première ligne visée        */
-    size_t last;                            /* Dernière ligne visée + 1    */
-    gint y;                                 /* Point de départ + décallage */
-    bool wait_selection;                    /* Sélection déjà passée ?     */
-    gint rel_selected;                      /* Position relative de sélect°*/
-    size_t i;                               /* Boucle de parcours          */
-    GBufferLine *line;                      /* Ligne à dessiner à l'écran  */
-    line_width_summary summary;             /* Résumé concis des largeurs  */
+    size_t last;                            /* Dernière ligne visée        */
 
-    class = G_BUFFER_VIEW_GET_CLASS(view);
+    line_height = g_buffer_cache_get_line_height(view->cache);
 
-    real_x = fake_x + class->left_text;
-    real_y = fake_y + area->y;
+    /* Indice et point de départ */
 
     first = view->first;
-    first += (real_y / class->line_height);
-
-    last = first + (area->height / class->line_height);
-    if (area->height % class->line_height > 0) last++;
-
-    last = MIN(last, view->last);
-
-    y = area->y - (real_y % class->line_height);
-
-    wait_selection = true;
+    first += (virt_y / line_height);
 
-    if (selected != NULL)
-        rel_selected = *selected - fake_y;
-
-    if (g_code_buffer_count_lines(view->buffer) > 0)
-        for (i = first; i <= last; i++)
-        {
-            /* Si sélection, on sousligne la ligne concernée */
-            if (wait_selection && selected != NULL && rel_selected == y)
-            {
-                cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.05);
+    cr_y = area->y - (virt_y % line_height);
 
-                cairo_rectangle(cr, area->x, y, area->width, class->line_height);
-                cairo_fill(cr);
+    /* Indice de d'arrivée */
 
-                wait_selection = false;
+    last = first + (area->height / line_height);
+    if (area->height % line_height > 0) last++;
 
-            }
+    last = MIN(last, view->last);
 
-            line = g_code_buffer_find_line_by_index(view->buffer, i);
+    /* Phase de dessin ! */
 
-            if (i == first || (g_buffer_line_get_flags(line) & BLF_WIDTH_MANAGER))
-                g_width_tracker_get_local_width_summary(view->tracker, i, &summary);
+    /**
+     * Le contexte n'est pas sauvegardé avant modification ici car
+     * l'appelant l'a fait pour nous avant sa translation sur les abscisses.
+     */
 
-            g_buffer_line_draw(line, cr, &summary, real_x, y, display, view->highlighted);
+    cairo_translate(cr, 0, cr_y);
 
-            y += class->line_height;
+    if (selected != NULL)
+        *selected -= cr_y;
 
-        }
+    g_buffer_cache_draw(view->cache, cr, first, last, area, display, selected, view->highlighted);
 
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = visualisation à consulter.                           *
-*                addr  = adresse où retrouver la ligne recherchée.            *
-*                flags = propriétés à vérifier en tout ou partie.             *
-*                idx   = indice de la ligne trouvée ou NULL. [OUT]            *
-*                                                                             *
-*  Description : Retrouve une ligne au sein d'un tampon avec une adresse.     *
-*                                                                             *
-*  Retour      : Line retrouvée ou NULL en cas d'échec.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_by_addr(const GBufferView *view, const vmpa2t *addr, BufferLineFlags flags, size_t *idx)
-{
-    GBufferLine *result;                    /* Ligne trouvée à retourner   */
-    phys_t length;                          /* Taille de la vue            */
-    mrange_t vrange;                        /* Couverture de la vue        */
-    bool allowed;                           /* Rechercher validée ?        */
-
-    /* Vérification des bornes */
-
-    if (!view->unrestricted)
-    {
-        length = compute_vmpa_diff(&view->start, &view->end);
 
-        init_mrange(&vrange, &view->start, length);
 
-        allowed = mrange_contains_addr_inclusive(&vrange, addr);
 
-    }
-    else allowed = true;
 
-    /* Lancement des recherches ? */
 
-    if (allowed)
-        result = g_code_buffer_find_line_by_addr(view->buffer, addr, flags, idx);
-    else
-        result = NULL;
 
-    return result;
-
-}
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = visualisation à consulter.                           *
-*                index = indice de la ligne recherchée.                       *
-*                                                                             *
-*  Description : Retrouve une ligne au sein d'un tampon avec un indice.       *
-*                                                                             *
-*  Retour      : Line retrouvée ou NULL en cas d'échec.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *view, size_t index)
-{
-    GBufferLine *result;                    /* Ligne trouvée à retourner   */
-    bool allowed;                           /* Rechercher validée ?        */
 
-    /* Vérification des bornes */
 
-    allowed = (view->first <= index && index <= view->last);
 
-    /* Lancement des recherches ? */
-
-    if (allowed)
-        result = g_code_buffer_find_line_by_index(view->buffer, index);
-    else
-        result = NULL;
-
-    return result;
-
-}
 
 
 /******************************************************************************
@@ -1124,19 +1085,19 @@ GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *view, size_t in
 *                                                                             *
 ******************************************************************************/
 
-GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
+static GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
 {
     GBufferLine *result;                    /* Ligne trouvée à retourner   */
     gint lheight;                           /* Hauteur d'une ligne         */
     size_t index;                           /* Indice attendu              */
 
-    lheight = g_buffer_view_get_line_height(view);
+    lheight = g_buffer_cache_get_line_height(view->cache);
     index = y / lheight;
 
     index += view->first;
 
     if (index <= view->last)
-        result = g_code_buffer_find_line_by_index(view->buffer, index);
+        result = g_buffer_cache_find_line_by_index(view->cache, index);
     else
         result = NULL;
 
@@ -1148,125 +1109,26 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view    = visualisation à consulter.                         *
-*                x       = abscisse comprise dans le segment recherché. [OUT] *
-*                y       = ordonnée comprise dans la ligne recherchée.        *
-*                idx     = indice de la ligne trouvée ou NULL. [OUT]          *
-*                display = règles d'affichage des colonnes modulables.        *
-*                segment = portion de texte recherchée ou NULL. [OUT]         *
-*                                                                             *
-*  Description : Fournit la ligne et son segment présents à une position.     *
-*                                                                             *
-*  Retour      : Ligne retrouvée ou NULL si aucune.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, const line_segment **segment)
-{
-    GBufferLine *result;                    /* Ligne trouvée à retourner   */
-    size_t index;                           /* Indice de la ligne trouvée  */
-    GBufferViewClass *class;                /* Classe pour les vues        */
-    line_width_summary summary;             /* Résumé concis des largeurs  */
-
-    /* Recherche d'une ligne correspondante */
 
-    result = g_buffer_view_find_line_at(view, y, &index);
 
-    if (idx != NULL) *idx = index;
 
-    /* Recherche du segment visé éventuel */
 
-    if (result != NULL && segment != NULL)
-    {
-        class = G_BUFFER_VIEW_GET_CLASS(view);
 
-        if (*x < class->left_text)
-            *segment = NULL;
 
-        else
-        {
-            g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
 
-            *x -= class->left_text;
-            *segment = g_buffer_line_get_segment_at(result, &summary, display,
-                                                    (gint []) { 0 }, x, GDK_SCROLL_LEFT, true);
 
-        }
 
-    }
 
-    return result;
 
-}
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : view    = visualisation à consulter.                         *
-*                x       = abscisse comprise dans le segment recherché. [OUT] *
-*                y       = ordonnée comprise dans la ligne recherchée.        *
-*                idx     = indice de la ligne trouvée ou NULL. [OUT]          *
-*                display = règles d'affichage des colonnes modulables.        *
-*                creator = instance à l'origine de la représentation. [OUT]   *
-*                                                                             *
-*  Description : Fournit la ligne et son segment présents à une position.     *
-*                                                                             *
-*  Retour      : Ligne retrouvée ou NULL si aucune.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, GObject **creator)
-{
-    GBufferLine *result;                    /* Ligne trouvée à retourner   */
-    size_t index;                           /* Indice de la ligne trouvée  */
-    GBufferViewClass *class;                /* Classe pour les vues        */
-    line_width_summary summary;             /* Résumé concis des largeurs  */
-
-    /* Recherche d'une ligne correspondante */
-
-    result = g_buffer_view_find_line_at(view, y, &index);
-
-    if (idx != NULL) *idx = index;
-
-    /* Recherche du segment visé éventuel */
-
-    if (result != NULL && creator != NULL)
-    {
-        class = G_BUFFER_VIEW_GET_CLASS(view);
-
-        if (*x < class->left_text)
-            *creator = NULL;
-
-        else
-        {
-            g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
-
-            *x -= class->left_text;
-            *creator = g_buffer_line_get_creator_at(result, &summary, display,
-                                                    (gint []) { 0 }, x, GDK_SCROLL_LEFT, true);
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à consulter.                            *
+*  Paramètres  : view = visualisation à consulter.                            *
 *                addr = adresse à présenter à l'écran.                        *
+*                code = s'arrête si possible à une ligne avec code.           *
 *                x    = position horizontale au sein du composant. [OUT]      *
 *                y    = position verticale au sein du composant. [OUT]        *
-*                code = s'arrête si possible à une ligne avec code.           *
 *                                                                             *
 *  Description : Indique la position d'affichage d'une adresse donnée.        *
 *                                                                             *
@@ -1276,61 +1138,11 @@ GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *view, gint *x,
 *                                                                             *
 ******************************************************************************/
 
-bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr, gint *x, gint *y, bool code)
+bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr, bool code, gint *x, gint *y)
 {
     bool result;                            /* Bilan à retourner           */
-    gint lheight;                           /* Hauteur d'une ligne         */
-    size_t i;                               /* Boucle de parcours          */
-    GBufferLine *line;                      /* Ligne à consulter           */
-    const mrange_t *range;                  /* Emplacement parcouru        */
-
-    result = false;
-
-    *x = 0;
-    *y = 0;
-
-    lheight = g_buffer_view_get_line_height(view);
-
-    for (i = view->first; i <= view->last; i++)
-    {
-        /**
-         * Si l'adresse recherchée est plus petite que l'adresse de départ,
-         * on va effectuer un parcours complet pour rien.
-         *
-         * On considère cependant que le seul cas où celà peut arriver
-         * est lorsque que des découpages en blocs sont impliqués.
-         *
-         * Les découpages conduisent alors à la formation de petites zones,
-         * rapides à parcourir.
-         */
-
-        line = g_code_buffer_find_line_by_index(view->buffer, i);
-        range = g_buffer_line_get_range(line);
-
-        result = mrange_contains_addr(range, addr);
-        if (result) break;
-
-        *y += lheight;
 
-    }
-
-    if (result && code)
-        for (; i <= view->last; i++)
-        {
-            line = g_code_buffer_find_line_by_index(view->buffer, i);
-
-            if (g_buffer_line_get_flags(line) & BLF_HAS_CODE) break;
-
-            if (i == view->last) break;
-
-            line = g_code_buffer_find_line_by_index(view->buffer, i + 1);
-
-            range = g_buffer_line_get_range(line);
-            if (!mrange_contains_addr(range, addr)) break;
-
-            *y += lheight;
-
-        }
+    result = g_buffer_cache_get_address_coordinates(view->cache, addr, view->first, view->last, code, x, y);
 
     return result;
 
diff --git a/src/glibext/gbufferview.h b/src/glibext/gbufferview.h
index 0aa26a6..dc1d704 100644
--- a/src/glibext/gbufferview.h
+++ b/src/glibext/gbufferview.h
@@ -28,7 +28,7 @@
 #include <glib-object.h>
 
 
-#include "gcodebuffer.h"
+#include "gbuffercache.h"
 
 
 
@@ -47,23 +47,22 @@ typedef struct _GBufferView GBufferView;
 typedef struct _GBufferViewClass GBufferViewClass;
 
 
-/* Détermine le type de la vue d'un tampon pour code désassemblé. */
+/* Détermine le type de la vue d'un tampon pour lignes générées. */
 GType g_buffer_view_get_type(void);
 
-/* Crée une nouvelle vue d'un tampon pour code désassemblé. */
-GBufferView *g_buffer_view_new(GCodeBuffer *, segcnt_list *);
+/* Crée une nouvelle vue d'un tampon pour lignes générées. */
+GBufferView *g_buffer_view_new(GBufferCache *, segcnt_list *);
+
+/* Fournit le tampon de code lié à un visualisateur donné. */
+GBufferCache *g_buffer_view_get_cache(const GBufferView *);
 
 /* Restreint le champ d'application de l'affichage. */
 void g_buffer_view_restrict(GBufferView *, const vmpa2t *, const vmpa2t *);
 
 /* Indique le champ d'application de l'affichage. */
-bool g_buffer_view_get_restrictions(GBufferView *, vmpa2t *, vmpa2t *);
+bool g_buffer_view_get_restrictions(const GBufferView *, vmpa2t *, vmpa2t *);
 
-/* Fournit le tampon de code lié à un visualisateur donné. */
-GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *);
 
-/* Fournit la hauteur d'impression d'une ligne visualisée. */
-gint g_buffer_view_get_line_height(GBufferView *);
 
 /* Fournit la largeur requise par une visualisation. */
 gint g_buffer_view_get_width(GBufferView *, const bool *);
@@ -74,14 +73,18 @@ gint g_buffer_view_get_margin(GBufferView *, const bool *);
 /* Fournit la hauteur requise par une visualisation. */
 gint g_buffer_view_get_height(const GBufferView *);
 
-/* Calcule la position idéale de curseur pour un point donné. */
-const vmpa2t *g_buffer_view_compute_caret(GBufferView *, gint, gint, const bool *, GdkRectangle *);
+
+
+
 
 /* Calcule la position idéale de curseur pour un point donné. */
-const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *, GBufferLine *, size_t, gint, const bool *, GdkRectangle *);
+bool g_buffer_view_compute_caret_full(GBufferView *, gint, gint, const bool *, GdkRectangle *, vmpa2t *);
 
 /* Déplace le curseur au sein d'une vue de tampon. */
-const vmpa2t *g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, const bool *);
+bool g_buffer_view_move_caret(GBufferView *, bool, GdkScrollDirection, const bool *, GdkRectangle *, vmpa2t *);
+
+
+
 
 /* Supprime toute mise en évidence de segments. */
 bool g_buffer_view_unhighlight_segments(GBufferView *);
@@ -89,26 +92,18 @@ bool g_buffer_view_unhighlight_segments(GBufferView *);
 /* Surligne tous les segments similaires à celui sous la souris. */
 bool g_buffer_view_highlight_segments(GBufferView *, gint, gint, const bool *);
 
-/* Imprime la visualisation du tampon de code désassemblé. */
-void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, gint, const cairo_rectangle_int_t *, const bool *, const gint *);
+/* Imprime la visualisation du tampon de lignes quelconques. */
+void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, const cairo_rectangle_int_t *, const bool *, gint *);
 
-/* Retrouve une ligne au sein d'un tampon avec une adresse. */
-GBufferLine *g_buffer_view_find_line_by_addr(const GBufferView *, const vmpa2t *, BufferLineFlags, size_t *);
 
-/* Retrouve une ligne au sein d'un tampon avec un indice. */
-GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *, size_t );
 
-/* Fournit la ligne présente à une ordonnée donnée. */
-GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *);
 
-/* Fournit la ligne et son segment présents à une position. */
-GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *, gint *, gint, size_t *, const bool *, const line_segment **);
 
-/* Fournit la ligne et son segment présents à une position. */
-GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *, gint *, gint, size_t *, const bool *, GObject **);
 
 /* Indique la position d'affichage d'une adresse donnée. */
-bool g_buffer_view_get_address_coordinates(GBufferView *, const vmpa2t *, gint *, gint *, bool);
+bool g_buffer_view_get_address_coordinates(GBufferView *, const vmpa2t *, bool, gint *, gint *);
+
+
 
 
 
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
deleted file mode 100644
index e9f1762..0000000
--- a/src/glibext/gcodebuffer.c
+++ /dev/null
@@ -1,1778 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gcodebuffer.c - affichage d'un fragment de code d'assemblage
- *
- * Copyright (C) 2010-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 "gcodebuffer.h"
-
-
-#include <assert.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "chrysamarshal.h"
-#include "delayed-int.h"
-#include "../common/extstr.h"
-
-
-
-/* -------------------------- PARCOURS DU CODE D'UN TAMPON -------------------------- */
-
-
-#define G_TYPE_BUFFER_SCAN               g_buffer_scan_get_type()
-#define G_BUFFER_SCAN(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_buffer_scan_get_type(), GDelayedExport))
-#define G_IS_BUFFER_SCAN(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_buffer_scan_get_type()))
-#define G_BUFFER_SCAN_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BUFFER_SCAN, GDelayedExportClass))
-#define G_IS_BUFFER_SCAN_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BUFFER_SCAN))
-#define G_BUFFER_SCAN_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BUFFER_SCAN, GDelayedExportClass))
-
-
-/* Ensembles binaires à désassembler (instance) */
-typedef struct _GBufferScan
-{
-    GDelayedWork parent;                    /* A laisser en premier        */
-
-    GCodeBuffer *buffer;                    /* Tampon à manipuler          */
-
-    vmpa2t start;                           /* Début du parcours           */
-    bool has_start;                         /* Validité des données #1     */
-    vmpa2t end;                             /* Fin du parcours             */
-    bool has_end;                           /* Validité des données #2     */
-
-    char *message;                          /* Message de progression      */
-
-    process_line_fc process;                /* Fonction de traitement réel */
-    void *user_data;                        /* Données à faire suivre      */
-
-} GBufferScan;
-
-/* Ensembles binaires à désassembler (classe) */
-typedef struct _GBufferScanClass
-{
-    GDelayedWorkClass parent;               /* A laisser en premier        */
-
-} GBufferScanClass;
-
-
-/* Indique le type défini pour les tâches d'exportation différée. */
-static GType g_buffer_scan_get_type(void);
-
-/* Initialise la classe des tâches d'exportation différée. */
-static void g_buffer_scan_class_init(GBufferScanClass *);
-
-/* Initialise une tâche d'exportation différée. */
-static void g_buffer_scan_init(GBufferScan *);
-
-/* Supprime toutes les références externes. */
-static void g_buffer_scan_dispose(GBufferScan *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_buffer_scan_finalize(GBufferScan *);
-
-/* Crée une tâche d'exportation différée. */
-static GBufferScan *g_buffer_scan_new(GCodeBuffer *, const vmpa2t *, const vmpa2t *, const char *, process_line_fc, void *);
-
-/* Assure l'exportation en différé. */
-static void g_buffer_scan_process(GBufferScan *, GtkStatusStack *);
-
-
-
-/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
-
-
-/* Suivi distant des évolutions */
-typedef struct _view_callback
-{
-    buffer_size_changed_cb size_changed;    /* Evolution de taille         */
-    GObject *data;                          /* Données à associer          */
-
-} view_callback;
-
-
-/* Tampon pour code désassemblé (instance) */
-struct _GCodeBuffer
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    BufferLineColumn main_column;           /* Colonne principale          */
-
-    GBufferLine **lines;                    /* Liste des lignes intégrées  */
-    size_t count;                           /* Quantité en cache           */
-    size_t used;                            /* Quantité utilisée           */
-
-    GWidthTracker *tracker;                 /* Suivi des largeurs          */
-
-    size_t indent;                          /* Indentation des lignes      */
-
-    view_callback *vcallbacks;              /* Vues à mettre à jour        */
-    size_t vcount;                          /* Quantité de ces vues        */
-
-};
-
-/* Tampon pour code désassemblé (classe) */
-struct _GCodeBufferClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-    /* Signaux */
-
-    void (* line_changed) (GCodeBuffer *, GBufferLine *, line_segment *);
-
-};
-
-
-/* Taille des allocations de masse */
-#define LINE_ALLOC_BULK 20
-
-
-/* Procède à l'initialisation d'une classe de tampon de code. */
-static void g_code_buffer_class_init(GCodeBufferClass *);
-
-/* Procède à l'initialisation d'un tampon pour code désassemblé. */
-static void g_code_buffer_init(GCodeBuffer *);
-
-/* Réagit à un changement de contenu d'une ligne donnée. */
-static void on_line_content_change(GBufferLine *, line_segment *, GCodeBuffer *);
-
-/* Réagit à un changement de propriété rattachée à une ligne. */
-static void on_line_flag_flip(GBufferLine *, BufferLineFlags, BufferLineFlags, GCodeBuffer *);
-
-/* Ajoute de nouvelles lignes à une position donnée. */
-static void g_code_buffer_insert_lines_at(GCodeBuffer *, GBufferLine **, size_t, size_t);
-
-
-
-/* ------------------------- CONFORTS POUR LES COMMENTAIRES ------------------------- */
-
-
-/* Affiche un commentaire sur une ligne de tampon donnée. */
-static bool _g_code_buffer_write_inlined_comment(GCodeBuffer *, GBufferLine *, const char *, GObject *);
-
-/* Affiche un commentaire sur une ligne de tampon dédiée. */
-static bool _g_code_buffer_write_comment_area(GCodeBuffer *, GBufferLine *, const char *, bool, GObject *);
-
-/* Retrouve la première ligne d'une zone de commentaire. */
-static size_t g_code_buffer_find_first_line_comment(const GCodeBuffer *, size_t);
-
-/* Retrouve la dernière ligne d'une zone de commentaire. */
-static size_t g_code_buffer_find_last_line_comment(const GCodeBuffer *, size_t);
-
-/* Supprime un commentaire existant. */
-static bool _g_code_buffer_delete_lines_comment(GCodeBuffer *, GBufferLine *);
-
-
-
-/* ------------------------- SIGNAUX IMMEDIATS POUR UNE VUE ------------------------- */
-
-
-/* Fait suivre une variation de la quantité de lignes du tampon. */
-static void g_code_buffer_notify_size_changed(const GCodeBuffer *, bool, size_t, size_t);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            PARCOURS DU CODE D'UN TAMPON                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini pour les tâches d'exportation différée. */
-G_DEFINE_TYPE(GBufferScan, g_buffer_scan, G_TYPE_DELAYED_WORK);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des tâches d'exportation différée.      *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_buffer_scan_class_init(GBufferScanClass *klass)
-{
-    GObjectClass *object;                   /* Autre version de la classe  */
-    GDelayedWorkClass *work;                /* Version en classe parente   */
-
-    object = G_OBJECT_CLASS(klass);
-
-    object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_scan_dispose;
-    object->finalize = (GObjectFinalizeFunc)g_buffer_scan_finalize;
-
-    work = G_DELAYED_WORK_CLASS(klass);
-
-    work->run = (run_task_fc)g_buffer_scan_process;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : scan = instance à initialiser.                               *
-*                                                                             *
-*  Description : Initialise une tâche d'exportation différée.                 *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_buffer_scan_init(GBufferScan *scan)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : scan = instance d'objet GLib à traiter.                      *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_buffer_scan_dispose(GBufferScan *scan)
-{
-    g_object_unref(G_OBJECT(scan->buffer));
-
-    G_OBJECT_CLASS(g_buffer_scan_parent_class)->dispose(G_OBJECT(scan));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : scan = instance d'objet GLib à traiter.                      *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_buffer_scan_finalize(GBufferScan *scan)
-{
-    free(scan->message);
-
-    G_OBJECT_CLASS(g_buffer_scan_parent_class)->finalize(G_OBJECT(scan));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer  = tampon à manipuler.                                *
-*                start   = première adresse visée ou NULL.                    *
-*                end     = dernière adresse visée ou NULL.                    *
-*                message = message à afficher lors de la progression.         *
-*                process = fonction assurant le traitement effectif.          *
-*                data    = données utilisateur à faire suivre.                *
-*                                                                             *
-*  Description : Crée une tâche d'exportation différée.                       *
-*                                                                             *
-*  Retour      : Tâche créée.                                                 *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static GBufferScan *g_buffer_scan_new(GCodeBuffer *buffer, const vmpa2t *start, const vmpa2t *end, const char *message, process_line_fc process, void *data)
-{
-    GBufferScan *result;            /* Tâche à retourner           */
-
-    result = g_object_new(G_TYPE_BUFFER_SCAN, NULL);
-
-    result->buffer = buffer;
-    g_object_ref(G_OBJECT(buffer));
-
-    result->has_start = (start != NULL);
-
-    if (result->has_start)
-        copy_vmpa(&result->start, start);
-
-    result->has_end = (end != NULL);
-
-    if (result->has_end)
-        copy_vmpa(&result->end, end);
-
-    result->message = strdup(message);
-
-    result->process = process;
-    result->user_data = data;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : scan   = parcours à mener.                                   *
-*                status = barre de statut à tenir informée.                   *
-*                                                                             *
-*  Description : Assure l'exportation en différé.                             *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_buffer_scan_process(GBufferScan *scan, GtkStatusStack *status)
-{
-    size_t first;                           /* Première ligne visée        */
-    size_t last;                            /* Dernière ligne visée + 1    */
-    GBufferLine **lines;                    /* Liste des lignes à traiter  */
-    //bstatus_id_t id;                        /* Identifiant de statut       */
-    size_t i;                               /* Boucle de parcours          */
-
-    /* TODO : lock scan->buffer->lines */
-
-    if (scan->has_start)
-        first = g_code_buffer_get_index_from_address(scan->buffer, &scan->start, true);
-    else
-        first = 0;
-
-    if (scan->has_end)
-        last = g_code_buffer_get_index_from_address(scan->buffer, &scan->end, false);
-    else
-        last = scan->buffer->used - 1;
-
-    lines = scan->buffer->lines;
-
-    //id = gtk_extended_status_bar_push(statusbar, scan->message, true);
-
-    if (scan->buffer->used > 0)
-        for (i = first; i <= last; i++)
-        {
-            if (!scan->process(scan->buffer, lines[i], scan->user_data))
-                break;
-
-            /*
-            gtk_extended_status_bar_update_activity(statusbar, id,
-                                                    (i - first) * 1.0 / (last - first));
-            */
-
-        }
-
-    /* TODO : unlock scan->buffer->lines */
-
-    //gtk_extended_status_bar_remove(statusbar, id);
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            TAMPON POUR CODE DESASSEMBLE                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Détermine le type du composant de tampon pour code désassemblé. */
-G_DEFINE_TYPE(GCodeBuffer, g_code_buffer, G_TYPE_OBJECT);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : class = classe de composant GTK à initialiser.               *
-*                                                                             *
-*  Description : Procède à l'initialisation d'une classe de tampon de code.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_code_buffer_class_init(GCodeBufferClass *class)
-{
-    g_signal_new("line-changed",
-                 G_TYPE_CODE_BUFFER,
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GCodeBufferClass, line_changed),
-                 NULL, NULL,
-                 g_cclosure_user_marshal_VOID__OBJECT_OBJECT,
-                 G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GTK à initialiser.                        *
-*                                                                             *
-*  Description : Procède à l'initialisation d'un tampon pour code désassemblé.*
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_code_buffer_init(GCodeBuffer *buffer)
-{
-    buffer->tracker = g_width_tracker_new(buffer);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : main = colonne à référencer comme étant la principale.       *
-*                                                                             *
-*  Description : Crée un nouveau composant de tampon pour code désassemblé.   *
-*                                                                             *
-*  Retour      : Composant GTK créé.                                          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GCodeBuffer *g_code_buffer_new(BufferLineColumn main)
-{
-    GCodeBuffer *result;                    /* Composant à retourner       */
-
-    result = g_object_new(G_TYPE_CODE_BUFFER, NULL);
-
-    result->main_column = main;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GLib à consulter.                         *
-*                                                                             *
-*  Description : Compte le nombre de lignes rassemblées dans un tampon.       *
-*                                                                             *
-*  Retour      : Nombre de lignes constituant le tampon.                      *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-size_t g_code_buffer_count_lines(const GCodeBuffer *buffer)
-{
-    return buffer->used;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GLib à consulter.                         *
-*                                                                             *
-*  Description : Fournit un lien vers la structure de suivi de largeurs.      *
-*                                                                             *
-*  Retour      : Gestionnaire de largeurs de lignes.                          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-const GWidthTracker *g_code_buffer_get_width_tracker(const GCodeBuffer *buffer)
-{
-    return buffer->tracker;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GLib à consulter.                         *
-*                range  = emplacement où va se situer la ligne.               *
-*                                                                             *
-*  Description : Initie une nouvelle ligne devant être insérée dans le tampon.*
-*                                                                             *
-*  Retour      : Nouvelle ligne vierge à écrire.                              *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferLine *g_code_buffer_prepare_new_line(GCodeBuffer *buffer, const mrange_t *range)
-{
-    GBufferLine *result;                    /* Instance à retourner        */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = g_buffer_line_new(range, buffer->main_column);
-
-    for (i = 0; i < buffer->indent; i++)
-        g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, "    ", 4, RTT_RAW, NULL);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : line    = ligne dont la définition vient d'évoluer.          *
-*                segment = éventuel segment qui vient d'évoluer ou NULL.      *
-*                buffer  = tampon de lignes cohérentes à manipuler.           *
-*                                                                             *
-*  Description : Réagit à un changement de contenu d'une ligne donnée.        *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void on_line_content_change(GBufferLine *line, line_segment *segment, GCodeBuffer *buffer)
-{
-    g_signal_emit_by_name(buffer, "line-changed", line, segment);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : line   = ligne dont la définition vient d'évoluer.           *
-*                old    = ancien groupe de propriétés associées.              *
-*                old    = nouveau groupe de propriétés associées.             *
-*                buffer = tampon de lignes cohérentes à manipuler.            *
-*                                                                             *
-*  Description : Réagit à un changement de propriété rattachée à une ligne.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void on_line_flag_flip(GBufferLine *line, BufferLineFlags old, BufferLineFlags new, GCodeBuffer *buffer)
-{
-    g_signal_emit_by_name(buffer, "line-changed", line, NULL);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GLib à mettre à jour.                     *
-*                lines  = liste de lignes à insérer.                          *
-*                count  = taille de cette liste.                              *
-*                index  = point d'insertion de la première ligne.             *
-*                                                                             *
-*  Description : Ajoute de nouvelles lignes à une position donnée.            *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_code_buffer_insert_lines_at(GCodeBuffer *buffer, GBufferLine **lines, size_t count, size_t index)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    /* Elaboration d'un espace suffisant */
-
-    if ((buffer->used + count) > buffer->count)
-    {
-        if (count > LINE_ALLOC_BULK)
-            buffer->count += count;
-        else
-            buffer->count += LINE_ALLOC_BULK;
-
-        buffer->lines = (GBufferLine **)realloc(buffer->lines,
-                                                buffer->count * sizeof(GBufferLine *));
-
-    }
-
-    /* Insertion des lignes */
-
-    if (index < buffer->used)
-    {
-        memmove(&buffer->lines[index + count], &buffer->lines[index],
-                (buffer->used - index) * sizeof(GBufferLine *));
-    }
-
-    buffer->used += count;
-
-    for (i = 0; i < count; i++)
-    {
-        assert((index + i) < buffer->used);
-
-        buffer->lines[index + i] = lines[i];
-
-        g_signal_connect(lines[i], "content-changed", G_CALLBACK(on_line_content_change), buffer);
-        g_signal_connect(lines[i], "flip-flag", G_CALLBACK(on_line_flag_flip), buffer);
-
-    }
-
-    /* Recueil initial des largeurs */
-
-    g_width_tracker_update_added(buffer->tracker, index, count);
-
-    g_code_buffer_notify_size_changed(buffer, true, index, count);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GLib à mettre à jour.                     *
-*                line   = lign à insérer à la fin du tampon.                  *
-*                                                                             *
-*  Description : Ajoute une nouvelle ligne en fin de tampon.                  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_code_buffer_append_new_line(GCodeBuffer *buffer, GBufferLine *line)
-{
-    g_code_buffer_insert_lines_at(buffer, (GBufferLine *[]) { line }, 1, buffer->used);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GLib à mettre à jour.                     *
-*                lines  = liste de lignes à insérer.                          *
-*                count  = taille de cette liste.                              *
-*                point  = point d'insertion du bloc de ligne.                 *
-*                before = emplacement de l'insertion par rapport au point.    *
-*                                                                             *
-*  Description : Ajoute de nouvelles lignes par rapport à une ligne donnée.   *
-*                                                                             *
-*  Retour      : Bilan : insertion réussie ou non ?                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_code_buffer_insert_lines(GCodeBuffer *buffer, GBufferLine **lines, size_t count, const GBufferLine *point, bool before)
-{
-    bool result;                            /* Bilan à retourner           */
-    size_t index;                           /* Indice d'insertion final    */
-
-    result = false;
-
-    index = g_code_buffer_find_index_by_line(buffer, point);
-
-    if (index == buffer->used)
-        goto gcbil_exit;
-
-    if (!before)
-        index++;
-
-    g_code_buffer_insert_lines_at(buffer, lines, count, index);
-
-
-
-
-    result = true;
-
- gcbil_exit:
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GLib à mettre à jour.                     *
-*                start  = première ligne devant être supprimée.               *
-*                end    = dernière ligne devant être supprimée.               *
-*                                                                             *
-*  Description : Supprime une ou plusieurs lignes du tampon indiqué.          *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_code_buffer_delete_lines(GCodeBuffer *buffer, size_t start, size_t end)
-{
-    size_t i;                               /* Boucle de parcours          */
-    GBufferLine *line;                      /* Ligne en cours de traitement*/
-
-    assert(start < buffer->used);
-    assert(end < buffer->used);
-
-    for (i = start; i <= end; i++)
-    {
-        line = buffer->lines[i];
-
-        g_signal_handlers_disconnect_by_func(line, G_CALLBACK(on_line_content_change), buffer);
-        g_signal_handlers_disconnect_by_func(line, G_CALLBACK(on_line_flag_flip), buffer);
-
-        g_object_unref(G_OBJECT(line));
-
-    }
-
-    if ((end + 1) < buffer->used)
-        memmove(&buffer->lines[start], &buffer->lines[end + 1],
-                (buffer->used - end - 1) * sizeof(GBufferLine *));
-
-    buffer->used -= (end - start + 1);
-
-    g_width_tracker_update_deleted(buffer->tracker, start, end);
-
-    g_code_buffer_notify_size_changed(buffer, false, start, end - start + 1);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GTK à mettre à jour.                      *
-*                addr   = adresse où retrouver la ligne recherchée.           *
-*                flags  = propriétés à vérifier en tout ou partie.            *
-*                idx    = indice de la ligne trouvée ou NULL. [OUT]           *
-*                                                                             *
-*  Description : Retrouve une ligne au sein d'un tampon avec une adresse.     *
-*                                                                             *
-*  Retour      : Line retrouvée ou NULL en cas d'échec.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferLine *g_code_buffer_find_line_by_addr(const GCodeBuffer *buffer, const vmpa2t *addr, BufferLineFlags flags, size_t *idx)
-{
-    GBufferLine *result;                    /* Instance à retourner        */
-    size_t index;                           /* Indice de la ligne visée    */
-
-    index = g_code_buffer_get_index_from_address(buffer, addr, true);
-
-    if (index == buffer->used)
-        result = NULL;
-
-    else
-    {
-        if (idx != NULL)
-            *idx = index;
-
-        result = buffer->lines[index];
-
-        if (flags != BLF_NONE)
-            while ((g_buffer_line_get_flags(result) & flags) != flags)
-            {
-                if ((index + 1) == buffer->used) break;
-
-                /* FIXME : vérifier que l'adresse est toujours celle recherchée ! */
-
-                if (idx != NULL)
-                    (*idx)++;
-
-                result = buffer->lines[++index];
-
-            }
-
-        g_object_ref(G_OBJECT(result));
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à consulter.                       *
-*                index  = indice de la ligne recherchée.                      *
-*                                                                             *
-*  Description : Retrouve une ligne au sein d'un tampon avec un indice.       *
-*                                                                             *
-*  Retour      : Line retrouvée ou NULL en cas d'échec.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferLine *g_code_buffer_find_line_by_index(const GCodeBuffer *buffer, size_t index)
-{
-    GBufferLine *result;                    /* Ligne trouvée à retourner   */
-
-    /* TODO : ref */
-
-    if (index < buffer->used)
-        result = buffer->lines[index];
-    else
-        result = NULL;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GTK à mettre à jour.                      *
-*                addr   = adresse où va se situer la ligne.                   *
-*                first  = indique si on l'arrête à la première ou la dernière.*
-*                                                                             *
-*  Description : Convertit une adresse en indice de ligne.                    *
-*                                                                             *
-*  Retour      : Indice de l'adresse trouvée, ou le nombre de lignes sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-size_t g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, const vmpa2t *addr, bool first)
-{
-    size_t result;                          /* Indice à retourner          */
-    GBufferLine **found;                    /* Renvoi vers une trouvaille  */
-    const mrange_t *range;                  /* Couverture d'une ligne      */
-
-    /**
-     * Si aucune adresse (ie. aucune limite ?) n'est précisée, on se base sur
-     * la direction pour trouver le bon indice.
-     */
-
-    if (addr == NULL)
-        result = (first ? 0 : buffer->used - 1);
-
-    /**
-     * Sinon on parcourt méthodiquement toutes les lignes !
-     */
-
-    else
-    {
-        /* Recherche dichotomique grossière */
-
-        int cmp_addr_and_line(const vmpa2t *addr, const GBufferLine **line)
-        {
-            int status;                     /* Bilan d'une comparaison     */
-            const mrange_t *lrange;         /* Couverture d'une ligne      */
-
-            lrange = g_buffer_line_get_range(*line);
-
-            status = cmp_mrange_with_vmpa(lrange, addr);
-
-            return status;
-
-        }
-
-        found = bsearch(addr, buffer->lines, buffer->used, sizeof(GBufferLine *),
-                        (__compar_fn_t)cmp_addr_and_line);
-
-        /* Dernier raffinage pour approcher la cible réelle */
-
-        if (found == NULL)
-            result = buffer->used;
-
-        else
-        {
-            result = found - buffer->lines;
-
-            if (first)
-                for (; result > 0; result--)
-                {
-                    range = g_buffer_line_get_range(buffer->lines[result - 1]);
-                    if (!mrange_contains_addr(range, addr)) break;
-                }
-
-            else
-                for (; (result + 1) < buffer->used; result++)
-                {
-                    range = g_buffer_line_get_range(buffer->lines[result + 1]);
-                    if (!mrange_contains_addr(range, addr)) break;
-                }
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à consulter.                       *
-*                line   = ligne dont l'indice est à retrouver.                *
-*                                                                             *
-*  Description : Retrouve l'indice associé à une ligne au sein d'un tampon.   *
-*                                                                             *
-*  Retour      : Indice de l'adresse trouvée, ou le nombre de lignes sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-size_t g_code_buffer_find_index_by_line(const GCodeBuffer *buffer, const GBufferLine *line)
-{
-    size_t result;                          /* Indice trouvé à retourner   */
-    const mrange_t *range;                  /* Emplacement de la ligne     */
-    const mrange_t *next;                   /* Emplacement suivant         */
-
-    range = g_buffer_line_get_range(line);
-
-    result = g_code_buffer_get_index_from_address(buffer, get_mrange_addr(range), true);
-
-    /**
-     * Comme plusieurs lignes consécutives peuvent avoir la même adresse,
-     * on parcourt les lignes suivantes pour retrouver la ligne recherchée.
-     */
-
-    if (result < buffer->used)
-    {
-        while (buffer->lines[result] != line)
-        {
-            if (++result == buffer->used)
-                break;
-
-            next = g_buffer_line_get_range(buffer->lines[result]);
-
-            if (cmp_vmpa(get_mrange_addr(range), get_mrange_addr(next)) != 0)
-            {
-                result = buffer->used;
-                break;
-            }
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GTK à mettre à jour.                      *
-*                                                                             *
-*  Description : Augmente l'indentation des prochaines lignes.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_code_buffer_inc_indentation(GCodeBuffer *buffer)
-{
-    buffer->indent++;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = composant GTK à mettre à jour.                      *
-*                                                                             *
-*  Description : Diminue l'indentation des prochaines lignes.                 *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_code_buffer_dec_indentation(GCodeBuffer *buffer)
-{
-    /* BUG_ON(buffer->indent == 0) */
-
-    buffer->indent--;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de données à utiliser.                       *
-*                start   = première adresse visée ou 0.                       *
-*                end     = dernière adresse visée ou VMPA_MAX.                *
-*                message = message à afficher lors de la progression.         *
-*                process = fonction assurant le traitement effectif.          *
-*                data    = données utilisateur à faire suivre.                *
-*                                                                             *
-*  Description : Lance un parcours des différentes lignes du tampon de code.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GDelayedWork *g_buffer_code_scan(GCodeBuffer *buffer, const vmpa2t *start, const vmpa2t *end, const char *message, process_line_fc process, void *data)
-{
-    GBufferScan *result;                    /* Procédure à créer / renvoyer*/
-    GWorkQueue *queue;                      /* Gestionnaire de différés    */
-
-    result = g_buffer_scan_new(buffer, start, end, message, process, data);
-    g_object_ref(G_OBJECT(result));
-
-    queue = get_work_queue();
-    g_work_queue_schedule_work(queue, G_DELAYED_WORK(result), DEFAULT_WORK_GROUP);
-
-    return G_DELAYED_WORK(result);
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                           CONFORTS POUR LES COMMENTAIRES                           */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer  = tampon de lignes à consulter.                      *
-*                line    = ligne à l'intérieur d'un commentaire.              *
-*                comment = nouveau commentaire à inscrire à la ligne donnée.  *
-*                creator = créateur à l'origine de la construction.           *
-*                                                                             *
-*  Description : Affiche un commentaire sur une ligne de tampon donnée.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération : ajout ou non ?                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool _g_code_buffer_write_inlined_comment(GCodeBuffer *buffer, GBufferLine *line, const char *comment, GObject *creator)
-{
-    bool result;                            /* Bilan à retourner           */
-    const mrange_t *range;                  /* Emplace de ligne à utiliser */
-    char *wcopy;                            /* Copie de travail            */
-    GBufferLine **extra;                    /* Lignes supplémentaires      */
-    size_t extra_count;                     /* Quantité de ces lignes      */
-    char *saveptr;                          /* Sauvegarde pour la sécurité */
-    char *token;                            /* Fragment à insérer          */
-    size_t len;                             /* Taille dudit fragment       */
-    GBufferLine *new;                       /* Nouvelle ligne créée        */
-    size_t i;                               /* Boucle de parcours          */
-
-    assert(!g_buffer_line_has_comment(line));
-
-    result = false;
-
-    range = g_buffer_line_get_range(line);
-
-    wcopy = strdup(comment);
-
-    extra = NULL;
-    extra_count = 0;
-
-    for (token = strtok_r(wcopy, COMMENT_LINE_SEP, &saveptr);
-         token != NULL;
-         token = strtok_r(NULL, COMMENT_LINE_SEP, &saveptr))
-    {
-        len = strlen(token);
-
-        if (!result)
-            g_buffer_line_append_text(line, BLC_COMMENTS, token, len, RTT_COMMENT, creator);
-
-        else
-        {
-            new = g_code_buffer_prepare_new_line(buffer, range);
-
-            g_buffer_line_append_text(new, BLC_COMMENTS, token, len, RTT_COMMENT, creator);
-
-            extra = (GBufferLine **)realloc(extra, ++extra_count * sizeof(GBufferLine *));
-
-            extra[extra_count - 1] = new;
-
-        }
-
-        result = true;
-
-    }
-
-    free(wcopy);
-
-    if (extra_count > 0)
-    {
-        result &= g_code_buffer_insert_lines(buffer, extra, extra_count, line, false);
-
-        if (!result)
-            for (i = 0; i < extra_count; i++)
-                g_object_unref(G_OBJECT(extra[i]));
-
-        free(extra);
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer  = tampon de lignes à consulter.                      *
-*                line    = ligne à l'intérieur d'un commentaire.              *
-*                comment = nouveau commentaire à inscrire à la ligne donnée.  *
-*                creator = créateur à l'origine de la construction.           *
-*                                                                             *
-*  Description : Affiche un commentaire sur une ligne de tampon donnée.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération : ajout ou non ?                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_code_buffer_update_inlined_comment(GCodeBuffer *buffer, GBufferLine *line, const char *comment, GObject *creator)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    if (g_buffer_line_has_comment(line))
-        result = _g_code_buffer_delete_lines_comment(buffer, line);
-    else
-        result = true;
-
-    if (result)
-        result = _g_code_buffer_write_inlined_comment(buffer, line, comment, creator);
-
-    /* TODO : emit() */
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer  = tampon de lignes à consulter.                      *
-*                line    = ligne à l'intérieur d'un commentaire.              *
-*                comment = nouveau commentaire à inscrire à la ligne donnée.  *
-*                before  = précise la position du commentaire.                *
-*                creator = créateur à l'origine de la construction.           *
-*                                                                             *
-*  Description : Affiche un commentaire sur une ligne de tampon dédiée.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération : ajout ou non ?                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool _g_code_buffer_write_comment_area(GCodeBuffer *buffer, GBufferLine *line, const char *comment, bool before, GObject *creator)
-{
-    bool result;                            /* Bilan à retourner           */
-    const mrange_t *range;                  /* Emplace de ligne à utiliser */
-    char *wcopy;                            /* Copie de travail            */
-    GBufferLine **extra;                    /* Lignes supplémentaires      */
-    size_t extra_count;                     /* Quantité de ces lignes      */
-    char *saveptr;                          /* Sauvegarde pour la sécurité */
-    char *token;                            /* Fragment à insérer          */
-    size_t len;                             /* Taille dudit fragment       */
-    GBufferLine *new;                       /* Nouvelle ligne créée        */
-    size_t i;                               /* Boucle de parcours          */
-
-    assert(!g_buffer_line_has_comment(line));
-
-    result = false;
-
-    range = g_buffer_line_get_range(line);
-
-    wcopy = strdup(comment);
-
-    extra = NULL;
-    extra_count = 0;
-
-    for (token = strtok_r(wcopy, COMMENT_LINE_SEP, &saveptr);
-         token != NULL;
-         token = strtok_r(NULL, COMMENT_LINE_SEP, &saveptr))
-    {
-        len = strlen(token);
-
-        new = g_code_buffer_prepare_new_line(buffer, range);
-        g_buffer_line_start_merge_at(new, BLC_DISPLAY);
-
-        g_buffer_line_append_text(new, BLC_DISPLAY, token, len, RTT_COMMENT, creator);
-
-        extra = (GBufferLine **)realloc(extra, ++extra_count * sizeof(GBufferLine *));
-
-        extra[extra_count - 1] = new;
-
-        result = true;
-
-    }
-
-    free(wcopy);
-
-    if (extra_count > 0)
-    {
-        result &= g_code_buffer_insert_lines(buffer, extra, extra_count, line, before);
-
-        if (!result)
-            for (i = 0; i < extra_count; i++)
-                g_object_unref(G_OBJECT(extra[i]));
-
-        free(extra);
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer  = tampon de lignes à consulter.                      *
-*                line    = ligne à l'intérieur d'un commentaire.              *
-*                comment = nouveau commentaire à inscrire à la ligne donnée.  *
-*                before  = précise la position du commentaire.                *
-*                creator = créateur à l'origine de la construction.           *
-*                                                                             *
-*  Description : Affiche un commentaire sur une ligne de tampon dédiée.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération : ajout ou non ?                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_code_buffer_update_comment_area(GCodeBuffer *buffer, GBufferLine *line, const char *comment, bool before, GObject *creator)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    if (g_buffer_line_has_comment(line))
-        result = _g_code_buffer_delete_lines_comment(buffer, line);
-    else
-        result = true;
-
-    if (result)
-        result = _g_code_buffer_write_comment_area(buffer, line, comment, before, creator);
-
-    /* TODO : emit() */
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à consulter.                       *
-*                index  = indice de ligne à l'intérieur d'un commentaire.     *
-*                                                                             *
-*  Description : Retrouve la première ligne d'une zone de commentaire.        *
-*                                                                             *
-*  Retour      : Indice de l'adresse trouvée, ou le nombre de lignes sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static size_t g_code_buffer_find_first_line_comment(const GCodeBuffer *buffer, size_t index)
-{
-    size_t result;                          /* Indice trouvé à retourner   */
-    GBufferLine *prev;                      /* Ligne précédente            */
-
-    assert(index < buffer->used);
-
-    bool is_first_line_of_comment(const GBufferLine *ln, const GBufferLine *pv)
-    {
-        bool first;                         /* Statut à renvoyer           */
-        BufferLineColumn merge_col;         /* Colonne de fusion #1        */
-        BufferLineColumn prev_merge_col;    /* Colonne de fusion #2        */
-
-        merge_col = g_buffer_line_get_merge_start(ln);
-
-        /**
-         * La ligne consultée contient toujours un commentaire.
-         *
-         * Deux cas de figures sont possibles ici :
-         *
-         *  - soit du texte est présent dans la colonne "commentaires".
-         *    Si du texte est présent avant, alors il s'agit forcément de
-         *    la première (et unique ?) ligne de commentaire.
-         *
-         *  - soit la ligne effectue une fusion des colonnes depuis BLC_DISPLAY.
-         *    Si la ligne qui précède fait de même, il s'agit alors d'une étiquette
-         *    ou de l'amont du commentaire.
-         *
-         */
-
-        if (g_buffer_line_has_text(ln, BLC_COMMENTS, BLC_COUNT))
-        {
-            first = g_buffer_line_has_text(ln, BLC_DISPLAY, BLC_COMMENTS);
-
-            if (!first)
-            {
-                /* La ligne d'avant doit avoir un commentaire ! */
-                first = !g_buffer_line_has_text(pv, BLC_COMMENTS, BLC_COUNT);
-            }
-
-        }
-
-        else
-        {
-            /**
-             * Le prologue "merge_col == BLC_FIRST" n'étant pas éditable,
-             * la seule fusion possible ici est la suivante.
-             */
-            assert(merge_col == BLC_DISPLAY);
-
-            /**
-             * La première ligne d'un tampon est toujours un prologue.
-             */
-            assert(pv != NULL);
-
-            prev_merge_col = g_buffer_line_get_merge_start(pv);
-
-            first = (prev_merge_col != BLC_DISPLAY);
-
-            if (!first)
-                first = (g_buffer_line_get_flags(pv) & BLF_IS_LABEL);
-
-        }
-
-        return first;
-
-    }
-
-    for (result = index; result > 0; result--)
-    {
-        prev = (result > 0 ? buffer->lines[result - 1] : NULL);
-
-        if (is_first_line_of_comment(buffer->lines[result], prev))
-            break;
-
-    }
-
-    if (result == 0)
-    {
-        if (!is_first_line_of_comment(buffer->lines[0], NULL))
-            result = buffer->used;
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à consulter.                       *
-*                index  = indice de ligne à l'intérieur d'un commentaire.     *
-*                                                                             *
-*  Description : Retrouve la dernière ligne d'une zone de commentaire.        *
-*                                                                             *
-*  Retour      : Indice de l'adresse trouvée, ou le nombre de lignes sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static size_t g_code_buffer_find_last_line_comment(const GCodeBuffer *buffer, size_t index)
-{
-    size_t result;                          /* Indice trouvé à retourner   */
-    GBufferLine *next;                      /* Ligne suivante              */
-
-    assert(index < buffer->used);
-
-    bool is_last_line_of_comment(const GBufferLine *ln, const GBufferLine *nx)
-    {
-        bool last;                          /* Statut à renvoyer           */
-        BufferLineColumn merge_col;         /* Colonne de fusion #1        */
-        BufferLineColumn next_merge_col;    /* Colonne de fusion #2        */
-
-        merge_col = g_buffer_line_get_merge_start(ln);
-
-        /**
-         * La ligne consultée contient toujours un commentaire.
-         *
-         * Deux cas de figures sont possibles ici :
-         *
-         *  - soit du texte est présent dans la colonne "commentaires".
-         *    Si la ligne suivante est similaire et si du texte est présent avant,
-         *    alors il s'agit forcément de d'un nouveau commentaire. S'il n'y a
-         *    aucun texte, il s'agit de la suite du commentaire.
-         *
-         *  - soit la ligne effectue une fusion des colonnes depuis BLC_DISPLAY.
-         *    Si la ligne qui suit fait de même, il s'agit alors d'une étiquette
-         *    ou de l'aval du commentaire.
-         *
-         */
-
-        if (g_buffer_line_has_text(ln, BLC_COMMENTS, BLC_COUNT))
-        {
-            last = !g_buffer_line_has_text(nx, BLC_COMMENTS, BLC_COUNT);
-
-            if (!last)
-                last = g_buffer_line_has_text(nx, BLC_DISPLAY, BLC_COMMENTS);
-
-        }
-
-        else
-        {
-            /**
-             * Le prologue "merge_col == BLC_FIRST" n'étant pas éditable,
-             * la seule fusion possible ici est la suivante.
-             */
-            assert(merge_col == BLC_DISPLAY);
-
-            if (nx == NULL)
-                last = true;
-
-            else
-            {
-                next_merge_col = g_buffer_line_get_merge_start(nx);
-
-                last = (next_merge_col != BLC_DISPLAY);
-
-                if (!last)
-                    last = (g_buffer_line_get_flags(nx) & BLF_IS_LABEL);
-
-            }
-
-        }
-
-        return last;
-
-    }
-
-    for (result = index; result < buffer->used; result++)
-    {
-        next = ((result + 1) < buffer->used ? buffer->lines[result + 1] : NULL);
-
-        if (is_last_line_of_comment(buffer->lines[result], next))
-            break;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à consulter.                       *
-*                line   = ligne à l'intérieur d'un commentaire.               *
-*                                                                             *
-*  Description : Retrouve le créateur d'un commentaire existant.              *
-*                                                                             *
-*  Retour      : Instance trouvée à déréférencer ensuite ou NULL si aucune.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GObject *g_code_buffer_get_comment_creator(const GCodeBuffer *buffer, const GBufferLine *line)
-{
-    GObject *result;                        /* Instance à retourner        */
-    BufferLineColumn merge_col;             /* Colonne de fusion           */
-
-    if (g_buffer_line_has_comment(line))
-    {
-        merge_col = g_buffer_line_get_merge_start(line);
-
-        if (merge_col == BLC_DISPLAY)
-            result = g_buffer_line_find_first_segment_creator(line, BLC_DISPLAY);
-        else
-            result = g_buffer_line_find_first_segment_creator(line, BLC_COMMENTS);
-
-    }
-
-    else
-        result = NULL;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à consulter.                       *
-*                line   = ligne à l'intérieur d'un commentaire.               *
-*                                                                             *
-*  Description : Récupère le contenu d'un commentaire existant.               *
-*                                                                             *
-*  Retour      : Commentaire retrouver à libérer ou NULL en cas d'échec.      *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-char *g_code_buffer_get_lines_comment(const GCodeBuffer *buffer, const GBufferLine *line)
-{
-    char *result;                           /* Contenu à retourner         */
-    size_t index;                           /* Indice de la ligne fournie  */
-    size_t start;                           /* Ligne de départ             */
-    size_t end;                             /* Ligne d'arrivée             */
-    BufferLineColumn merge_col;             /* Colonne de fusion           */
-    size_t i;                               /* Boucle de parcours          */
-    char *extra;                            /* Commentaire supplémentaire  */
-
-    /* Pas de prologue ici ! */
-    assert(g_buffer_line_has_comment(line));
-
-    result = NULL;
-
-    index = g_code_buffer_find_index_by_line(buffer, line);
-
-    if (index == buffer->used)
-        goto gcbglc_exit;
-
-    start = g_code_buffer_find_first_line_comment(buffer, index);
-
-    if (start == buffer->used)
-        goto gcbglc_exit;
-
-    end = g_code_buffer_find_last_line_comment(buffer, index);
-
-    if (end == buffer->used)
-        goto gcbglc_exit;
-
-    merge_col = g_buffer_line_get_merge_start(line);
-
-    for (i = start; i <= end; i++)
-    {
-        if (merge_col == BLC_DISPLAY)
-            extra = g_buffer_line_get_text(buffer->lines[i], BLC_DISPLAY, BLC_COUNT, false);
-
-        else
-            extra = g_buffer_line_get_text(buffer->lines[i], BLC_COMMENTS, BLC_COUNT, false);
-
-        assert(extra != NULL);
-
-        if (result == NULL)
-            result = extra;
-
-        else
-        {
-            result = stradd(result, extra);
-            free(extra);
-        }
-
-    }
-
- gcbglc_exit:
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à modifier.                        *
-*                line   = ligne à l'intérieur d'un commentaire.               *
-*                                                                             *
-*  Description : Supprime un commentaire existant.                            *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool _g_code_buffer_delete_lines_comment(GCodeBuffer *buffer, GBufferLine *line)
-{
-    bool result;                            /* Bilan à retourner           */
-    size_t index;                           /* Indice de la ligne fournie  */
-    size_t start;                           /* Ligne de départ             */
-    size_t end;                             /* Ligne d'arrivée             */
-    BufferLineColumn merge_col;             /* Colonne de fusion           */
-
-    /* Pas de prologue ici ! */
-    assert(g_buffer_line_has_comment(line));
-
-    result = false;
-
-    index = g_code_buffer_find_index_by_line(buffer, line);
-
-    if (index == buffer->used)
-        goto gcbdlc_exit;
-
-    start = g_code_buffer_find_first_line_comment(buffer, index);
-
-    if (start == buffer->used)
-        goto gcbdlc_exit;
-
-    end = g_code_buffer_find_last_line_comment(buffer, index);
-
-    if (end == buffer->used)
-        goto gcbdlc_exit;
-
-    result = true;
-
-    merge_col = g_buffer_line_get_merge_start(line);
-
-    if (merge_col == BLC_DISPLAY)
-        g_code_buffer_delete_lines(buffer, start, end);
-
-    else
-    {
-        g_buffer_line_delete_text(buffer->lines[start], BLC_COMMENTS, BLC_COUNT);
-
-        if (end > start)
-            g_code_buffer_delete_lines(buffer, start + 1, end);
-
-    }
-
- gcbdlc_exit:
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à modifier.                        *
-*                line   = ligne à l'intérieur d'un commentaire.               *
-*                                                                             *
-*  Description : Supprime un commentaire existant.                            *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_code_buffer_delete_lines_comment(GCodeBuffer *buffer, GBufferLine *line)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    result = _g_code_buffer_delete_lines_comment(buffer, line);
-
-    /* TODO : emit() */
-
-    return result;
-
-}
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                           SIGNAUX IMMEDIATS POUR UNE VUE                           */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à modifier.                        *
-*                cb     = fonction à appeler au moment opportun.              *
-*                data   = object GLib à associer à l'appel.                   *
-*                                                                             *
-*  Description : Enregistre l'adresse d'une fonction de mise à jour de vue.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_code_buffer_register_view_callback(GCodeBuffer *buffer, buffer_size_changed_cb cb, GObject *data)
-{
-    view_callback *new;                     /* Informations sur l'appel    */
-
-    buffer->vcount++;
-
-    buffer->vcallbacks = (view_callback *)realloc(buffer->vcallbacks, buffer->vcount * sizeof(view_callback));
-
-    new = &buffer->vcallbacks[buffer->vcount - 1];
-
-    new->size_changed = cb;
-    new->data = data;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à modifier.                        *
-*                data   = object GLib à associer à l'appel.                   *
-*                                                                             *
-*  Description : Supprime un élément des vues à contacter pour mises à jour.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_code_buffer_unregister_view_callback(GCodeBuffer *buffer, GObject *data)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    for (i = 0; i < buffer->vcount; i++)
-        if (buffer->vcallbacks[i].data == data)
-        {
-            if ((i + 1) < buffer->vcount)
-                memmove(&buffer->vcallbacks[i], &buffer->vcallbacks[i + 1],
-                        (buffer->vcount - i - 1) * sizeof(view_callback));
-
-            buffer->vcount--;
-
-            buffer->vcallbacks = (view_callback *)realloc(buffer->vcallbacks,
-                                                          buffer->vcount * sizeof(view_callback));
-
-        }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : buffer = tampon de lignes à diffuser.                        *
-*                added  = indication sur la variation de la taille du tampon. *
-*                index  = indice de la première ligne à traiter.              *
-*                count  = nombre de lignes à traiter.                         *
-*                                                                             *
-*  Description : Fait suivre une variation de la quantité de lignes du tampon.*
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_code_buffer_notify_size_changed(const GCodeBuffer *buffer, bool added, size_t index, size_t count)
-{
-    size_t i;                               /* Boucle de parcours          */
-    view_callback *cb;                      /* Informations sur l'appel    */
-
-    for (i = 0; i < buffer->vcount; i++)
-    {
-        cb = &buffer->vcallbacks[i];
-
-        cb->size_changed(buffer, added, index, count, cb->data);
-
-    }
-
-}
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
deleted file mode 100644
index f600aee..0000000
--- a/src/glibext/gcodebuffer.h
+++ /dev/null
@@ -1,155 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gcodebuffer.h - prototypes pour l'affichage d'un fragment de code d'assemblage
- *
- * Copyright (C) 2010-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 _GLIBEXT_GCODEBUFFER_H
-#define _GLIBEXT_GCODEBUFFER_H
-
-
-#include <glib-object.h>
-
-
-#include "delayed.h"
-#include "gbufferline.h"
-#include "gwidthtracker.h"
-
-
-
-/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
-
-
-#define G_TYPE_CODE_BUFFER                  (g_code_buffer_get_type())
-#define G_CODE_BUFFER(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GCodeBuffer))
-#define G_CODE_BUFFER_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GCodeBufferClass))
-#define G_IS_CODE_BUFFER(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
-#define G_IS_CODE_BUFFER_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
-#define G_CODE_BUFFER_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GCodeBufferClass))
-
-
-/* Tampon pour code désassemblé (instance) */
-typedef struct _GCodeBuffer GCodeBuffer;
-
-/* Tampon pour code désassemblé (classe) */
-typedef struct _GCodeBufferClass GCodeBufferClass;
-
-
-/* Détermine le type du composant de tampon pour code désassemblé. */
-GType g_code_buffer_get_type(void);
-
-/* Crée un nouveau composant de tampon pour code désassemblé. */
-GCodeBuffer *g_code_buffer_new(BufferLineColumn);
-
-/* Compte le nombre de lignes rassemblées dans un tampon. */
-size_t g_code_buffer_count_lines(const GCodeBuffer *);
-
-/* Fournit un lien vers la structure de suivi de largeurs. */
-const GWidthTracker *g_code_buffer_get_width_tracker(const GCodeBuffer *);
-
-/* Initie une nouvelle ligne devant être insérée dans le tampon. */
-GBufferLine *g_code_buffer_prepare_new_line(GCodeBuffer *, const mrange_t *);
-
-/* Ajoute une nouvelle ligne en fin de tampon. */
-void g_code_buffer_append_new_line(GCodeBuffer *, GBufferLine *);
-
-/* Ajoute de nouvelles lignes par rapport à une ligne donnée. */
-bool g_code_buffer_insert_lines(GCodeBuffer *, GBufferLine **, size_t, const GBufferLine *, bool);
-
-/* Supprime une ou plusieurs lignes du tampon indiqué. */
-void g_code_buffer_delete_lines(GCodeBuffer *, size_t, size_t);
-
-
-
-/* FIXME */
-#define g_code_buffer_append_new_line_fixme(b) \
-    g_code_buffer_prepare_new_line(b, (mrange_t []){ { 0, 0 }, 0 })
-
-/* FIXME */
-#define g_code_buffer_insert_at(buf, a, b) NULL
-
-
-
-/* Retrouve une ligne au sein d'un tampon avec une adresse. */
-GBufferLine *g_code_buffer_find_line_by_addr(const GCodeBuffer *, const vmpa2t *, BufferLineFlags, size_t *);
-
-/* Retrouve une ligne au sein d'un tampon avec un indice. */
-GBufferLine *g_code_buffer_find_line_by_index(const GCodeBuffer *, size_t);
-
-/* Convertit une adresse en indice de ligne. */
-size_t g_code_buffer_get_index_from_address(const GCodeBuffer *, const vmpa2t *, bool);
-
-/* Retrouve l'indice associé à une ligne au sein d'un tampon. */
-size_t g_code_buffer_find_index_by_line(const GCodeBuffer *, const GBufferLine *);
-
-/* Augmente l'indentation des prochaines lignes. */
-void g_code_buffer_inc_indentation(GCodeBuffer *);
-
-/* Diminue l'indentation des prochaines lignes. */
-void g_code_buffer_dec_indentation(GCodeBuffer *);
-
-/* Traitement d'une ligne parcourue. */
-typedef bool (* process_line_fc) (GCodeBuffer *, GBufferLine *, void *);
-
-/* Lance un parcours des différentes lignes du tampon de code. */
-GDelayedWork *g_buffer_code_scan(GCodeBuffer *, const vmpa2t *, const vmpa2t *, const char *, process_line_fc, void *);
-
-
-
-/* ------------------------- CONFORTS POUR LES COMMENTAIRES ------------------------- */
-
-
-/* Séparateur commun à tous les plateformes */
-#define COMMENT_LINE_SEP "\n"
-
-
-/* Affiche un commentaire sur une ligne de tampon donnée. */
-bool g_code_buffer_update_inlined_comment(GCodeBuffer *, GBufferLine *, const char *, GObject *);
-
-/* Affiche un commentaire sur une ligne de tampon dédiée. */
-bool g_code_buffer_update_comment_area(GCodeBuffer *, GBufferLine *, const char *, bool, GObject *);
-
-/* Retrouve le créateur d'un commentaire existant. */
-GObject *g_code_buffer_get_comment_creator(const GCodeBuffer *, const GBufferLine *);
-
-/* Récupère le contenu d'un commentaire existant. */
-char *g_code_buffer_get_lines_comment(const GCodeBuffer *, const GBufferLine *);
-
-/* Supprime un commentaire existant. */
-bool g_code_buffer_delete_lines_comment(GCodeBuffer *, GBufferLine *);
-
-
-
-/* ------------------------- SIGNAUX IMMEDIATS POUR UNE VUE ------------------------- */
-
-
-/* Accompagne une variation de la quantité de lignes du tampon. */
-typedef void (* buffer_size_changed_cb) (const GCodeBuffer *, bool, size_t, size_t, GObject *);
-
-
-/* Enregistre l'adresse d'une fonction de mise à jour de vue. */
-void g_code_buffer_register_view_callback(GCodeBuffer *, buffer_size_changed_cb, GObject *);
-
-/* Supprime un élément des vues à contacter pour mises à jour. */
-void g_code_buffer_unregister_view_callback(GCodeBuffer *, GObject *);
-
-
-
-#endif  /* _GLIBEXT_GCODEBUFFER_H */
diff --git a/src/glibext/generator-int.h b/src/glibext/generator-int.h
new file mode 100644
index 0000000..d284d87
--- /dev/null
+++ b/src/glibext/generator-int.h
@@ -0,0 +1,52 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * generator-int.h - prototypes internes pour la génération de lignes à la volée
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GLIBEXT_GENERATOR_INT_H
+#define _GLIBEXT_GENERATOR_INT_H
+
+
+#include "generator.h"
+
+
+
+
+
+/* Accès à un contenu binaire quelconque (interface) */
+struct _GBinContentIface
+{
+    GTypeInterface base_iface;              /* A laisser en premier        */
+
+
+
+
+
+
+};
+
+
+/* Redéfinition */
+typedef GBinContentIface GBinContentInterface;
+
+
+
+#endif  /* _GLIBEXT_GENERATOR_INT_H */
diff --git a/src/glibext/generators/Makefile.am b/src/glibext/generators/Makefile.am
new file mode 100644
index 0000000..5dd7133
--- /dev/null
+++ b/src/glibext/generators/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES  = libglibextgenerators.la
+
+libglibextgenerators_la_SOURCES =		\
+	prologue.h prologue.c				\
+	rborder.h rborder.c
+
+libglibextgenerators_la_LDFLAGS = 
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = 
diff --git a/src/glibext/generators/prologue.c b/src/glibext/generators/prologue.c
new file mode 100644
index 0000000..7a4fea5
--- /dev/null
+++ b/src/glibext/generators/prologue.c
@@ -0,0 +1,359 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * prologue.c - génération à la volée de lignes d'introduction
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "prologue.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+
+
+#include "../gbufferline.h"
+#include "../linegen-int.h"
+#include "../linesegment.h"
+
+
+
+/* Tampon pour générateur de lignes en prologue (instance) */
+struct _GIntroGenerator
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    char **text;                            /* Lignes brutes à représenter */
+    size_t count;                           /* Quantité de ces lignes      */
+
+};
+
+/* Tampon pour générateur de lignes en prologue (classe) */
+struct _GIntroGeneratorClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Procède à l'initialisation d'une classe de générateur. */
+static void g_intro_generator_class_init(GIntroGeneratorClass *);
+
+/* Procède à l'initialisation d'un générateur de lignes d'intro. */
+static void g_intro_generator_init(GIntroGenerator *);
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_intro_generator_interface_init(GLineGeneratorInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_intro_generator_dispose(GIntroGenerator *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_intro_generator_finalize(GIntroGenerator *);
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_intro_generator_count_lines(const GIntroGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_intro_generator_compute_addr(const GIntroGenerator *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_intro_generator_contains_addr(const GIntroGenerator *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_intro_generator_get_flags(const GIntroGenerator *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_intro_generator_print(GIntroGenerator *, GBufferLine *, size_t, size_t);
+
+
+
+/* Détermine le type du générateur de lignes d'introduction à la volée. */
+G_DEFINE_TYPE_WITH_CODE(GIntroGenerator, g_intro_generator, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_intro_generator_interface_init));
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe de composant GLib à initialiser.              *
+*                                                                             *
+*  Description : Procède à l'initialisation d'une classe de générateur.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_intro_generator_class_init(GIntroGeneratorClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_intro_generator_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_intro_generator_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = composant GLib à initialiser.                    *
+*                                                                             *
+*  Description : Procède à l'initialisation d'un générateur de lignes d'intro.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_intro_generator_init(GIntroGenerator *generator)
+{
+    generator->text = NULL;
+    generator->count = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_intro_generator_interface_init(GLineGeneratorInterface *iface)
+{
+    iface->count = (linegen_count_lines_fc)g_intro_generator_count_lines;
+    iface->compute = (linegen_compute_fc)g_intro_generator_compute_addr;
+    iface->contains = (linegen_contains_fc)g_intro_generator_contains_addr;
+    iface->get_flags = (linegen_get_flags_fc)g_intro_generator_get_flags;
+    iface->print = (linegen_print_fc)g_intro_generator_print;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = instance d'objet GLib à traiter.                 *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_intro_generator_dispose(GIntroGenerator *generator)
+{
+    G_OBJECT_CLASS(g_intro_generator_parent_class)->dispose(G_OBJECT(generator));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = instance d'objet GLib à traiter.                 *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_intro_generator_finalize(GIntroGenerator *generator)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < generator->count; i++)
+        free(generator->text[i]);
+
+    if (generator->text != NULL)
+        free(generator->text);
+
+    G_OBJECT_CLASS(g_intro_generator_parent_class)->finalize(G_OBJECT(generator));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang  = trauducteur pour l'impression finale.                *
+*                text  = tableau de lignes à conserver.                       *
+*                count = taille du tableau fourni.                            *
+*                                                                             *
+*  Description : Crée un nouveau générateur de lignes d'introduction.         *
+*                                                                             *
+*  Retour      : Composant GLib créé.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GIntroGenerator *g_intro_generator_new(const GCodingLanguage *lang, char **text, size_t count)
+{
+    GIntroGenerator *result;                  /* Composant à retourner       */
+
+    result = g_object_new(G_TYPE_INTRO_GENERATOR, NULL);
+
+    result->text = text;
+    result->count = count;
+
+    g_coding_language_encapsulate_comments(lang, &result->text, &result->count);
+
+    result->text = (char **)realloc(result->text, ++result->count * sizeof(char *));
+
+    result->text[result->count - 1] = NULL;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                                                                             *
+*  Description : Indique le nombre de ligne prêtes à être générées.           *
+*                                                                             *
+*  Retour      : Nombre de lignes devant apparaître au final.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t g_intro_generator_count_lines(const GIntroGenerator *generator)
+{
+    return generator->count;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                x         = position géographique sur la ligne concernée.    *
+*                addr      = position en mémoire à analyser.                  *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_intro_generator_compute_addr(const GIntroGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+    init_vmpa(addr, 0, 0);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                addr      = position en mémoire à analyser.                  *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
+*                                                                             *
+*  Retour      : Bilan de la détermination, utilisable en comparaisons.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int g_intro_generator_contains_addr(const GIntroGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+{
+    /**
+     * Les lignes générées sont purement artificielles et sans attache.
+     * Elles n'existent donc pas.
+     */
+
+    return 1;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Renseigne sur les propriétés liées à un générateur.          *
+*                                                                             *
+*  Retour      : Propriétés particulières associées.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static BufferLineFlags g_intro_generator_get_flags(const GIntroGenerator *generator, size_t index, size_t repeat)
+{
+    return BLF_NONE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à utiliser pour l'impression.         *
+*                line      = ligne de rendu à compléter.                      *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Imprime dans une ligne de rendu le contenu représenté.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_intro_generator_print(GIntroGenerator *generator, GBufferLine *line, size_t index, size_t repeat)
+{
+    assert(repeat < generator->count);
+
+    if ((repeat + 1) != generator->count)
+    {
+        g_buffer_line_start_merge_at(line, BLC_PHYSICAL);
+
+        g_buffer_line_append_text(line, BLC_PHYSICAL, SL(generator->text[repeat]), RTT_COMMENT, NULL);
+
+        if (repeat == 0)
+            g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
+
+    }
+
+}
diff --git a/src/glibext/generators/prologue.h b/src/glibext/generators/prologue.h
new file mode 100644
index 0000000..40cdce3
--- /dev/null
+++ b/src/glibext/generators/prologue.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * prologue.h - prototypes pour la génération à la volée de lignes d'introduction
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GLIBEXT_GENERATORS_PROLOGUE_H
+#define _GLIBEXT_GENERATORS_PROLOGUE_H
+
+
+#include <glib-object.h>
+
+
+#include "../../analysis/human/lang.h"
+
+
+
+#define G_TYPE_INTRO_GENERATOR             (g_intro_generator_get_type())
+#define G_INTRO_GENERATOR(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GIntroGenerator))
+#define G_INTRO_GENERATOR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GIntroGeneratorClass))
+#define G_IS_INTRO_GENERATOR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
+#define G_IS_INTRO_GENERATOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
+#define G_INTRO_GENERATOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GIntroGeneratorClass))
+
+
+/* Tampon pour générateur de lignes en prologue (instance) */
+typedef struct _GIntroGenerator GIntroGenerator;
+
+/* Tampon pour générateur de lignes en prologue (classe) */
+typedef struct _GIntroGeneratorClass GIntroGeneratorClass;
+
+
+/* Détermine le type du générateur de lignes d'introduction à la volée. */
+GType g_intro_generator_get_type(void);
+
+/* Crée un nouveau générateur de lignes d'introduction. */
+GIntroGenerator *g_intro_generator_new(const GCodingLanguage *, char **, size_t);
+
+
+
+#endif  /* _GLIBEXT_GENERATORS_PROLOGUE_H */
diff --git a/src/glibext/generators/rborder.c b/src/glibext/generators/rborder.c
new file mode 100644
index 0000000..ff34dfb
--- /dev/null
+++ b/src/glibext/generators/rborder.c
@@ -0,0 +1,361 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * prologue.c - génération à la volée de délimitations de routines
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "rborder.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../gbufferline.h"
+#include "../linegen-int.h"
+#include "../linesegment.h"
+
+
+
+/* Tampon pour générateur de délimitations de routines (instance) */
+struct _GBorderGenerator
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GCodingLanguage *lang;                  /* Traduction de la sortie     */
+
+    vmpa2t addr;                            /* Position de la limite       */
+    bool start;                             /* Début ou fin de routine ?   */
+
+    MemoryDataSize msize;                   /* Taille du bus d'adresses    */
+
+};
+
+/* Tampon pour générateur de délimitations de routines (classe) */
+struct _GBorderGeneratorClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+#define ROUTINE_INTRO_MSG "--------------- BEGIN OF PROCEDURE ---------------"
+
+#define ROUTINE_OUTRO_MSG "---------------- END OF PROCEDURE ----------------"
+
+
+/* Procède à l'initialisation d'une classe de générateur. */
+static void g_border_generator_class_init(GBorderGeneratorClass *);
+
+/* Procède à l'initialisation d'un générateur de délimitations. */
+static void g_border_generator_init(GBorderGenerator *);
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_border_generator_interface_init(GLineGeneratorInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_border_generator_dispose(GBorderGenerator *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_border_generator_finalize(GBorderGenerator *);
+
+/* Indique le nombre de ligne prêtes à être générées. */
+static size_t g_border_generator_count_lines(const GBorderGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_border_generator_compute_addr(const GBorderGenerator *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_border_generator_contains_addr(const GBorderGenerator *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_border_generator_get_flags(const GBorderGenerator *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+static void g_border_generator_print(GBorderGenerator *, GBufferLine *, size_t, size_t);
+
+
+
+/* Détermine le type du générateur de délimitations de routines à la volée. */
+G_DEFINE_TYPE_WITH_CODE(GBorderGenerator, g_border_generator, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_border_generator_interface_init));
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe de composant GLib à initialiser.              *
+*                                                                             *
+*  Description : Procède à l'initialisation d'une classe de générateur.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_border_generator_class_init(GBorderGeneratorClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_border_generator_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_border_generator_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = composant GLib à initialiser.                    *
+*                                                                             *
+*  Description : Procède à l'initialisation d'un générateur de délimitations. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_border_generator_init(GBorderGenerator *generator)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_border_generator_interface_init(GLineGeneratorInterface *iface)
+{
+    iface->count = (linegen_count_lines_fc)g_border_generator_count_lines;
+    iface->compute = (linegen_compute_fc)g_border_generator_compute_addr;
+    iface->contains = (linegen_contains_fc)g_border_generator_contains_addr;
+    iface->get_flags = (linegen_get_flags_fc)g_border_generator_get_flags;
+    iface->print = (linegen_print_fc)g_border_generator_print;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = instance d'objet GLib à traiter.                 *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_border_generator_dispose(GBorderGenerator *generator)
+{
+    g_object_unref(G_OBJECT(generator->lang));
+
+    G_OBJECT_CLASS(g_border_generator_parent_class)->dispose(G_OBJECT(generator));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = instance d'objet GLib à traiter.                 *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_border_generator_finalize(GBorderGenerator *generator)
+{
+    G_OBJECT_CLASS(g_border_generator_parent_class)->finalize(G_OBJECT(generator));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : lang  = trauducteur pour l'impression finale.                *
+*                addr  = position correspondant à la délimitation à marquer.  *
+*                start = indique le type de délimitation observée.            *
+*                msize = taille des adresses représentées.                    *
+*                                                                             *
+*  Description : Crée un nouveau générateur de délimitations de routines.     *
+*                                                                             *
+*  Retour      : Composant GLib créé.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBorderGenerator *g_border_generator_new(GCodingLanguage *lang, const vmpa2t *addr, bool start, MemoryDataSize msize)
+{
+    GBorderGenerator *result;                  /* Composant à retourner       */
+
+    result = g_object_new(G_TYPE_BORDER_GENERATOR, NULL);
+
+    result->lang = lang;
+    g_object_ref(G_OBJECT(lang));
+
+    copy_vmpa(&result->addr, addr);
+    result->start = start;
+
+    result->msize = msize;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                                                                             *
+*  Description : Indique le nombre de ligne prêtes à être générées.           *
+*                                                                             *
+*  Retour      : Nombre de lignes devant apparaître au final.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t g_border_generator_count_lines(const GBorderGenerator *generator)
+{
+    return 3;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                x         = position géographique sur la ligne concernée.    *
+*                addr      = position en mémoire à analyser.                  *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_border_generator_compute_addr(const GBorderGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+    copy_vmpa(addr, &generator->addr);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                addr      = position en mémoire à analyser.                  *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
+*                                                                             *
+*  Retour      : Bilan de la détermination, utilisable en comparaisons.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int g_border_generator_contains_addr(const GBorderGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+{
+    return cmp_vmpa(addr, &generator->addr);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Renseigne sur les propriétés liées à un générateur.          *
+*                                                                             *
+*  Retour      : Propriétés particulières associées.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static BufferLineFlags g_border_generator_get_flags(const GBorderGenerator *generator, size_t index, size_t repeat)
+{
+    return BLF_NONE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à utiliser pour l'impression.         *
+*                line      = ligne de rendu à compléter.                      *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Imprime dans une ligne de rendu le contenu représenté.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_border_generator_print(GBorderGenerator *generator, GBufferLine *line, size_t index, size_t repeat)
+{
+    char *text;                             /* Texte principal à insérer   */
+
+    assert(repeat < 3);
+
+    g_buffer_line_fill_vmpa(line, &generator->addr, generator->msize, generator->msize);
+
+    if (repeat == 1)
+    {
+        text = strdup(generator->start ? ROUTINE_INTRO_MSG : ROUTINE_OUTRO_MSG);
+        g_coding_language_encapsulate_comment(generator->lang, &text);
+
+        g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+        g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(text), RTT_COMMENT, NULL);
+
+        free(text);
+
+    }
+
+}
diff --git a/src/glibext/generators/rborder.h b/src/glibext/generators/rborder.h
new file mode 100644
index 0000000..fa12734
--- /dev/null
+++ b/src/glibext/generators/rborder.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rborder.h - prototypes pour la génération à la volée de délimitations de routines
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GLIBEXT_GENERATORS_RBORDER_H
+#define _GLIBEXT_GENERATORS_RBORDER_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "../../analysis/human/lang.h"
+#include "../../arch/vmpa.h"
+
+
+
+#define G_TYPE_BORDER_GENERATOR             (g_border_generator_get_type())
+#define G_BORDER_GENERATOR(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_BUFFER, GBorderGenerator))
+#define G_BORDER_GENERATOR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_BUFFER, GBorderGeneratorClass))
+#define G_IS_BORDER_GENERATOR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_BUFFER))
+#define G_IS_BORDER_GENERATOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_BUFFER))
+#define G_BORDER_GENERATOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_BUFFER, GBorderGeneratorClass))
+
+
+/* Tampon pour générateur de délimitations de routines (instance) */
+typedef struct _GBorderGenerator GBorderGenerator;
+
+/* Tampon pour générateur de délimitations de routines (classe) */
+typedef struct _GBorderGeneratorClass GBorderGeneratorClass;
+
+
+/* Détermine le type du générateur de délimitations de routines à la volée. */
+GType g_border_generator_get_type(void);
+
+/* Crée un nouveau générateur de délimitations de routines. */
+GBorderGenerator *g_border_generator_new(GCodingLanguage *, const vmpa2t *, bool, MemoryDataSize);
+
+
+
+#endif  /* _GLIBEXT_GENERATORS_RBORDER_H */
diff --git a/src/glibext/gwidthtracker.c b/src/glibext/gwidthtracker.c
index 3a1863e..cd452bc 100644
--- a/src/glibext/gwidthtracker.c
+++ b/src/glibext/gwidthtracker.c
@@ -30,7 +30,7 @@
 #include <string.h>
 
 
-#include "gcodebuffer.h"
+#include "gbuffercache.h"
 
 
 
@@ -51,7 +51,7 @@ struct _GWidthTracker
 {
     GObject parent;                         /* A laisser en premier        */
 
-    GCodeBuffer *buffer;                    /* Ensemble complet de lignes  */
+    GBufferCache *cache;                    /* Ensemble complet de lignes  */
 
     common_metrics *portions;               /* Portions représentées       */
     size_t count;                           /* Quantité de ces portions    */
@@ -163,7 +163,7 @@ static void g_width_tracker_init(GWidthTracker *tracker)
 
 static void g_width_tracker_dispose(GWidthTracker *tracker)
 {
-    g_object_unref(G_OBJECT(tracker->buffer));
+    g_object_unref(G_OBJECT(tracker->cache));
 
     G_OBJECT_CLASS(g_width_tracker_parent_class)->dispose(G_OBJECT(tracker));
 
@@ -203,14 +203,14 @@ static void g_width_tracker_finalize(GWidthTracker *tracker)
 *                                                                             *
 ******************************************************************************/
 
-GWidthTracker *g_width_tracker_new(GCodeBuffer *buffer)
+GWidthTracker *g_width_tracker_new(GBufferCache *cache)
 {
     GWidthTracker *result;                  /* Composant à retourner       */
 
     result = g_object_new(G_TYPE_WIDTH_TRACKER, NULL);
 
-    g_object_ref(G_OBJECT(buffer));
-    result->buffer = buffer;
+    g_object_ref(G_OBJECT(cache));
+    result->cache = cache;
 
     return result;
 
@@ -240,8 +240,8 @@ GWidthTracker *g_width_tracker_new_restricted(const GWidthTracker *template, siz
 
     result = g_object_new(G_TYPE_WIDTH_TRACKER, NULL);
 
-    g_object_ref(G_OBJECT(template->buffer));
-    result->buffer = template->buffer;
+    g_object_ref(G_OBJECT(template->cache));
+    result->cache = template->cache;
 
     start = g_width_tracker_find_metrics(template, first);
     assert(start < template->count);
@@ -404,7 +404,6 @@ static const line_width_summary *g_width_tracker_get_up_to_date_widths(GWidthTra
 {
     common_metrics *portion;                /* Portion à actualiser        */
     size_t i;                               /* Boucle de parcours          */
-    GBufferLine *line;                      /* Ligne à manipuler           */
 
     assert(index < tracker->count);
 
@@ -419,12 +418,7 @@ static const line_width_summary *g_width_tracker_get_up_to_date_widths(GWidthTra
         /* Collecte */
 
         for (i = portion->first; i <= portion->last; i++)
-        {
-            line = g_code_buffer_find_line_by_index(tracker->buffer, i);
-
-            g_buffer_line_collect_widths(line, &portion->summary);
-
-        }
+            g_buffer_cache_collect_widths(tracker->cache, i, &portion->summary);
 
         /* Marquage pour mémoire */
 
@@ -441,6 +435,30 @@ static const line_width_summary *g_width_tracker_get_up_to_date_widths(GWidthTra
 *                                                                             *
 *  Paramètres  : tracker = gestionnaire de largeurs de lignes à mettre jour.  *
 *                index   = position de la première des lignes à ajouter.      *
+*                                                                             *
+*  Description : Prend acte d'un changement sur une ligne pour les largeurs.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_width_tracker_update(GWidthTracker *tracker, size_t index)
+{
+    size_t current;                         /* Indice de portion visée     */
+
+    current = g_width_tracker_find_metrics(tracker, index);
+
+    g_width_tracker_reset_widths(tracker, current);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tracker = gestionnaire de largeurs de lignes à mettre jour.  *
+*                index   = position de la première des lignes à ajouter.      *
 *                count   = quantité de lignes devant être ajoutées.           *
 *                                                                             *
 *  Description : Prend acte de l'ajout de lignes pour les largeurs.           *
@@ -457,7 +475,6 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
     common_metrics *portion;                /* Portion sélectionnée        */
     size_t next;                            /* Prochaine portion à décaller*/
     size_t i;                               /* Boucle de parcours          */
-    GBufferLine *line;                      /* Ligne à manipuler           */
     size_t dest;                            /* Destination d'une recopie   */
     size_t src;                             /* Source d'une recopie        */
 
@@ -502,9 +519,7 @@ void g_width_tracker_update_added(GWidthTracker *tracker, size_t index, size_t c
 
     for (i = index + count - 1; i >= index; i--)
     {
-        line = g_code_buffer_find_line_by_index(tracker->buffer, i);
-
-        if (g_buffer_line_get_flags(line) & BLF_WIDTH_MANAGER)
+        if (g_buffer_cache_get_line_flags(tracker->cache, i) & BLF_WIDTH_MANAGER)
         {
             /* Insertion d'une nouvelle place */
 
@@ -602,11 +617,11 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
 
     /* Suppression de portions inutiles ? */
 
-    keep_first = (tracker->portions[first].first > start || end < tracker->portions[first].last);
+    keep_first = (tracker->portions[first].first < start || end < tracker->portions[first].last);
 
     dest = (keep_first ? first + 1 : first);
 
-    keep_last = (tracker->portions[last].first > start || end < tracker->portions[last].last);
+    keep_last = (tracker->portions[last].first < start || end < tracker->portions[last].last);
 
     src = (keep_last ? last : last + 1);
 
@@ -647,7 +662,7 @@ void g_width_tracker_update_deleted(GWidthTracker *tracker, size_t start, size_t
         if (end < tracker->portions[first].last)
             tracker->portions[first].last -= diff;
         else
-            tracker->portions[first].last = start;
+            tracker->portions[first].last = start - 1;
     }
 
     if (keep_last && last != first)
diff --git a/src/glibext/gwidthtracker.h b/src/glibext/gwidthtracker.h
index fe22088..b9d22ed 100644
--- a/src/glibext/gwidthtracker.h
+++ b/src/glibext/gwidthtracker.h
@@ -33,9 +33,8 @@
 
 
 
-/* gcodebuffer.h : Tampon pour code désassemblé (instance) */
-typedef struct _GCodeBuffer GCodeBuffer;
-
+/* gbuffercache.h : Tampon pour gestion de lignes optimisée (instance) */
+typedef struct _GBufferCache GBufferCache;
 
 
 #define G_TYPE_WIDTH_TRACKER            (g_width_tracker_get_type())
@@ -57,11 +56,14 @@ typedef struct _GWidthTrackerClass GWidthTrackerClass;
 GType g_width_tracker_get_type(void);
 
 /* Crée un nouveau suivi de largeurs au sein de lignes. */
-GWidthTracker *g_width_tracker_new(GCodeBuffer *);
+GWidthTracker *g_width_tracker_new(GBufferCache *);
 
 /* Crée un nouveau suivi de largeurs au sein de lignes. */
 GWidthTracker *g_width_tracker_new_restricted(const GWidthTracker *, size_t, size_t);
 
+/* Prend acte d'un changement sur une ligne pour les largeurs. */
+void g_width_tracker_update(GWidthTracker *, size_t);
+
 /* Prend acte de l'ajout de lignes pour les largeurs. */
 void g_width_tracker_update_added(GWidthTracker *, size_t, size_t);
 
diff --git a/src/glibext/linecolumn.c b/src/glibext/linecolumn.c
index 83413cf..5cce969 100644
--- a/src/glibext/linecolumn.c
+++ b/src/glibext/linecolumn.c
@@ -389,7 +389,7 @@ line_segment *get_line_column_content_from_index(const line_column *column, size
 {
     line_segment *result;                   /* Trouvaille à retourner      */
 
-    assert(index < column->count);
+    assert(index != -1 && index < column->count);
 
     result = column->segments[index];
 
diff --git a/src/glibext/linegen-int.h b/src/glibext/linegen-int.h
new file mode 100644
index 0000000..f43b2f3
--- /dev/null
+++ b/src/glibext/linegen-int.h
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linegen-int.h - définitions internes propres aux intermédiaires de génération de lignes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GLIBEXT_LINEGEN_INT_H
+#define _GLIBEXT_LINEGEN_INT_H
+
+
+#include "linegen.h"
+
+
+
+/* Indique le nombre de ligne prêtes à être générées. */
+typedef size_t (* linegen_count_lines_fc) (const GLineGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+typedef void (* linegen_compute_fc) (const GLineGenerator *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+typedef int (* linegen_contains_fc) (const GLineGenerator *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+typedef BufferLineFlags (* linegen_get_flags_fc) (const GLineGenerator *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+typedef void (* linegen_print_fc) (GLineGenerator *, GBufferLine *, size_t, size_t);
+
+
+/* Intermédiaire pour la génération de lignes (interface) */
+struct _GLineGeneratorIface
+{
+    GTypeInterface base_iface;              /* A laisser en premier        */
+
+    linegen_count_lines_fc count;           /* Décompte des lignes         */
+    linegen_compute_fc compute;             /* Calcul d'emplacement        */
+    linegen_contains_fc contains;           /* Inclusion de positions      */
+    linegen_get_flags_fc get_flags;         /* Récupération des drapeaux   */
+    linegen_print_fc print;                 /* Impression d'une ligne      */
+
+};
+
+
+/* Redéfinition */
+typedef GLineGeneratorIface GLineGeneratorInterface;
+
+
+
+#endif  /* _GLIBEXT_LINEGEN_INT_H */
diff --git a/src/glibext/linegen.c b/src/glibext/linegen.c
new file mode 100644
index 0000000..fc0e01e
--- /dev/null
+++ b/src/glibext/linegen.c
@@ -0,0 +1,208 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linegen.c - intermédiaires de génération de lignes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "linegen.h"
+
+
+#include <assert.h>
+
+
+#include "linegen-int.h"
+
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void g_line_generator_default_init(GLineGeneratorInterface *);
+
+
+
+/* Détermine le type d'une interface pour la mise en place de lignes. */
+G_DEFINE_INTERFACE(GLineGenerator, g_line_generator, G_TYPE_OBJECT)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_line_generator_default_init(GLineGeneratorInterface *iface)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                                                                             *
+*  Description : Indique le nombre de ligne prêtes à être générées.           *
+*                                                                             *
+*  Retour      : Nombre de lignes devant apparaître au final.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_line_generator_count_lines(const GLineGenerator *generator)
+{
+    size_t result;                          /* Décompte à retourner        */
+    GLineGeneratorIface *iface;             /* Interface utilisée          */
+
+    iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+    result = iface->count(generator);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                x         = position géographique sur la ligne concernée.    *
+*                addr      = position en mémoire à analyser.                  *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Retrouve l'emplacement correspondant à une position donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_line_generator_compute_addr(const GLineGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+{
+    GLineGeneratorIface *iface;             /* Interface utilisée          */
+
+    iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+#ifndef NDEBUG
+    if (iface->count != NULL)
+        assert(repeat < g_line_generator_count_lines(generator));
+#endif
+
+    iface->compute(generator, x, addr, index, repeat);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                addr      = position en mémoire à analyser.                  *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
+*                                                                             *
+*  Retour      : Bilan de la détermination, utilisable en comparaisons.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int g_line_generator_contains_addr(const GLineGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+{
+    GLineGeneratorIface *iface;             /* Interface utilisée          */
+
+    iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+#ifndef NDEBUG
+    if (iface->count != NULL)
+        assert(repeat < g_line_generator_count_lines(generator));
+#endif
+
+    return iface->contains(generator, addr, index, repeat);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à consulter.                          *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Renseigne sur les propriétés liées à un générateur.          *
+*                                                                             *
+*  Retour      : Propriétés particulières associées.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+BufferLineFlags g_line_generator_get_flags(const GLineGenerator *generator, size_t index, size_t repeat)
+{
+    GLineGeneratorIface *iface;             /* Interface utilisée          */
+
+    iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+#ifndef NDEBUG
+    if (iface->count != NULL)
+        assert(repeat < g_line_generator_count_lines(generator));
+#endif
+
+    return iface->get_flags(generator, index, repeat);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : generator = générateur à utiliser pour l'impression.         *
+*                line      = ligne de rendu à compléter.                      *
+*                index     = indice de cette même ligne dans le tampon global.*
+*                repeat    = indice d'utilisations successives du générateur. *
+*                                                                             *
+*  Description : Imprime dans une ligne de rendu le contenu représenté.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_line_generator_print(GLineGenerator *generator, GBufferLine *line, size_t index, size_t repeat)
+{
+    GLineGeneratorIface *iface;             /* Interface utilisée          */
+
+    iface = G_LINE_GENERATOR_GET_IFACE(generator);
+
+#ifndef NDEBUG
+    if (iface->count != NULL)
+        assert(repeat < g_line_generator_count_lines(generator));
+#endif
+
+    return iface->print(generator, line, index, repeat);
+
+}
diff --git a/src/glibext/linegen.h b/src/glibext/linegen.h
new file mode 100644
index 0000000..c64baaa
--- /dev/null
+++ b/src/glibext/linegen.h
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linegen.h - prototypes pour les intermédiaires de génération de lignes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GLIBEXT_LINEGEN_H
+#define _GLIBEXT_LINEGEN_H
+
+
+
+#include "gbufferline.h"
+
+
+
+#define G_TYPE_LINE_GENERATOR               (g_line_generator_get_type())
+#define G_LINE_GENERATOR(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LINE_GENERATOR, GLineGenerator))
+#define G_LINE_GENERATOR_CLASS(vtable)      (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LINE_GENERATOR, GLineGeneratorIface))
+#define GTK_IS_LINE_GENERATOR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LINE_GENERATOR))
+#define GTK_IS_LINE_GENERATOR_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LINE_GENERATOR))
+#define G_LINE_GENERATOR_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LINE_GENERATOR, GLineGeneratorIface))
+
+
+/* Intermédiaire pour la génération de lignes (coquille vide) */
+typedef struct _GLineGenerator GLineGenerator;
+
+/* Intermédiaire pour la génération de lignes (interface) */
+typedef struct _GLineGeneratorIface GLineGeneratorIface;
+
+
+/* Détermine le type d'une interface pour la mise en place de lignes. */
+GType g_line_generator_get_type(void) G_GNUC_CONST;
+
+/* Indique le nombre de ligne prêtes à être générées. */
+size_t g_line_generator_count_lines(const GLineGenerator *);
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+void g_line_generator_compute_addr(const GLineGenerator *, gint, vmpa2t *, size_t, size_t);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+int g_line_generator_contains_addr(const GLineGenerator *, const vmpa2t *, size_t, size_t);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+BufferLineFlags g_line_generator_get_flags(const GLineGenerator *, size_t, size_t);
+
+/* Imprime dans une ligne de rendu le contenu représenté. */
+void g_line_generator_print(GLineGenerator *, GBufferLine *, size_t, size_t);
+
+
+
+#endif  /* _GLIBEXT_LINEGEN_H */
diff --git a/src/glibext/linesegment.c b/src/glibext/linesegment.c
index 8306320..5208db6 100644
--- a/src/glibext/linesegment.c
+++ b/src/glibext/linesegment.c
@@ -47,7 +47,11 @@
 
 static const char *_segment_names[RTT_COUNT] = {
 
+    [RTT_NONE]          = SEGMENT_NAME("none"),
     [RTT_RAW]           = SEGMENT_NAME("raw"),
+    [RTT_RAW_NULL]      = SEGMENT_NAME("raw-null"),
+    [RTT_PRINTABLE]     = SEGMENT_NAME("printable"),
+    [RTT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"),
     [RTT_COMMENT]       = SEGMENT_NAME("comment"),
     [RTT_INDICATION]    = SEGMENT_NAME("indication"),
     [RTT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"),
@@ -55,6 +59,7 @@ static const char *_segment_names[RTT_COUNT] = {
     [RTT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"),
     [RTT_VIRT_ADDR]     = SEGMENT_NAME("virt-addr"),
     [RTT_RAW_CODE]      = SEGMENT_NAME("raw-code"),
+    [RTT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"),
     [RTT_LABEL]         = SEGMENT_NAME("label"),
     [RTT_INSTRUCTION]   = SEGMENT_NAME("instruction"),
     [RTT_IMMEDIATE]     = SEGMENT_NAME("immediate"),
@@ -162,6 +167,10 @@ struct _segcnt_list
 };
 
 
+/* Indique si le contenu d'un segment est notable ou non. */
+bool selection_list_has_segment_content(const segcnt_list *, const line_segment *);
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                          NATURE POUR UN FRAGMENT DE TEXTE                          */
diff --git a/src/glibext/linesegment.h b/src/glibext/linesegment.h
index da43e7e..892dce2 100644
--- a/src/glibext/linesegment.h
+++ b/src/glibext/linesegment.h
@@ -66,7 +66,12 @@ void exit_segment_content_hash_table(void);
 /* Types de partie de rendu */
 typedef enum _RenderingTagType
 {
+    RTT_NONE,                               /* Espace ou tabulation        */
+
     RTT_RAW,                                /* Contenu brut                */
+    RTT_RAW_NULL,                           /* Contenu brut et nul         */
+    RTT_PRINTABLE,                          /* Caractère imprimable        */
+    RTT_NOT_PRINTABLE,                      /* Caractère non imprimable    */
 
     RTT_COMMENT,                            /* Commentaire                 */
     RTT_INDICATION,                         /* Aide à la lecture           */
@@ -76,6 +81,7 @@ typedef enum _RenderingTagType
     RTT_VIRT_ADDR_PAD,                      /* Adresse virtuelle (début)   */
     RTT_VIRT_ADDR,                          /* Adresse virtuelle           */
     RTT_RAW_CODE,                           /* Code binaire brut           */
+    RTT_RAW_CODE_NULL,                      /* Code binaire brut et nul    */
 
     RTT_LABEL,                              /* Etiquette sur une adresse   */
 
@@ -188,9 +194,6 @@ bool reset_segment_content_list(segcnt_list *);
 /* Marque le contenu d'un segment comme remarquable. */
 bool add_segment_content_to_selection_list(segcnt_list *, const line_segment *);
 
-/* Indique si le contenu d'un segment est notable ou non. */
-bool selection_list_has_segment_content(const segcnt_list *, const line_segment *);
-
 
 
 #endif  /* _GLIBEXT_LINESEGMENT_H */
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 45ce4ad..d874ac1 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -1,21 +1,20 @@
 
 noinst_LTLIBRARIES = libgtkext.la
 
-libgtkext_la_SOURCES =					\
-	easygtk.h easygtk.c					\
-	gtkbinarystrip.h gtkbinarystrip.c	\
-	gtkextstatusbar.h gtkextstatusbar.c	\
-	gtkblockview.h gtkblockview.c		\
-	gtkbufferview-int.h					\
-	gtkbufferview.h gtkbufferview.c		\
-	gtkdisplaypanel-int.h				\
-	gtkdisplaypanel.h gtkdisplaypanel.c	\
-	gtkdockable-int.h					\
-	gtkdockable.h gtkdockable.c			\
-	gtkdockstation.h gtkdockstation.c	\
-	gtkgraphview.h gtkgraphview.c		\
-	gtksourceview.h gtksourceview.c		\
-	gtkstatusstack.h gtkstatusstack.c	\
+libgtkext_la_SOURCES =						\
+	easygtk.h easygtk.c						\
+	gtkbinarystrip.h gtkbinarystrip.c		\
+	gtkextstatusbar.h gtkextstatusbar.c		\
+	gtkblockdisplay.h gtkblockdisplay.c		\
+	gtkbufferdisplay-int.h					\
+	gtkbufferdisplay.h gtkbufferdisplay.c	\
+	gtkdisplaypanel-int.h					\
+	gtkdisplaypanel.h gtkdisplaypanel.c		\
+	gtkdockable-int.h						\
+	gtkdockable.h gtkdockable.c				\
+	gtkdockstation.h gtkdockstation.c		\
+	gtkgraphdisplay.h gtkgraphdisplay.c		\
+	gtkstatusstack.h gtkstatusstack.c		\
 	support.h support.c
 
 libgtkext_la_LIBADD = 					\
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 06e06c2..558e3cd 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -30,8 +30,8 @@
 #include <string.h>
 
 
-#include "../gtkblockview.h"
-#include "../gtkbufferview.h"
+#include "../gtkblockdisplay.h"
+#include "../gtkbufferdisplay.h"
 #include "../gtkdisplaypanel.h"
 #include "../../common/sort.h"
 
@@ -104,7 +104,7 @@ struct _GGraphCluster
     size_t ta_count;                        /* Quantité de ces accroches   */
 
     GBasicBlock *block;                     /* Bloc d'origine représenté   */
-    GtkWidget *view;                        /* Vue graphique associée      */
+    GtkWidget *display;                     /* Vue graphique associée      */
     GtkAllocation alloc;                    /* Emplacement final du bloc   */
 
     leaving_edge **bottom_anchors;          /* Accroches inférieures       */
@@ -255,7 +255,7 @@ static void g_graph_cluster_init(GGraphCluster *cluster)
 static void g_graph_cluster_dispose(GGraphCluster *cluster)
 {
     g_object_unref(G_OBJECT(cluster->block));
-    g_object_unref(G_OBJECT(cluster->view));
+    g_object_unref(G_OBJECT(cluster->display));
 
     G_OBJECT_CLASS(g_graph_cluster_parent_class)->dispose(G_OBJECT(cluster));
 
@@ -301,7 +301,7 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list
     GGraphCluster *result;                  /* Structure à retourner       */
     vmpa2t first;                           /* Début d'un groupe de lignes */
     vmpa2t last;                            /* Fin d'un groupe de lignes   */
-    GCodeBuffer *buffer;                    /* Tampon brut à découper      */
+    GBufferCache *cache;                    /* Tampon brut à découper      */
     GBufferView *view;                      /* Partie affichée du tampon   */
     GtkRequisition requisition;             /* Taille à l'écran actuelle   */
 
@@ -312,26 +312,26 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list
     result->block = g_block_list_get_block(list, index);
     g_object_ref(G_OBJECT(result->block));
 
-    result->view = gtk_block_view_new();
+    result->display = gtk_block_display_new();
 
-    gtk_widget_show(result->view);
-    gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result->view), binary, BVW_GRAPH);
+    gtk_widget_show(result->display);
+    gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result->display), binary, BVW_GRAPH);
 
-    gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->view), true);
+    gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->display), true);
 
     /* Restriction au bloc basique */
 
     g_basic_block_get_boundary_addresses(result->block, &first, &last);
 
-    buffer = g_loaded_binary_get_disassembled_buffer(binary);
+    cache = g_loaded_binary_get_disassembled_cache(binary);
 
-    view = g_buffer_view_new(buffer, highlighted);
+    view = g_buffer_view_new(cache, highlighted);
     g_buffer_view_restrict(view, &first, &last);
-    gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result->view), view);
+    gtk_buffer_display_set_view(GTK_BUFFER_DISPLAY(result->display), view);
 
     /* Détermination d'une position initiale centrée */
 
-    gtk_widget_get_preferred_size(result->view, NULL, &requisition);
+    gtk_widget_get_preferred_size(result->display, NULL, &requisition);
 
     result->alloc.x = -requisition.width / 2;
     result->alloc.y = 0;
@@ -741,7 +741,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc
 
                 if (needed.x < alloc->x)
                 {
-                    alloc->width += (alloc->x + needed.x);
+                    alloc->width += (alloc->x - needed.x);
                     alloc->x = needed.x;
                 }
 
@@ -765,7 +765,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc
 
                 if (needed.x < alloc->x)
                 {
-                    alloc->width += (alloc->x + needed.x);
+                    alloc->width += (alloc->x - needed.x);
                     alloc->x = needed.x;
                 }
 
@@ -800,7 +800,7 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : cluster = encapsulation à traiter.                           *
-*                view    = support de destination finale.                     *
+*                display = support de destination finale.                     *
 *                                                                             *
 *  Description : Dispose chaque noeud sur la surface de destination donnée.   *
 *                                                                             *
@@ -810,23 +810,23 @@ void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAlloc
 *                                                                             *
 ******************************************************************************/
 
-void g_graph_cluster_place(GGraphCluster *cluster, GtkGraphView *view)
+void g_graph_cluster_place(GGraphCluster *cluster, GtkGraphDisplay *display)
 {
     size_t i;                               /* Boucle de parcours #1       */
     size_t j;                               /* Boucle de parcours #2       */
 
-    g_object_ref(G_OBJECT(cluster->view));
-    gtk_graph_view_put(view, cluster->view, &cluster->alloc);
+    g_object_ref(G_OBJECT(cluster->display));
+    gtk_graph_display_put(display, cluster->display, &cluster->alloc);
 
     for (i = 0; i < cluster->ta_count; i++)
     {
         g_object_ref(G_OBJECT(cluster->top_anchors[i]->edge));
-        gtk_graph_view_add_edge(view, cluster->top_anchors[i]->edge);
+        gtk_graph_display_add_edge(display, cluster->top_anchors[i]->edge);
     }
 
     for (i = 0; i < cluster->ranks_count; i++)
         for (j = 0; j < cluster->ranks[i].count; j++)
-            g_graph_cluster_place(cluster->ranks[i].clusters[j], view);
+            g_graph_cluster_place(cluster->ranks[i].clusters[j], display);
 
 }
 
@@ -1671,9 +1671,9 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : blocks = ensemble des blocs basiques déjà découpés.          *
-*                views  = morceaux de code à afficher de façon organisée.     *
-*                count  = quantité de ces morceaux de code.                   *
+*  Paramètres  : blocXXXXXXXXXXXXXXXXXXXXks = ensemble des blocs basiques déjà découpés.          *
+*                views  = morceaux de codXXXXXXXXXXXXXXXXXxe à afficher de façon organisée.     *
+*                count  = quantité de ces morceaux de code.XXXXXXXXXXXXXXXXXX                   *
 *                                                                             *
 *  Description : Construit un graphique à partir de blocs basiques.           *
 *                                                                             *
diff --git a/src/gtkext/graph/cluster.h b/src/gtkext/graph/cluster.h
index d43622b..9c375d3 100644
--- a/src/gtkext/graph/cluster.h
+++ b/src/gtkext/graph/cluster.h
@@ -26,7 +26,7 @@
 
 
 
-#include "../gtkgraphview.h"
+#include "../gtkgraphdisplay.h"
 #include "../../analysis/binary.h"
 #include "../../analysis/disass/block.h"
 
@@ -57,7 +57,7 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *, const GBlockList *, size_t,
 void g_graph_cluster_compute_needed_alloc(const GGraphCluster *, GtkAllocation *);
 
 /* Dispose chaque noeud sur la surface de destination donnée. */
-void g_graph_cluster_place(GGraphCluster *, GtkGraphView *);
+void g_graph_cluster_place(GGraphCluster *, GtkGraphDisplay *);
 
 
 
diff --git a/src/gtkext/graph/edge.c b/src/gtkext/graph/edge.c
index 561b9f3..27400a6 100644
--- a/src/gtkext/graph/edge.c
+++ b/src/gtkext/graph/edge.c
@@ -267,6 +267,33 @@ void g_graph_edge_resolve(GGraphEdge *edge)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : edge = ligne de rendu à modifier dans ses positions.         *
+*                dx   = déplacement à effectuer sur l'axe des abscisses.      *
+*                dy   = déplacement à effectuer sur l'axe des ordonnées.      *
+*                                                                             *
+*  Description : Opère un décallage du lien dans une direction donnée.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_graph_edge_offset(GGraphEdge *edge, gint dx, gint dy)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < edge->count; i++)
+    {
+        edge->points[i].x += dx;
+        edge->points[i].y += dy;
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : edge  = ligne de rendu à manipuler.                          *
 *                cairo = assistant pour le rendu graphique.                   *
 *                arrow = indique le besoin en flèche à l'arrivée.             *
diff --git a/src/gtkext/graph/edge.h b/src/gtkext/graph/edge.h
index f60954c..4c43edb 100644
--- a/src/gtkext/graph/edge.h
+++ b/src/gtkext/graph/edge.h
@@ -81,6 +81,9 @@ void g_graph_edge_get_x_borders(const GGraphEdge *, gint *, gint *);
 /* Détermine les positions finales d'un lien graphique. */
 void g_graph_edge_resolve(GGraphEdge *);
 
+/* Opère un décallage du lien dans une direction donnée. */
+void g_graph_edge_offset(GGraphEdge *, gint, gint);
+
 /* Dessine les liens graphiques enregistrés dans le moteur. */
 void g_graph_edge_draw(const GGraphEdge *, cairo_t *, bool);
 
diff --git a/src/gtkext/gtkblockdisplay.c b/src/gtkext/gtkblockdisplay.c
new file mode 100644
index 0000000..d53d766
--- /dev/null
+++ b/src/gtkext/gtkblockdisplay.c
@@ -0,0 +1,337 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkblockdisplay.c - affichage d'un fragment de code d'assemblage
+ *
+ * Copyright (C) 2008-2012 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "gtkblockdisplay.h"
+
+
+#include "gtkbufferdisplay-int.h"
+
+
+
+/* Composant d'affichage de bloc d'assembleur (instance) */
+struct _GtkBlockDisplay
+{
+    GtkBufferDisplay parent;                /* A laisser en premier        */
+
+};
+
+/* Composant d'affichage de code d'assembleur (classe) */
+struct _GtkBlockDisplayClass
+{
+    GtkBufferDisplayClass parent;           /* A laisser en premier        */
+
+    /* Signaux */
+
+    void (* highlight_changed) (GtkBlockDisplay *);
+
+};
+
+
+/* Procède à l'initialisation des afficheurs de bloc assembleur. */
+static void gtk_block_display_class_init(GtkBlockDisplayClass *);
+
+/* Procède à l'initialisation de l'afficheur de bloc assembleur. */
+static void gtk_block_display_init(GtkBlockDisplay *);
+
+/* Supprime toutes les références externes. */
+static void gtk_block_display_dispose(GtkBlockDisplay *);
+
+/* Procède à la libération totale de la mémoire. */
+static void gtk_block_display_finalize(GtkBlockDisplay *);
+
+/* Assure la gestion des clics de souris sur le composant. */
+static gboolean gtk_block_display_button_press(GtkWidget *, GdkEventButton *);
+
+/* Redessine l'affichage suite à un changement visuel. */
+static gboolean gtk_block_display_need_redraw(GtkBlockDisplay *, GBufferView *);
+
+/* Prend acte de l'association d'un binaire chargé. */
+static void gtk_block_display_attach_binary(GtkBlockDisplay *, GLoadedBinary *);
+
+/* Réagit à un déplacement de curseur. */
+static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *, const GdkRectangle *, const vmpa2t *);
+
+
+
+/* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */
+G_DEFINE_TYPE(GtkBlockDisplay, gtk_block_display, GTK_TYPE_BUFFER_DISPLAY)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe GTK à initialiser.                            *
+*                                                                             *
+*  Description : Procède à l'initialisation des afficheurs de bloc assembleur.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_block_display_class_init(GtkBlockDisplayClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GtkWidgetClass *widget_class;           /* Classe version Widget       */
+    GtkDisplayPanelClass *panel_class;      /* Classe parente              */
+    GtkBufferDisplayClass *buffer_class;    /* Classe supérieure           */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)gtk_block_display_dispose;
+    object->finalize = (GObjectFinalizeFunc)gtk_block_display_finalize;
+
+    widget_class = GTK_WIDGET_CLASS(class);
+
+    widget_class->button_press_event = gtk_block_display_button_press;
+
+    panel_class = GTK_DISPLAY_PANEL_CLASS(class);
+
+    panel_class->attach = (attach_binary_fc)gtk_block_display_attach_binary;
+
+    buffer_class = GTK_BUFFER_DISPLAY_CLASS(class);
+
+    buffer_class->notify_caret = (notify_caret_relocation_fc)gtk_block_display_notify_caret_relocation;
+
+    /* Signaux */
+
+    g_signal_new("highlight-changed",
+                 GTK_TYPE_BLOCK_DISPLAY,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GtkBlockDisplayClass, highlight_changed),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view = composant GTK à initialiser.                          *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'afficheur de bloc assembleur.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_block_display_init(GtkBlockDisplay *view)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_block_display_dispose(GtkBlockDisplay *display)
+{
+    G_OBJECT_CLASS(gtk_block_display_parent_class)->dispose(G_OBJECT(display));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance d'objet Gtk à traiter.                    *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_block_display_finalize(GtkBlockDisplay *display)
+{
+    G_OBJECT_CLASS(gtk_block_display_parent_class)->finalize(G_OBJECT(display));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un nouveau composant pour l'affichage de bloc en ASM.   *
+*                                                                             *
+*  Retour      : Composant GTK créé.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *gtk_block_display_new(void)
+{
+    GtkBlockDisplay *result;                   /* Composant à retourner       */
+
+    result = g_object_new(GTK_TYPE_BLOCK_DISPLAY, NULL);
+
+    return GTK_WIDGET(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK visé par l'opération.                 *
+*                event  = informations liées à l'événement.                   *
+*                                                                             *
+*  Description : Assure la gestion des clics de souris sur le composant.      *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_block_display_button_press(GtkWidget *widget, GdkEventButton *event)
+{
+    GtkBlockDisplay *display;               /* Autre version du composant  */
+    gint real_x;                            /* Abscisse absolue réelle     */
+    gint real_y;                            /* Ordonnée absolue réelle     */
+    GBufferView *view;                      /* Vue du tampon représenté    */
+    bool changed;                           /* Suivi des changements       */
+
+    GTK_WIDGET_CLASS(gtk_block_display_parent_class)->button_press_event(widget, event);
+
+    display = GTK_BLOCK_DISPLAY(widget);
+
+    if (event->type == GDK_2BUTTON_PRESS)
+    {
+        real_x = event->x;
+        real_y = event->y;
+
+        gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(display), &real_x, &real_y);
+
+        view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display));
+
+        changed = g_buffer_view_highlight_segments(view, real_x, real_y, GTK_DISPLAY_PANEL(display)->display);
+
+        g_object_unref(G_OBJECT(view));
+
+        if (changed)
+            g_signal_emit_by_name(display, "highlight-changed");
+
+    }
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK d'affichage.                         *
+*                view    = composant GLib interne.                            *
+*                                                                             *
+*  Description : Redessine l'affichage suite à un changement visuel.          *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_block_display_need_redraw(GtkBlockDisplay *display, GBufferView *view)
+{
+    gtk_widget_queue_draw(GTK_WIDGET(display));
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à mettre à jour.                     *
+*                binary  = binaire associé à intégrer.                        *
+*                                                                             *
+*  Description : Prend acte de l'association d'un binaire chargé.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_block_display_attach_binary(GtkBlockDisplay *display, GLoadedBinary *binary)
+{
+    GBufferCache *cache;                    /* Tampon par défaut           */
+    GBufferView *view;                      /* Vue sur ce même tampon      */
+
+    cache = g_loaded_binary_get_disassembled_cache(binary);
+    view = g_buffer_view_new(cache, NULL);
+
+    gtk_buffer_display_set_view(GTK_BUFFER_DISPLAY(display), view);
+
+    g_signal_connect_swapped(G_OBJECT(view), "need-redraw",
+                             G_CALLBACK(gtk_block_display_need_redraw), display);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                area    = emplacement pour le dessin d'un curseur.           *
+*                addr    = position dans la mémoire représentée du curseur.   *
+*                                                                             *
+*  Description : Réagit à un déplacement de curseur.                          *
+*                                                                             *
+*  Retour      : true si un changement a été opéré.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *display, const GdkRectangle *area, const vmpa2t *addr)
+{
+    bool result;                            /* Bilan à retourner           */
+    GBufferView *view;                      /* Vue du tampon représenté    */
+
+    view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display));
+
+    result = g_buffer_view_highlight_segments(view, area->x, area->y, GTK_DISPLAY_PANEL(display)->display);
+
+    g_object_unref(G_OBJECT(view));
+
+    if (result)
+        g_signal_emit_by_name(display, "highlight-changed");
+
+    return result;
+
+}
diff --git a/src/gtkext/gtkblockdisplay.h b/src/gtkext/gtkblockdisplay.h
new file mode 100644
index 0000000..caef762
--- /dev/null
+++ b/src/gtkext/gtkblockdisplay.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkblockdisplay.h - prototypes pour l'affichage d'un fragment de code d'assemblage
+ *
+ * Copyright (C) 2008-2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GTKEXT_GTKBLOCKDISPLAY_H
+#define _GTKEXT_GTKBLOCKDISPLAY_H
+
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+
+
+#define GTK_TYPE_BLOCK_DISPLAY              (gtk_block_display_get_type())
+#define GTK_BLOCK_DISPLAY(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplay))
+#define GTK_BLOCK_DISPLAY_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplayClass))
+#define GTK_IS_BLOCK_DISPLAY(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BLOCK_DISPLAY))
+#define GTK_IS_BLOCK_DISPLAY_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BLOCK_DISPLAY))
+#define GTK_BLOCK_DISPLAY_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BLOCK_DISPLAY, GtkBlockDisplayClass))
+
+
+/* Composant d'affichage de code d'assembleur (instance) */
+typedef struct _GtkBlockDisplay GtkBlockDisplay;
+
+/* Composant d'affichage de code d'assembleur (classe) */
+typedef struct _GtkBlockDisplayClass GtkBlockDisplayClass;
+
+
+/* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */
+GType gtk_block_display_get_type(void);
+
+/* Crée un nouveau composant pour l'affichage de bloc en ASM. */
+GtkWidget *gtk_block_display_new(void);
+
+
+
+#endif  /* _GTKEXT_GTKBLOCKDISPLAY_H */
diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c
deleted file mode 100644
index 82743b0..0000000
--- a/src/gtkext/gtkblockview.c
+++ /dev/null
@@ -1,289 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkblockview.c - affichage d'un fragment de code d'assemblage
- *
- * Copyright (C) 2008-2012 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 "gtkblockview.h"
-
-
-#include "gtkbufferview-int.h"
-
-
-
-/* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */
-
-
-/* Composant d'affichage de bloc d'assembleur (instance) */
-struct _GtkBlockView
-{
-    GtkBufferView parent;                   /* A laisser en premier        */
-
-};
-
-/* Composant d'affichage de code d'assembleur (classe) */
-struct _GtkBlockViewClass
-{
-    GtkBufferViewClass parent;              /* A laisser en premier        */
-
-    /* Signaux */
-
-    void (* highlight_changed) (GtkBlockView *);
-
-};
-
-
-/* Procède à l'initialisation des afficheurs de bloc assembleur. */
-static void gtk_block_view_class_init(GtkBlockViewClass *);
-
-/* Procède à l'initialisation de l'afficheur de bloc assembleur. */
-static void gtk_block_view_init(GtkBlockView *);
-
-/* Réagit à un déplacement de curseur. */
-static bool gtk_block_view_notify_caret_relocation(GtkBlockView *, const GdkRectangle *, const vmpa2t *);
-
-/* Assure la gestion des clics de souris sur le composant. */
-static gboolean gtk_block_view_button_press_event(GtkBlockView *, GdkEventButton *, gpointer);
-
-/* Redessine l'affichage suite à un changement visuel. */
-static gboolean gtk_block_view_need_redraw(GBufferView *, GtkBlockView *);
-
-/* Prend acte de l'association d'un binaire chargé. */
-static void gtk_block_view_attach_binary(GtkBlockView *, GLoadedBinary *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            INTERACTION DIRECTE AVEC GTK                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */
-G_DEFINE_TYPE(GtkBlockView, gtk_block_view, GTK_TYPE_BUFFER_VIEW)
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : class = classe GTK à initialiser.                            *
-*                                                                             *
-*  Description : Procède à l'initialisation des afficheurs de bloc assembleur.*
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_block_view_class_init(GtkBlockViewClass *class)
-{
-    GtkDisplayPanelClass *panel_class;      /* Classe parente              */
-    GtkBufferViewClass *buffer_class;       /* Classe supérieure           */
-
-    panel_class = GTK_DISPLAY_PANEL_CLASS(class);
-    buffer_class = GTK_BUFFER_VIEW_CLASS(class);
-
-    panel_class->attach = (attach_binary_fc)gtk_block_view_attach_binary;
-
-    buffer_class->notify_caret = (notify_caret_relocation_fc)gtk_block_view_notify_caret_relocation;
-
-    g_signal_new("highlight-changed",
-                 GTK_TYPE_BLOCK_VIEW,
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GtkBlockViewClass, highlight_changed),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__VOID,
-                 G_TYPE_NONE, 0);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à initialiser.                          *
-*                                                                             *
-*  Description : Procède à l'initialisation de l'afficheur de bloc assembleur.*
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_block_view_init(GtkBlockView *view)
-{
-
-
-    /*
-    g_signal_connect(G_OBJECT(view), "button_press_event",
-                     G_CALLBACK(gtk_block_view_button_press_event), NULL);
-    */
-
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à manipuler.                            *
-*                area = emplacement pour le dessin d'un curseur.              *
-*                addr = position dans la mémoire représentée du curseur.      *
-*                                                                             *
-*  Description : Réagit à un déplacement de curseur.                          *
-*                                                                             *
-*  Retour      : true si un changement a été opéré.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool gtk_block_view_notify_caret_relocation(GtkBlockView *view, const GdkRectangle *area, const vmpa2t *addr)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    result = g_buffer_view_highlight_segments(GTK_BUFFER_VIEW(view)->buffer_view, area->x, area->y,
-                                              GTK_DISPLAY_PANEL(view)->display);
-
-    if (result)
-        g_signal_emit_by_name(view, "highlight-changed");
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée un nouveau composant pour l'affichage de bloc en ASM.   *
-*                                                                             *
-*  Retour      : Composant GTK créé.                                          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GtkWidget *gtk_block_view_new(void)
-{
-    GtkBlockView *result;                   /* Composant à retourner       */
-
-    result = g_object_new(GTK_TYPE_BLOCK_VIEW, NULL);
-
-    return GTK_WIDGET(result);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = composant GTK visé par l'opération.                  *
-*                event = informations liées à l'événement.                    *
-*                data  = donnée non utilisée ici.                             *
-*                                                                             *
-*  Description : Assure la gestion des clics de souris sur le composant.      *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_block_view_button_press_event(GtkBlockView *view, GdkEventButton *event, gpointer data)
-{
-    GtkBufferView *bview;                   /* Autre vision du composant   */
-    gint real_x;                            /* Abscisse absolue réelle     */
-    gint real_y;                            /* Ordonnée absolue réelle     */
-
-    if (event->type == GDK_2BUTTON_PRESS)
-    {
-
-
-
-        printf("I feel %s clicked with button %d\n",
-               event->type == GDK_2BUTTON_PRESS ? "double" : "triple",
-               event->button);
-
-        bview = GTK_BUFFER_VIEW(view);
-
-        real_x = event->x;
-        real_y = event->y;
-
-        gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(bview), &real_x, &real_y);
-
-        g_buffer_view_highlight_segments(gtk_buffer_view_get_buffer(bview), real_x, real_y, NULL);
-
-
-
-    }
-
-    return FALSE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = composant GLib interne.                              *
-*                block = composant GTK d'affichage.                           *
-*                                                                             *
-*  Description : Redessine l'affichage suite à un changement visuel.          *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_block_view_need_redraw(GBufferView *view, GtkBlockView *block)
-{
-    gtk_widget_queue_draw(GTK_WIDGET(block));
-
-    return FALSE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view   = composant GTK à mettre à jour.                      *
-*                binary = binaire associé à intégrer.                         *
-*                                                                             *
-*  Description : Prend acte de l'association d'un binaire chargé.             *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_block_view_attach_binary(GtkBlockView *view, GLoadedBinary *binary)
-{
-    GCodeBuffer *buffer;                    /* Tampon par défaut           */
-    GBufferView *bview;                     /* Vue sur ce même tampon      */
-
-    buffer = g_loaded_binary_get_disassembled_buffer(binary);
-    bview = g_buffer_view_new(buffer, NULL);
-
-    gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), bview);
-
-    g_signal_connect(G_OBJECT(bview), "need-redraw",
-                     G_CALLBACK(gtk_block_view_need_redraw), view);
-
-}
diff --git a/src/gtkext/gtkblockview.h b/src/gtkext/gtkblockview.h
deleted file mode 100644
index 735d128..0000000
--- a/src/gtkext/gtkblockview.h
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkblockview.h - prototypes pour l'affichage d'un fragment de code d'assemblage
- *
- * Copyright (C) 2008-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 _GTKEXT_GTKBLOCKVIEW_H
-#define _GTKEXT_GTKBLOCKVIEW_H
-
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-
-
-#define GTK_TYPE_BLOCK_VIEW                  (gtk_block_view_get_type())
-#define GTK_BLOCK_VIEW(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BLOCK_VIEW, GtkBlockView))
-#define GTK_BLOCK_VIEW_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BLOCK_VIEW, GtkBlockViewClass))
-#define GTK_IS_BLOCK_VIEW(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BLOCK_VIEW))
-#define GTK_IS_BLOCK_VIEW_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BLOCK_VIEW))
-#define GTK_BLOCK_VIEW_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BLOCK_VIEW, GtkBlockViewClass))
-
-
-/* Composant d'affichage de code d'assembleur (instance) */
-typedef struct _GtkBlockView GtkBlockView;
-
-/* Composant d'affichage de code d'assembleur (classe) */
-typedef struct _GtkBlockViewClass GtkBlockViewClass;
-
-
-/* Détermine le type du composant d'affichage de bloc en langage d'assemblage. */
-GType gtk_block_view_get_type(void);
-
-/* Crée un nouveau composant pour l'affichage de bloc en ASM. */
-GtkWidget *gtk_block_view_new(void);
-
-
-
-#endif  /* _GTKEXT_GTKBLOCKVIEW_H */
diff --git a/src/gtkext/gtkbufferdisplay-int.h b/src/gtkext/gtkbufferdisplay-int.h
new file mode 100644
index 0000000..4406361
--- /dev/null
+++ b/src/gtkext/gtkbufferdisplay-int.h
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkbufferdisplay-int.h - prototypes internes pour l'affichage de tampons de lignes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GTK_BUFFERDISPLAY_INT_H
+#define _GTK_BUFFERDISPLAY_INT_H
+
+
+#include "gtkbufferdisplay.h"
+
+
+#include "gtkdisplaypanel-int.h"
+
+
+
+/* Réagit à un déplacement de curseur. */
+typedef bool (* notify_caret_relocation_fc) (GtkBufferDisplay *, const GdkRectangle *, const vmpa2t *);
+
+
+/* Composant d'affichage de tampon de lignes (instance) */
+struct _GtkBufferDisplay
+{
+    GtkDisplayPanel parent;                 /* A laisser en premier        */
+
+    GBufferView *view;                      /* Vue sur le contenu affiché  */
+
+    GdkRectangle caret;                     /* Emplacement du curseur      */
+    vmpa2t caret_addr;                      /* Position mémoire du curseur */
+    guint caret_timer;                      /* Identifiant du chronomètre  */
+    bool show_caret;                        /* Bascule entre les affichages*/
+
+};
+
+/* Composant d'affichage de tampon de lignes (classe) */
+struct _GtkBufferDisplayClass
+{
+    GtkDisplayPanelClass parent;            /* A laisser en premier        */
+
+    notify_caret_relocation_fc notify_caret;/* Accompagne un déplacement   */
+
+    /* Signaux */
+
+    void (* reach_limit) (GtkBufferDisplay *, GdkScrollDirection);
+
+};
+
+
+
+#endif  /* _GTK_BUFFERDISPLAY_INT_H */
diff --git a/src/gtkext/gtkbufferdisplay.c b/src/gtkext/gtkbufferdisplay.c
new file mode 100644
index 0000000..b510c8f
--- /dev/null
+++ b/src/gtkext/gtkbufferdisplay.c
@@ -0,0 +1,1104 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkbufferdisplay.c - affichage de tampons de lignes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "gtkbufferdisplay.h"
+
+
+#include "gtkbufferdisplay-int.h"
+
+
+#include "../core/params.h"
+
+
+
+/* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */
+
+
+/* Procède à l'initialisation de l'afficheur de tampons. */
+static void gtk_buffer_display_class_init(GtkBufferDisplayClass *);
+
+/* Procède à l'initialisation de l'afficheur de tampons. */
+static void gtk_buffer_display_init(GtkBufferDisplay *);
+
+/* Supprime toutes les références externes. */
+static void gtk_buffer_display_dispose(GtkBufferDisplay *);
+
+/* Procède à la libération totale de la mémoire. */
+static void gtk_buffer_display_finalize(GtkBufferDisplay *);
+
+/* Intègre le focus dans le rendu du composant. */
+static gboolean gtk_buffer_display_focus(GtkWidget *, GdkEventFocus *);
+
+/* Assure la gestion des clics de souris sur le composant. */
+static gboolean gtk_buffer_display_button_press(GtkWidget *, GdkEventButton *);
+
+/* Met à jour l'affichage de la visualisation de code buffer. */
+static gboolean gtk_buffer_display_draw(GtkWidget *, cairo_t *);
+
+/* Prend en compte une frappe de touche sur le composant. */
+static gboolean gtk_buffer_display_key_press(GtkWidget *, GdkEventKey *);
+
+/* Indique les dimensions de travail du composant d'affichage. */
+static void gtk_buffer_display_compute_requested_size(GtkBufferDisplay *, gint *, gint *);
+
+/* Détermine la taille des bonds lors de défilements. */
+static void gtk_buffer_display_compute_scroll_inc(GtkBufferDisplay *, gint, GtkOrientation, gdouble *, gdouble *);
+
+/* Réagit à un défilement chez une barre associée au composant. */
+static void gtk_buffer_display_adjust_scroll_value(GtkBufferDisplay *, GtkAdjustment *, GtkOrientation);
+
+/* Indique la position courante du curseur. */
+static const vmpa2t *gtk_buffer_display_get_caret_location(const GtkBufferDisplay *);
+
+/* Indique la position d'affichage d'une adresse donnée. */
+static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
+
+/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
+static void gtk_buffer_display_cache_glance(GtkBufferDisplay *, cairo_t *, const GtkAllocation *, double);
+
+
+
+/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */
+
+
+/* Déplace le curseur à un emplacement défini. */
+static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *, gint, gint);
+
+/* Déplace le curseur en effaçant son éventuelle position. */
+static void gtk_buffer_display_relocate_caret(GtkBufferDisplay *, const GdkRectangle *, const vmpa2t *);
+
+/* Redémarre l'affichage du curseur à l'emplacement courant. */
+static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *);
+
+/* Bascule et relance l'affichage du curseur. */
+static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            INTERACTION DIRECTE AVEC GTK                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type du composant d'affichage de tampon de lignes. */
+G_DEFINE_TYPE(GtkBufferDisplay, gtk_buffer_display, GTK_TYPE_DISPLAY_PANEL)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe GTK à initialiser.                            *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'afficheur de tampons.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_class_init(GtkBufferDisplayClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GtkWidgetClass *widget_class;           /* Classe version Widget       */
+    GtkDisplayPanelClass *panel_class;      /* Classe parente              */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)gtk_buffer_display_dispose;
+    object->finalize = (GObjectFinalizeFunc)gtk_buffer_display_finalize;
+
+    widget_class = GTK_WIDGET_CLASS(class);
+
+    widget_class->focus_in_event = gtk_buffer_display_focus;
+    widget_class->focus_out_event = gtk_buffer_display_focus;
+    widget_class->button_press_event = gtk_buffer_display_button_press;
+    widget_class->draw = gtk_buffer_display_draw;
+    widget_class->key_press_event = gtk_buffer_display_key_press;
+
+    panel_class = GTK_DISPLAY_PANEL_CLASS(class);
+
+    panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_display_compute_requested_size;
+    panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_display_compute_scroll_inc;
+    panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_display_adjust_scroll_value;
+    panel_class->get_caret_loc = (get_caret_location_fc)gtk_buffer_display_get_caret_location;
+    panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_display_get_address_coordinates;
+    panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_display_move_caret_to;
+    panel_class->cache_glance = (cache_glance_fc)gtk_buffer_display_cache_glance;
+
+    /* Signaux */
+
+    g_signal_new("reach-limit",
+                 GTK_TYPE_BUFFER_DISPLAY,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GtkBufferDisplayClass, reach_limit),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__ENUM,
+                 G_TYPE_NONE, 1, GTK_TYPE_SCROLL_TYPE);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à initialiser.                       *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'afficheur de tampons.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_init(GtkBufferDisplay *display)
+{
+    init_vmpa(&display->caret_addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_dispose(GtkBufferDisplay *display)
+{
+    if (display->view != NULL)
+        g_object_unref(G_OBJECT(display->view));
+
+    G_OBJECT_CLASS(gtk_buffer_display_parent_class)->dispose(G_OBJECT(display));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance d'objet Gtk à traiter.                    *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_finalize(GtkBufferDisplay *display)
+{
+    G_OBJECT_CLASS(gtk_buffer_display_parent_class)->finalize(G_OBJECT(display));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK visé par l'opération.                 *
+*                event  = informations liées à l'événement.                   *
+*                                                                             *
+*  Description : Intègre le focus dans le rendu du composant.                 *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_buffer_display_focus(GtkWidget *widget, GdkEventFocus *event)
+{
+    GtkBufferDisplay *display;              /* Autre version du composant  */
+    gboolean has_focus;                     /* Etat courant                */
+
+    display = GTK_BUFFER_DISPLAY(widget);
+    has_focus = event->in;
+
+    if (has_focus)
+        gtk_buffer_display_restart_caret_blinking(display);
+
+    else if (display->caret_timer != 0)
+    {
+        g_source_remove(display->caret_timer);
+        display->caret_timer = 0;
+
+        display->show_caret = true;
+        gtk_buffer_display_refresh_caret(display);
+
+    }
+
+    return TRUE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK visé par l'opération.                 *
+*                event  = informations liées à l'événement.                   *
+*                                                                             *
+*  Description : Assure la gestion des clics de souris sur le composant.      *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_buffer_display_button_press(GtkWidget *widget, GdkEventButton *event)
+{
+    GtkBufferDisplay *display;              /* Autre version du composant  */
+    GBufferCache *cache;                    /* Contenu représenté          */
+    gint left_margin;                       /* Limite entre zones réactives*/
+    gint real_x;                            /* Abscisse absolue réelle     */
+    gint real_y;                            /* Ordonnée absolue réelle     */
+
+    display = GTK_BUFFER_DISPLAY(widget);
+
+    real_x = event->x;
+    real_y = event->y;
+    gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(display), &real_x, &real_y);
+
+    cache = g_buffer_view_get_cache(display->view);
+
+    left_margin = g_buffer_cache_get_left_margin(cache);
+
+    g_object_unref(G_OBJECT(cache));
+
+    if (real_x < left_margin)
+    {
+        /* TODO */
+    }
+    else
+        _gtk_buffer_display_move_caret_to(display, real_x, real_y);
+
+    gtk_widget_grab_focus(widget);
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK à redessiner.                         *
+*                cr     = contexte graphique associé à l'événement.           *
+*                                                                             *
+*  Description : Met à jour l'affichage de la visualisation de code buffer.   *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
+{
+    GtkBufferDisplay *display;              /* Autre version du composant  */
+    GtkDisplayPanel *parent;                /* Autre version du composant  */
+    GdkWindow *window;                      /* Fenêtre à redessiner        */
+    cairo_region_t *region;                 /* Région visible à redessiner */
+    cairo_rectangle_int_t area;             /* Surface correspondante      */
+    GtkStyleContext *context;               /* Contexte du thème actuel    */
+    gint virt_x;                            /* Abscisse virtuelle          */
+    gint virt_y;                            /* Ordonnée virtuelle          */
+    GBufferCache *cache;                    /* Contenu représenté          */
+    gint left_margin;                       /* Marge gauche + espace       */
+    GdkRGBA color;                          /* Couleur de thème récupérée  */
+    bool sel_line;                          /* Souslignage de la sélection */
+    gint *selected;                         /* Ordonnée d'une sélection    */
+
+
+    //gboolean status;
+
+
+    GtkStyleContext *other;
+    GtkWidgetPath *path;
+
+
+    other = gtk_style_context_new();
+
+
+    path = gtk_widget_path_new ();
+    gtk_widget_path_append_type (path, GTK_TYPE_SCALE);
+    //gtk_widget_path_iter_add_class (path, 0, "slider");
+    //gtk_widget_path_iter_add_class (path, 0, "scale");
+    gtk_style_context_set_path (other, path);
+    gtk_widget_path_free (path);
+
+
+
+
+    //context = gtk_widget_get_style_context(widget);
+
+
+    //gtk_render_background(context, cr, 0, 0, 1000, 1000);
+
+
+    //status = GTK_WIDGET_CLASS(gtk_buffer_display_parent_class)->draw(widget, cr);
+
+    //printf("status: %d\n", status);
+
+    //return TRUE;
+
+
+
+
+    display = GTK_BUFFER_DISPLAY(widget);
+    parent = GTK_DISPLAY_PANEL(widget);
+
+    window = gtk_widget_get_window(widget);
+
+    cairo_save(cr);
+    gtk_cairo_transform_to_window(cr, widget, window);
+
+    region = gdk_window_get_clip_region(window);
+    cairo_region_get_extents(region, &area);
+    cairo_region_destroy(region);
+
+    context = gtk_widget_get_style_context(widget);
+
+    if (parent->show_border)
+    {
+        gtk_display_panel_define_border_path(parent, cr, 0, 0);
+        cairo_clip(cr);
+    }
+
+
+
+    gtk_render_background(context, cr, area.x, area.y, area.width, area.height);
+
+
+
+    /* Décallage pour le défilement horizontal */
+
+    virt_x = 0;
+    virt_y = 0;
+    gtk_display_panel_compute_fake_coord(parent, &virt_x, &virt_y);
+
+    cairo_save(cr);
+
+    cairo_translate(cr, virt_x, 0);
+
+    /* Récupération de la limite utile */
+
+    cache = g_buffer_view_get_cache(display->view);
+
+    left_margin = g_buffer_cache_get_left_margin(cache);
+
+    g_object_unref(G_OBJECT(cache));
+
+
+    /* Dessin de la marge gauche */
+
+    gtk_style_context_save(context);
+
+    gtk_style_context_add_class(other, GTK_STYLE_CLASS_TOOLBAR);
+
+    gtk_style_context_get_background_color(other, GTK_STATE_FLAG_ACTIVE, &color);
+
+    cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
+    //cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
+
+    cairo_rectangle(cr, 0, area.y, left_margin, area.height);
+    cairo_fill(cr);
+
+    gtk_style_context_restore(context);
+
+    /* Fond de la zone de texte */
+
+#if 1
+    gtk_style_context_save(context);
+
+    gtk_style_context_add_class(context, GTK_STYLE_CLASS_VIEW);
+
+    gtk_style_context_get_background_color(context, GTK_STATE_FLAG_ACTIVE, &color);
+
+    cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.7);
+
+    cairo_rectangle(cr, left_margin, area.y, area.width, area.height);
+    cairo_fill(cr);
+
+    gtk_style_context_restore(context);
+#endif
+
+    /* Ligne de séparation */
+
+    gtk_style_context_save(context);
+
+    gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME);
+
+    gtk_style_context_get_border_color(context, GTK_STATE_FLAG_ACTIVE, &color);
+
+    cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
+
+    cairo_set_line_width(cr, 1.0);
+
+    cairo_move_to(cr, left_margin + 0.5, area.y - 0.5);
+    cairo_line_to(cr, left_margin + 0.5, area.y + area.height + 0.5);
+    cairo_stroke(cr);
+
+    gtk_style_context_restore(context);
+
+    /* Eventuelle bordure globale */
+
+    if (parent->show_border)
+        gtk_display_panel_draw_border(parent, cr);
+
+    /* Impression du désassemblage */
+
+    if (display->view != NULL)
+    {
+        g_generic_config_get_value(get_main_configuration(), MPK_SELECTION_LINE, &sel_line);
+        sel_line &= gtk_widget_has_focus(widget);
+
+        if (!sel_line || is_invalid_vmpa(&display->caret_addr))
+            selected = NULL;
+        else
+        {
+            selected = (gint []) { display->caret.y };
+            gtk_display_panel_compute_relative_coords(parent, NULL, selected);
+        }
+
+        area.x -= virt_x;
+        virt_y += area.y;
+
+        g_buffer_view_draw(display->view, cr, virt_y, &area, parent->display, selected);
+
+    }
+
+    cairo_restore(cr);
+
+    /* Curseur clignotant ? */
+
+    /*
+    if (gtk_widget_is_focus(widget))
+    {
+        view->show_caret = !view->show_caret;
+        gtk_buffer_view_refresh_caret(view);
+    }
+    */
+
+    cairo_restore(cr);
+
+    return TRUE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant visé par l'opération.                     *
+*                event  = informations liées à l'événement.                   *
+*                                                                             *
+*  Description : Prend en compte une frappe de touche sur le composant.       *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_buffer_display_key_press(GtkWidget *widget, GdkEventKey *event)
+{
+    gboolean result;                        /* Suites à renvoyer           */
+    GdkScrollDirection dir;                 /* Direction du déplacement    */
+    GtkBufferDisplay *display;              /* Autre version du composant  */
+    GtkDisplayPanel *panel;                 /* Autre version du composant  */
+    bool ctrl;                              /* Statut de la touche Contrôle*/
+    GdkRectangle area;                      /* Emplacement de curseur      */
+    vmpa2t addr;                            /* Adresse du nouveau curseur  */
+    bool status;                            /* Validité d'un déplacement   */
+
+    switch (event->keyval)
+    {
+        case GDK_KEY_Left:
+            dir = GDK_SCROLL_LEFT;
+            result = TRUE;
+            break;
+
+        case GDK_KEY_Up:
+            dir = GDK_SCROLL_UP;
+            result = TRUE;
+            break;
+
+        case GDK_KEY_Right:
+            dir = GDK_SCROLL_RIGHT;
+            result = TRUE;
+            break;
+
+        case GDK_KEY_Down:
+            dir = GDK_SCROLL_DOWN;
+            result = TRUE;
+            break;
+
+        default:
+            result = FALSE;
+            break;
+
+    }
+
+    if (result)
+    {
+        display = GTK_BUFFER_DISPLAY(widget);
+        panel = GTK_DISPLAY_PANEL(widget);
+
+        ctrl = (event->state & GDK_CONTROL_MASK);
+        area = display->caret;
+
+        status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display, &area, &addr);
+
+        if (status)
+        {
+            gtk_buffer_display_relocate_caret(display, &area, &addr);
+            _gtk_display_panel_scroll_to_address(panel, &addr, SPT_RAW, false);
+        }
+        else
+            g_signal_emit_by_name(display, "reach-limit", dir);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à consulter.                         *
+*                width   = largeur requise à renseigner ou NULL. [OUT]        *
+*                height  = hauteur requise à renseigner ou NULL. [OUT]        *
+*                                                                             *
+*  Description : Indique les dimensions de travail du composant d'affichage.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_compute_requested_size(GtkBufferDisplay *display, gint *width, gint *height)
+{
+    if (width != NULL)
+    {
+        if (display->view != NULL)
+            *width = g_buffer_view_get_width(display->view, GTK_DISPLAY_PANEL(display)->display);
+        else
+            *width = 0;
+    }
+
+    if (height != NULL)
+    {
+        if (display->view != NULL)
+            *height = g_buffer_view_get_height(display->view);
+        else
+            *height = 0;
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display     = composant GTK d'affichage à consulter.         *
+*                size        = taille de l'espace dans la direction donnée.   *
+*                orientation = indication sur le défilement à traiter.        *
+*                step        = valeur d'un petit pas de défilement. [OUT]     *
+*                page        = valeur d'un grand pas de défilement. [OUT]     *
+*                                                                             *
+*  Description : Détermine la taille des bonds lors de défilements.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_compute_scroll_inc(GtkBufferDisplay *display, gint size, GtkOrientation orientation, gdouble *step, gdouble *page)
+{
+    GBufferCache *cache;                    /* Gestionnaire de lignes      */
+
+    if (orientation == GTK_ORIENTATION_VERTICAL && display->view != NULL)
+    {
+        cache = g_buffer_view_get_cache(display->view);
+
+        *step = g_buffer_cache_get_line_height(cache);
+        *page = *step * 10;
+
+        g_object_unref(G_OBJECT(cache));
+
+    }
+
+    else
+        GTK_DISPLAY_PANEL_CLASS(gtk_buffer_display_parent_class)->compute_inc(GTK_DISPLAY_PANEL(display),
+                                                                           size, orientation, step, page);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display     = panneau d'affichage concerné.                  *
+*                adj         = défilement dont une valeur a changé.           *
+*                orientation = indication sur le défilement à traiter.        *
+*                                                                             *
+*  Description : Réagit à un défilement chez une barre associée au composant. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_adjust_scroll_value(GtkBufferDisplay *display, GtkAdjustment *adj, GtkOrientation orientation)
+{
+    GtkWidget *widget;                      /* Autre vision du composant   */
+
+    widget = GTK_WIDGET(display);
+
+    if (gtk_widget_get_realized(widget))
+        gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, FALSE);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                                                                             *
+*  Description : Indique la position courante du curseur.                     *
+*                                                                             *
+*  Retour      : Emplacement courant du curseur ou NULL si aucun.             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const vmpa2t *gtk_buffer_display_get_caret_location(const GtkBufferDisplay *display)
+{
+    return &display->caret_addr;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à consulter.                         *
+*                addr    = adresse à présenter à l'écran.                     *
+*                x       = position horizontale au sein du composant. [OUT]   *
+*                y       = position verticale au sein du composant. [OUT]     *
+*                tweak   = adaptation finale à effectuer.                     *
+*                                                                             *
+*  Description : Indique la position d'affichage d'une adresse donnée.        *
+*                                                                             *
+*  Retour      : true si l'adresse fait partie du composant, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *display, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
+{
+    bool result;                            /* Bilan à remonter            */
+    bool need_code;                         /* Recherche plus raffinée     */
+    GBufferCache *cache;                    /* Gestionnaire de lignes      */
+    int height;                             /* Hauteur allouée             */
+
+    need_code = (tweak == SPT_BOTTOM);
+
+    cache = g_buffer_view_get_cache(display->view);
+
+    result = g_buffer_view_get_address_coordinates(display->view, addr, need_code, x, y);
+
+    if (result)
+    {
+        *x += g_buffer_view_get_margin(display->view, GTK_DISPLAY_PANEL(display)->display);
+
+        height = gtk_widget_get_allocated_height(GTK_WIDGET(display));
+
+        switch (tweak)
+        {
+            case SPT_RAW:
+                break;
+
+            case SPT_TOP:
+                break;
+
+            case SPT_CENTER:
+                *y -= (height / 2);
+                break;
+
+            case SPT_BOTTOM:
+                *y -= height;
+                *y += g_buffer_cache_get_line_height(cache);
+                break;
+
+        }
+
+    }
+
+    g_object_unref(G_OBJECT(cache));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                cairo   = assistant pour la création de rendus.              *
+*                area    = taille de la surface réduite à disposition.        *
+*                scale   = échelle vis à vis de la taille réelle.             *
+*                                                                             *
+*  Description : Place en cache un rendu destiné à l'aperçu graphique rapide. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_cache_glance(GtkBufferDisplay *display, cairo_t *cairo, const GtkAllocation *area, double scale)
+{
+    cairo_set_line_width(cairo, 1);
+    cairo_set_source_rgb(cairo, 0.4, 0.4, 0.4);
+
+    cairo_rectangle(cairo, area->x + 0.5, area->y + 0.5, area->width - 1, area->height - 1);
+
+    cairo_stroke(cairo);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance d'objet Gtk à actualiser.                 *
+*                view    = nouvelle vue à associer au composant.              *
+*                                                                             *
+*  Description : Lie une vue au composant d'affichage de tampon.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_buffer_display_set_view(GtkBufferDisplay *display, GBufferView *view)
+{
+    if (display->view != NULL)
+        g_object_unref(G_OBJECT(display->view));
+
+    display->view = view;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à consulter.                         *
+*                                                                             *
+*  Description : Fournit la vue associée au tampon de lignes courant.         *
+*                                                                             *
+*  Retour      : Vue mise en place.                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *display)
+{
+    GBufferView *result;                    /* Instance à retourner        */
+
+    result = display->view;
+
+    g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                                ANIMATION DU CURSEUR                                */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                x       = abscisse proposée pour le nouvel emplacement.      *
+*                y       = ordonnée proposée pour le nouvel emplacement.      *
+*                                                                             *
+*  Description : Déplace le curseur à un emplacement défini.                  *
+*                                                                             *
+*  Retour      : true si un traitement a été effectué, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, gint x, gint y)
+{
+    bool result;                            /* Bilan à retourner           */
+    GtkDisplayPanel *panel;                 /* Autre version du composant  */
+    vmpa2t addr;                            /* Position mémoire associée   */
+    GdkRectangle new;                       /* Nouvel emplacement calculé  */
+
+    panel = GTK_DISPLAY_PANEL(display);
+
+    result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display, &new, &addr);
+
+    if (result)
+        gtk_buffer_display_relocate_caret(display, &new, &addr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display   = composant GTK à manipuler.                       *
+*                beginning = précise le coin où se retrouvera le curseur.     *
+*                same_x    = tente de conserver une même abscisse ou NULL ?   *
+*                                                                             *
+*  Description : Déplace le curseur à un emplacement en extrémité.            *
+*                                                                             *
+*  Retour      : true si un traitement a été effectué, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, bool beginning, gint *same_x)
+{
+    bool result;                            /* Bilan à remonter            */
+    GBufferCache *cache;                    /* Contenu représenté          */
+    gint left_margin;                       /* Limite entre zones réactives*/
+    gint x;                                 /* Abscisse d'emplacement      */
+    gint y;                                 /* Ordonnée d'emplacement      */
+
+    if (beginning)
+    {
+        cache = g_buffer_view_get_cache(display->view);
+
+        left_margin = g_buffer_cache_get_left_margin(cache);
+
+        g_object_unref(G_OBJECT(cache));
+
+        x = same_x != NULL ? *same_x : left_margin * 2;
+        y = 0;
+
+    }
+    else
+    {
+        if (same_x != NULL)
+            x = *same_x;
+        else
+            gtk_widget_get_preferred_width(GTK_WIDGET(display), NULL, &x);
+
+        gtk_widget_get_preferred_height(GTK_WIDGET(display), NULL, &y);
+        y--;
+
+    }
+
+    result = _gtk_buffer_display_move_caret_to(display, x, y);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                area    = emplacement pour le dessin d'un curseur.           *
+*                addr    = position dans la mémoire représentée du curseur.   *
+*                                                                             *
+*  Description : Déplace le curseur en effaçant son éventuelle position.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_relocate_caret(GtkBufferDisplay *display, const GdkRectangle *area, const vmpa2t *addr)
+{
+    bool clear_old;                         /* Effacement chirurgical      */
+    GdkRectangle old_area;                  /* Mémorisation de l'ancien    */
+    bool need_redraw;                       /* Besoin de rafraîchissement ?*/
+
+    if (!is_invalid_vmpa(&display->caret_addr))
+    {
+        clear_old = true;
+        old_area = display->caret;
+    }
+    else
+        clear_old = false;
+
+    display->caret = *area;
+    copy_vmpa(&display->caret_addr, addr);
+
+    if (GTK_BUFFER_DISPLAY_GET_CLASS(display)->notify_caret != NULL)
+        need_redraw = GTK_BUFFER_DISPLAY_GET_CLASS(display)->notify_caret(display, area, addr);
+    else
+        need_redraw = false;
+
+    if (need_redraw)
+        gtk_widget_queue_draw(GTK_WIDGET(display));
+
+    else if (clear_old)
+    {
+        gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &old_area.x, &old_area.y);
+
+        gtk_widget_queue_draw_area(GTK_WIDGET(display), old_area.x, old_area.y,
+                                   old_area.width, old_area.height);
+
+    }
+
+    gtk_buffer_display_restart_caret_blinking(display);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                                                                             *
+*  Description : Redémarre l'affichage du curseur à l'emplacement courant.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_buffer_display_restart_caret_blinking(GtkBufferDisplay *display)
+{
+
+    GtkSettings *settings;                  /* Propriétés du système       */
+    guint interval;                         /* Fréquence d'actualisation   */
+
+    if (display->caret_timer != 0)
+    {
+        g_source_remove(display->caret_timer);
+        display->caret_timer = 0;
+    }
+
+    if (!is_invalid_vmpa(&display->caret_addr))
+    {
+        display->show_caret = false;
+        gtk_buffer_display_refresh_caret(display);
+
+        settings = gtk_settings_get_default();
+
+        g_object_get(settings, "gtk-cursor-blink-time", &interval, NULL);
+
+        g_object_ref(G_OBJECT(display));
+
+        display->caret_timer = g_timeout_add_full(G_PRIORITY_DEFAULT, interval,
+                                               (GSourceFunc)gtk_buffer_display_refresh_caret,
+                                               display, g_object_unref);
+
+    }
+
+    g_signal_emit_by_name(display, "caret-moved", &display->caret_addr);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                                                                             *
+*  Description : Bascule et relance l'affichage du curseur.                   *
+*                                                                             *
+*  Retour      : TRUE pour poursuivre les basculements automatiques.          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_buffer_display_refresh_caret(GtkBufferDisplay *display)
+{
+    GtkWidget *widget;                      /* Autre version du composant  */
+    GdkWindow *window;                      /* Fenêtre de support associée */
+    GdkRectangle area;                      /* Région adaptée à traiter    */
+    cairo_t *cr;                            /* Contexte graphique          */
+    GdkRGBA *color;                         /* Couleur du curseur          */
+
+    widget = GTK_WIDGET(display);
+    window = gtk_widget_get_window(widget);
+
+    /**
+     * Si le composant n'est pas encore réalisé (ou caché, en cas de
+     * basculement entre les types de vues), gdk_cairo_create() ne va
+     * pas apprécier l'argument NULL. Donc on écourte l'opération.
+     */
+    if (window == NULL)
+    {
+        display->show_caret = !display->show_caret;
+        return TRUE;
+    }
+
+    area = display->caret;
+    gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(display), &area.x, &area.y);
+
+    /* Réinitialisation de la surface */
+    if (display->show_caret)
+    {
+        display->show_caret = false;
+        gtk_widget_queue_draw_area(widget, area.x, area.y, area.width, area.height);
+    }
+
+    /* Dessin */
+    else
+    {
+        display->show_caret = true;
+
+        cr = gdk_cairo_create(gtk_widget_get_window(widget));
+
+        gtk_style_context_get(gtk_widget_get_style_context(widget),
+                              gtk_widget_get_state_flags(widget),
+                              GTK_STYLE_PROPERTY_COLOR, &color, NULL);
+
+        cairo_set_source_rgb(cr, color->red, color->green, color->blue);
+
+        cairo_rectangle(cr, area.x, area.y, area.width, area.height);
+        cairo_fill(cr);
+
+        cairo_destroy(cr);
+
+    }
+
+    return TRUE;
+
+}
diff --git a/src/gtkext/gtkbufferdisplay.h b/src/gtkext/gtkbufferdisplay.h
new file mode 100644
index 0000000..ea06b94
--- /dev/null
+++ b/src/gtkext/gtkbufferdisplay.h
@@ -0,0 +1,70 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkbufferdisplay.h - prototypes pour l'affichage de tampons de lignes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GTKEXT_GTKBUFFER_DISPLAY_H
+#define _GTKEXT_GTKBUFFER_DISPLAY_H
+
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+
+#include "../glibext/gbufferview.h"
+
+
+
+#define GTK_TYPE_BUFFER_DISPLAY             (gtk_buffer_display_get_type())
+#define GTK_BUFFER_DISPLAY(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplay))
+#define GTK_BUFFER_DISPLAY_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplayClass))
+#define GTK_IS_BUFFER_DISPLAY(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUFFER_DISPLAY))
+#define GTK_IS_BUFFER_DISPLAY_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUFFER_DISPLAY))
+#define GTK_BUFFER_DISPLAY_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferDisplayClass))
+
+
+/* Composant d'affichage de tampon de lignes (instance) */
+typedef struct _GtkBufferDisplay GtkBufferDisplay;
+
+/* Composant d'affichage de tampon de lignes (classe) */
+typedef struct _GtkBufferDisplayClass GtkBufferDisplayClass;
+
+
+/* Détermine le type du composant d'affichage de tampon de lignes. */
+GType gtk_buffer_display_get_type(void);
+
+/* Lie une vue au composant d'affichage de tampon. */
+void gtk_buffer_display_set_view(GtkBufferDisplay *, GBufferView *);
+
+/* Fournit la vue associée au tampon de lignes courant. */
+GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *);
+
+
+
+/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */
+
+
+/* Déplace le curseur à un emplacement en extrémité. */
+bool gtk_buffer_display_move_caret_to(GtkBufferDisplay *, bool, gint *);
+
+
+
+#endif  /* _GTKEXT_GTKBUFFER_DISPLAY_H */
diff --git a/src/gtkext/gtkbufferview-int.h b/src/gtkext/gtkbufferview-int.h
deleted file mode 100644
index a7da69d..0000000
--- a/src/gtkext/gtkbufferview-int.h
+++ /dev/null
@@ -1,73 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkbufferview.h - prototypes pour l'affichage de tampons de lignes
- *
- * Copyright (C) 2010-2013 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 _GTK_BUFFERVIEW_INT_H
-#define _GTK_BUFFERVIEW_INT_H
-
-
-#include "gtkbufferview.h"
-
-
-#include "gtkdisplaypanel-int.h"
-
-
-
-/* Réagit à un déplacement de curseur. */
-typedef bool (* notify_caret_relocation_fc) (GtkBufferView *, const GdkRectangle *, const vmpa2t *);
-
-
-/* Composant d'affichage de tampon de lignes (instance) */
-struct _GtkBufferView
-{
-    GtkDisplayPanel parent;                 /* A laisser en premier        */
-
-    //GCodeBuffer *buffer;                    /* Code sous forme de texte    */
-    GBufferView *buffer_view;               /* Affichage de cette forme    */
-
-    gint line_height;                       /* Hauteur maximale des lignes */
-    gint left_margin;                       /* Marge gauche + espace       */
-    gint left_text;                         /* Début d'impression du code  */
-
-    GdkRectangle caret;                     /* Emplacement du curseur      */
-    const vmpa2t *caret_addr;               /* Position mémoire du curseur */   /* FIXME : REMME */
-    guint caret_timer;                      /* Identifiant du chronomètre  */
-    bool show_caret;                        /* Bascule entre les affichages*/
-
-};
-
-/* Composant d'affichage de tampon de lignes (classe) */
-struct _GtkBufferViewClass
-{
-    GtkDisplayPanelClass parent;            /* A laisser en premier        */
-
-    notify_caret_relocation_fc notify_caret;/* Accompagne un déplacement   */
-
-    /* Signaux */
-
-    void (* reach_limit) (GtkBufferView *, GdkScrollDirection);
-
-};
-
-
-
-#endif  /* _GTK_BUFFERVIEW_INT_H */
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
deleted file mode 100644
index bafb15d..0000000
--- a/src/gtkext/gtkbufferview.c
+++ /dev/null
@@ -1,1243 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkbufferview.c - affichage de tampons de lignes
- *
- * Copyright (C) 2010-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 "gtkbufferview-int.h"
-
-
-#include <gdk/gdkkeysyms.h>
-
-
-#include "../arch/target.h"
-#include "../common/extstr.h"
-#include "../core/params.h"
-#include "../glibext/chrysamarshal.h"
-
-
-
-/* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */
-
-
-/* Procède à l'initialisation de l'afficheur de tampons. */
-static void gtk_buffer_view_class_init(GtkBufferViewClass *);
-
-/* Procède à l'initialisation de l'afficheur de tampons. */
-static void gtk_buffer_view_init(GtkBufferView *);
-
-/* Supprime toutes les références externes. */
-static void gtk_buffer_view_dispose(GtkBufferView *);
-
-/* Procède à la libération totale de la mémoire. */
-static void gtk_buffer_view_finalize(GtkBufferView *);
-
-/* Intègre le focus dans le rendu du composant. */
-static gboolean gtk_buffer_view_focus(GtkWidget *, GdkEventFocus *);
-
-/* Assure la gestion des clics de souris sur le composant. */
-static gboolean gtk_buffer_view_button_press(GtkWidget *, GdkEventButton *);
-
-/* Met à jour l'affichage de la visualisation de code buffer. */
-static gboolean gtk_buffer_view_draw(GtkWidget *, cairo_t *);
-
-/* Prend en compte une frappe de touche sur le composant. */
-static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *);
-
-/* Prépare l'affichage d'une astuce. */
-static gboolean gtk_buffer_view_query_tooltip(GtkWidget *, gint, gint, gboolean, GtkTooltip *);
-
-/* Indique les dimensions de travail du composant d'affichage. */
-static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint *);
-
-/* Détermine la taille des bonds lors de défilements. */
-static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *, gint, GtkOrientation, gdouble *, gdouble *);
-
-/* Réagit à un défilement chez une barre associée au composant. */
-static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *, GtkAdjustment *, GtkOrientation);
-
-/* Indique la position courante du curseur. */
-static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *);
-
-/* Indique la position d'affichage d'une adresse donnée. */
-static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
-
-/* Fournit des éléments liés à la position courante dans la vue. */
-static bool gtk_buffer_view_get_position(const GtkBufferView *, GBufferLine **, GObject **);
-
-/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
-static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAllocation *, double);
-
-
-
-/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */
-
-
-/* Déplace le curseur à un emplacement défini. */
-static bool _gtk_buffer_view_move_caret_to(GtkBufferView *, gint, gint);
-
-/* Déplace le curseur en effaçant son éventuelle position. */
-static void gtk_buffer_view_relocate_caret(GtkBufferView *, const GdkRectangle *, const vmpa2t *);
-
-/* Redémarre l'affichage du curseur à l'emplacement courant. */
-static void restart_caret_blinking(GtkBufferView *);
-
-/* Bascule et relance l'affichage du curseur. */
-static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            INTERACTION DIRECTE AVEC GTK                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Détermine le type du composant d'affichage de tampon de lignes. */
-G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_DISPLAY_PANEL)
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : class = classe GTK à initialiser.                            *
-*                                                                             *
-*  Description : Procède à l'initialisation de l'afficheur de tampons.        *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_class_init(GtkBufferViewClass *class)
-{
-    GObjectClass *object;                   /* Autre version de la classe  */
-    GtkWidgetClass *widget_class;           /* Classe version Widget       */
-    GtkDisplayPanelClass *panel_class;      /* Classe parente              */
-
-    object = G_OBJECT_CLASS(class);
-    widget_class = GTK_WIDGET_CLASS(class);
-    panel_class = GTK_DISPLAY_PANEL_CLASS(class);
-
-    object->dispose = (GObjectFinalizeFunc/* ! */)gtk_buffer_view_dispose;
-    object->finalize = (GObjectFinalizeFunc)gtk_buffer_view_finalize;
-
-    widget_class->focus_in_event = gtk_buffer_view_focus;
-    widget_class->focus_out_event = gtk_buffer_view_focus;
-    widget_class->button_press_event = gtk_buffer_view_button_press;
-    widget_class->draw = gtk_buffer_view_draw;
-    widget_class->key_press_event = gtk_buffer_view_key_press;
-    widget_class->query_tooltip = gtk_buffer_view_query_tooltip;
-
-    panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_view_compute_requested_size;
-    panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_view_compute_scroll_inc;
-    panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_view_adjust_scroll_value;
-
-    panel_class->get_caret_loc = (get_caret_location_fc)gtk_buffer_view_get_caret_location;
-    panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_view_get_address_coordinates;
-    panel_class->get_position = (get_view_position_fc)gtk_buffer_view_get_position;
-    panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_view_move_caret_to;
-    panel_class->cache_glance = (cache_glance_fc)gtk_buffer_view_cache_glance;
-
-    g_signal_new("reach-limit",
-                 GTK_TYPE_BUFFER_VIEW,
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GtkBufferViewClass, reach_limit),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__ENUM,
-                 G_TYPE_NONE, 1, GTK_TYPE_SCROLL_TYPE);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à initialiser.                          *
-*                                                                             *
-*  Description : Procède à l'initialisation de l'afficheur de tampons.        *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_init(GtkBufferView *view)
-{
-    GObject *object;                        /* Autre version de l'instance */
-
-    object = G_OBJECT(view);
-
-    g_object_set(object, "has-tooltip", TRUE, NULL);
-
-    view->caret.x = 10;
-    view->caret.y = 10;
-    view->caret.width = 100;
-    view->caret.height = 100;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = instance d'objet GLib à traiter.                      *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_dispose(GtkBufferView *view)
-{
-    G_OBJECT_CLASS(gtk_buffer_view_parent_class)->dispose(G_OBJECT(view));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = instance d'objet GLib à traiter.                      *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_finalize(GtkBufferView *view)
-{
-    G_OBJECT_CLASS(gtk_buffer_view_parent_class)->finalize(G_OBJECT(view));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant GTK visé par l'opération.                 *
-*                event  = informations liées à l'événement.                   *
-*                                                                             *
-*  Description : Intègre le focus dans le rendu du composant.                 *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_buffer_view_focus(GtkWidget *widget, GdkEventFocus *event)
-{
-    GtkBufferView *view;                    /* Autre version du composant  */
-    gboolean has_focus;                     /* Etat courant                */
-
-    view = GTK_BUFFER_VIEW(widget);
-    has_focus = event->in;
-
-    if (has_focus)
-        restart_caret_blinking(view);
-
-    else if (view->caret_timer != 0)
-    {
-        g_source_remove(view->caret_timer);
-        view->caret_timer = 0;
-
-        view->show_caret = true;
-        gtk_buffer_view_refresh_caret(view);
-
-    }
-
-    return TRUE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant GTK visé par l'opération.                 *
-*                event  = informations liées à l'événement.                   *
-*                                                                             *
-*  Description : Assure la gestion des clics de souris sur le composant.      *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *event)
-{
-    GtkBufferView *view;                    /* Autre version du composant  */
-    gint real_x;                            /* Abscisse absolue réelle     */
-    gint real_y;                            /* Ordonnée absolue réelle     */
-    GBufferLine *line;                      /* Ligne à la position courante*/
-
-    view = GTK_BUFFER_VIEW(widget);
-
-    real_x = event->x;
-    real_y = event->y;
-    gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(view), &real_x, &real_y);
-
-    printf(" !mouse! :: (%g ; %g) -> (%d ; %d)\n",
-           event->x, event->y,
-           real_x, real_y);
-
-
-    if (real_x < view->left_margin)
-    {
-        line = g_buffer_view_find_line_at(view->buffer_view, real_y, NULL);
-        if (line == NULL) return FALSE;
-
-        /* TODO */
-        printf("Border Line :: %p\n", line);
-
-    }
-    else
-        _gtk_buffer_view_move_caret_to(view, real_x, real_y);
-
-    gtk_widget_grab_focus(widget);
-
-    return FALSE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant GTK à redessiner.                         *
-*                cr     = contexte graphique associé à l'événement.           *
-*                                                                             *
-*  Description : Met à jour l'affichage de la visualisation de code buffer.   *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
-{
-    GtkBufferView *view;                    /* Autre version du composant  */
-    GtkDisplayPanel *panel;                 /* Autre version du composant  */
-    GdkWindow *window;                      /* Fenêtre à redessiner        */
-    cairo_region_t *region;                 /* Région visible à redessiner */
-    cairo_rectangle_int_t area;             /* Surface correspondante      */
-    GtkStyleContext *context;               /* Contexte du thème actuel    */
-    GdkRGBA color;                          /* Couleur de thème récupérée  */
-    gint fake_x;                            /* Abscisse virtuelle          */
-    gint fake_y;                            /* Ordonnée virtuelle          */
-    bool sel_line;                          /* Souslignage de la sélection */
-    gint *selected;                         /* Ordonnée d'une sélection    */
-
-    view = GTK_BUFFER_VIEW(widget);
-    panel = GTK_DISPLAY_PANEL(widget);
-
-    window = gtk_widget_get_window(widget);
-
-    cairo_save(cr);
-    gtk_cairo_transform_to_window(cr, widget, window);
-
-    region = gdk_window_get_clip_region(window);
-    cairo_region_get_extents(region, &area);
-    cairo_region_destroy(region);
-
-    context = gtk_widget_get_style_context(widget);
-
-    if (panel->show_border)
-    {
-        gtk_display_panel_define_border_path(panel, cr, 0, 0);
-        cairo_clip(cr);
-    }
-
-    /* Dessin de la marge gauche */
-
-    gtk_style_context_save(context);
-
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_TOOLBAR);
-
-    gtk_style_context_get_background_color(context, GTK_STATE_FLAG_ACTIVE, &color);
-
-    cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
-
-    cairo_rectangle(cr, 0, area.y, view->left_margin, area.height);
-    cairo_fill(cr);
-
-    gtk_style_context_restore(context);
-
-    /* Fond de la zone de texte */
-
-    gtk_style_context_save(context);
-
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_VIEW);
-
-    gtk_style_context_get_background_color(context, GTK_STATE_FLAG_ACTIVE, &color);
-
-    cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha * 0.7);
-
-    cairo_rectangle(cr, view->left_margin, area.y, area.width, area.height);
-    cairo_fill(cr);
-
-    gtk_style_context_restore(context);
-
-    /* Ligne de séparation */
-
-    gtk_style_context_save(context);
-
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME);
-
-    gtk_style_context_get_border_color(context, GTK_STATE_FLAG_ACTIVE, &color);
-
-    cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
-
-    cairo_set_line_width(cr, 1.0);
-
-    cairo_move_to(cr, view->left_margin + 0.5, area.y - 0.5);
-    cairo_line_to(cr, view->left_margin + 0.5, area.y + area.height + 0.5);
-    cairo_stroke(cr);
-
-    gtk_style_context_restore(context);
-
-    /* Eventuelle bordure globale */
-
-    if (panel->show_border)
-        gtk_display_panel_draw_border(panel, cr);
-
-    /* Impression du désassemblage */
-
-    if (view->buffer_view != NULL)
-    {
-        fake_x = 0;
-        fake_y = 0;
-        gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(view), &fake_x, &fake_y);
-
-        g_generic_config_get_value(get_main_configuration(), MPK_SELECTION_LINE, &sel_line);
-        sel_line &= gtk_widget_has_focus(widget);
-
-        if (!sel_line || view->caret_addr == NULL)
-            selected = NULL;
-        else
-            selected = &view->caret.y;
-
-        g_buffer_view_draw(view->buffer_view, cr, fake_x, fake_y, &area, panel->display, selected);
-
-    }
-
-    /* Curseur clignotant ? */
-
-    if (gtk_widget_is_focus(widget))
-    {
-        view->show_caret = !view->show_caret;
-        gtk_buffer_view_refresh_caret(view);
-    }
-
-    cairo_restore(cr);
-
-    return TRUE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant visé par l'opération.                     *
-*                event  = informations liées à l'événement.                   *
-*                                                                             *
-*  Description : Prend en compte une frappe de touche sur le composant.       *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
-{
-    gboolean result;                        /* Suites à renvoyer           */
-    GtkBufferView *view;                    /* Autre version du composant  */
-    GtkDisplayPanel *panel;                 /* Autre version du composant  */
-    bool ctrl;                              /* Statut de la touche Contrôle*/
-    GdkScrollDirection dir;                 /* Direction du déplacement    */
-    GdkRectangle area;                      /* Emplacement de curseur      */
-    const vmpa2t *addr;                     /* Adresse du nouveau curseur  */
-
-    result = FALSE;
-
-    view = GTK_BUFFER_VIEW(widget);
-    panel = GTK_DISPLAY_PANEL(widget);
-
-    switch (event->keyval)
-    {
-        case GDK_KEY_Left:
-            dir = GDK_SCROLL_LEFT;
-            result = TRUE;
-            break;
-
-        case GDK_KEY_Up:
-            dir = GDK_SCROLL_UP;
-            result = TRUE;
-            break;
-
-        case GDK_KEY_Right:
-            dir = GDK_SCROLL_RIGHT;
-            result = TRUE;
-            break;
-
-        case GDK_KEY_Down:
-            dir = GDK_SCROLL_DOWN;
-            result = TRUE;
-            break;
-
-        default:
-            break;
-
-    }
-
-    if (result)
-    {
-        area = view->caret;
-        ctrl = (event->state & GDK_CONTROL_MASK);
-
-        addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, dir, panel->display);
-
-        if (addr != NULL)
-        {
-            gtk_buffer_view_relocate_caret(view, &area, addr);
-            _gtk_display_panel_scroll_to_address(panel, addr, SPT_RAW, false);
-        }
-        else
-            g_signal_emit_by_name(view, "reach-limit", dir);
-
-
-
-        //if (addr == NULL) return FALSE;
-
-
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget   = composant GTK visé par l'opération.               *
-*                x        = abscisse de la position du message.               *
-*                y        = ordonnée de la position du message.               *
-*                keyboard = indique une demande suite à obtiention du focus.  *
-*                tooltip  = astuce à compléter. [OUT]                         *
-*                                                                             *
-*  Description : Prépare l'affichage d'une astuce.                            *
-*                                                                             *
-*  Retour      : TRUE pour un affichage validé, FALSE sinon.                  *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip *tooltip)
-{
-    gboolean result;                        /* Bilan à retourner           */
-    GBinFormat *format;                     /* Format du fichier binaire   */
-    GtkBufferView *view;                    /* Autre version du composant  */
-    gint real_x;                            /* Abscisse absolue réelle     */
-    gint real_y;                            /* Ordonnée absolue réelle     */
-    GBufferLine *line;                      /* Ligne en cours de survol    */
-    GObject *creator;                       /* Créateur à l'orgine du seg. */
-    virt_t virt;                            /* Adresse virtuelle           */
-    vmpa2t addr;                            /* Adresse de destination      */
-    GBinSymbol *target_sym;                 /* Symbole présent à l'adresse */
-    GBinSymbol *next_sym;                   /* Symbole suivant l'adresse   */
-    GCodeBuffer *buffer;                    /* Tampon où lire les lignes   */
-    const vmpa2t *stop_addr;                /* Adresse associée, pour fin  */
-    const mrange_t *lrange;                 /* Couverture d'une ligne      */
-    size_t count;                           /* Nbre de lignes max à traiter*/
-    char *markup;                           /* Description à construire    */
-    size_t i;                               /* Boucle de parcours          */
-    size_t index;                           /* Indice d'une ligne imprimée */
-    char *text;                             /* Contenu à ajouter           */
-
-    if (keyboard) return FALSE;
-
-    result = FALSE;
-
-    format = NULL;
-
-    view = GTK_BUFFER_VIEW(widget);
-
-    /* Récupération de la destination pointée */
-
-    real_x = x;
-    real_y = y;
-    gtk_display_panel_compute_real_coord(GTK_DISPLAY_PANEL(view), &real_x, &real_y);
-
-    line = g_buffer_view_find_line_and_creator_at(view->buffer_view,
-                                                  &real_x, real_y, NULL,
-                                                  GTK_DISPLAY_PANEL(view)->display, &creator);
-
-    if (line == NULL || creator == NULL) goto no_tooltip;
-
-    /**
-     * On fait le pari de reposer uniquement sur des adresses virtuelles !
-     * A changer dans un futur ?
-     */
-
-    virt = VMPA_NO_VIRTUAL;
-
-    if (G_IS_TARGET_OPERAND(creator))
-        virt = g_target_operand_get_addr(G_TARGET_OPERAND(creator));
-
-    else if (G_IS_IMM_OPERAND(creator))
-    {
-        if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(creator), &virt))
-            virt = VMPA_NO_VIRTUAL;
-    }
-
-    if (virt == VMPA_NO_VIRTUAL) goto no_tooltip;
-
-    init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
-
-    /* Construction du contenu textuel */
-
-    format = G_BIN_FORMAT(g_loaded_binary_get_format(GTK_DISPLAY_PANEL(view)->binary));
-
-    if (!g_binary_format_find_symbol_at(format, &addr, &target_sym))
-        goto no_tooltip;
-
-    g_object_unref(G_OBJECT(target_sym));
-
-    /* Construction du contenu textuel */
-
-    /**
-     * Dans le cas des vues de blocs basiques, il est impératif
-     * de chercher les lignes dans le tampon global, et non uniquement dans
-     * celui propre au bloc basique courant.
-     */
-
-    buffer = g_loaded_binary_get_disassembled_buffer(GTK_DISPLAY_PANEL(view)->binary);
-
-    if (g_binary_format_find_next_symbol_at(format, &addr, &next_sym))
-        stop_addr = get_mrange_addr(g_binary_symbol_get_range(next_sym));
-    else
-        stop_addr = NULL;   /* Pour GCC */
-
-    g_generic_config_get_value(get_main_configuration(), MPK_TOOLTIP_SIZE, &count);
-
-    markup = NULL;
-
-    for (i = 0, line = g_code_buffer_find_line_by_addr(buffer, &addr, BLF_NONE, &index);
-         i < count && line != NULL;
-         i++, line = g_code_buffer_find_line_by_index(buffer, index + i))
-    {
-        /* Si on commence à marcher sur les plates-bandes du symbole suivant... */
-        if (next_sym != NULL)
-        {
-            lrange = g_buffer_line_get_range(line);
-
-            if (mrange_contains_addr(lrange, stop_addr))
-                break;
-
-        }
-
-        text = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true);
-
-        if (markup != NULL)
-            markup = stradd(markup, "\n");
-
-        if (text != NULL)
-            markup = stradd(markup, text);
-
-        free(text);
-
-    }
-
-    if (next_sym != NULL)
-        g_object_unref(G_OBJECT(next_sym));
-
-    if (markup == NULL) goto no_tooltip;
-
-    /* Impression finale */
-
-    result = TRUE;
-
-    gtk_tooltip_set_markup(tooltip, markup);
-    free(markup);
-
- no_tooltip:
-
-    if (creator != NULL)
-        g_object_unref(creator);
-
-    /*
-      FIXME : ref() !
-    if (line != NULL)
-        g_object_unref(G_OBJECT(line));
-    */
-
-    if (format != NULL)
-        g_object_unref(G_OBJECT(format));
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view   = composant GTK à consulter.                          *
-*                width  = largeur requise à renseigner ou NULL. [OUT]         *
-*                height = hauteur requise à renseigner ou NULL. [OUT]         *
-*                                                                             *
-*  Description : Indique les dimensions de travail du composant d'affichage.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *width, gint *height)
-{
-    if (width != NULL)
-    {
-        if (view->buffer_view != NULL)
-            *width = g_buffer_view_get_width(view->buffer_view, GTK_DISPLAY_PANEL(view)->display);
-        else
-            *width = 0;
-    }
-
-    if (height != NULL)
-    {
-        if (view->buffer_view != NULL)
-            *height = g_buffer_view_get_height(view->buffer_view);
-        else
-            *height = 0;
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     *
-*                size        = taille de l'espace dans la direction donnée.   *
-*                orientation = indication sur le défilement à traiter.        *
-*                step        = valeur d'un petit pas de défilement. [OUT]     *
-*                page        = valeur d'un grand pas de défilement. [OUT]     *
-*                                                                             *
-*  Description : Détermine la taille des bonds lors de défilements.           *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, GtkOrientation orientation, gdouble *step, gdouble *page)
-{
-    if (orientation == GTK_ORIENTATION_VERTICAL)
-    {
-        *step = 17; // FIXME g_buffer_view_get_line_height(view->buffer_view);
-        *page = *step * 10;
-    }
-
-    else
-        GTK_DISPLAY_PANEL_CLASS(gtk_buffer_view_parent_class)->compute_inc(GTK_DISPLAY_PANEL(view),
-                                                                        size, orientation, step, page);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view        = panneau d'affichage concerné.                  *
-*                adj         = défilement dont une valeur a changé.           *
-*                orientation = indication sur le défilement à traiter.        *
-*                                                                             *
-*  Description : Réagit à un défilement chez une barre associée au composant. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *view, GtkAdjustment *adj, GtkOrientation orientation)
-{
-    GtkWidget *widget;                      /* Autre vision du composant   */
-
-    widget = GTK_WIDGET(view);
-
-    if (gtk_widget_get_realized(widget))
-        gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, false);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à manipuler.                            *
-*                                                                             *
-*  Description : Indique la position courante du curseur.                     *
-*                                                                             *
-*  Retour      : Emplacement courant du curseur ou NULL si aucun.             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *view)
-{
-    return view->caret_addr;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = composant GTK à consulter.                           *
-*                addr  = adresse à présenter à l'écran.                       *
-*                x     = position horizontale au sein du composant. [OUT]     *
-*                y     = position verticale au sein du composant. [OUT]       *
-*                tweak = adaptation finale à effectuer.                       *
-*                                                                             *
-*  Description : Indique la position d'affichage d'une adresse donnée.        *
-*                                                                             *
-*  Retour      : true si l'adresse fait partie du composant, false sinon.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
-{
-    bool result;                            /* Bilan à remonter            */
-    bool need_code;                         /* Recherche plus raffinée     */
-    int height;                             /* Hauteur allouée             */
-
-    need_code = (tweak == SPT_BOTTOM);
-
-    result = g_buffer_view_get_address_coordinates(view->buffer_view, addr, x, y, need_code);
-
-    if (result)
-    {
-        *x += g_buffer_view_get_margin(view->buffer_view, GTK_DISPLAY_PANEL(view)->display);
-
-        height = gtk_widget_get_allocated_height(GTK_WIDGET(view));
-
-        switch (tweak)
-        {
-            case SPT_RAW:
-                break;
-
-            case SPT_TOP:
-                break;
-
-            case SPT_CENTER:
-                *y -= (height / 2);
-                break;
-
-            case SPT_BOTTOM:
-                *y -= height;
-                *y += g_buffer_view_get_line_height(view->buffer_view);
-                break;
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view    = composant GTK à consulter.                         *
-*                line    = ligne de tampon où se trouve le curseur. [OUT]     *
-*                creator = instance à l'origine de la représentation. [OUT]   *
-*                                                                             *
-*  Description : Fournit des éléments liés à la position courante dans la vue.*
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool gtk_buffer_view_get_position(const GtkBufferView *view, GBufferLine **line, GObject **creator)
-{
-    GObject *obj;                           /* Elément à récupérer         */
-
-    /* Si aucune position n'est définie... */
-    if (view->caret_addr == NULL)
-        return false;
-
-    *line = g_buffer_view_find_line_and_creator_at(view->buffer_view,
-                                                   (gint []){ view->caret.x }, view->caret.y, NULL,
-                                                   GTK_DISPLAY_PANEL(view)->display, &obj);
-
-    if (creator != NULL)
-        *creator = obj;
-
-    return (line != NULL);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = composant GTK à manipuler.                           *
-*                cairo = assistant pour la création de rendus.                *
-*                area  = taille de la surface réduite à disposition.          *
-*                scale = échelle vis à vis de la taille réelle.               *
-*                                                                             *
-*  Description : Place en cache un rendu destiné à l'aperçu graphique rapide. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, const GtkAllocation *area, double scale)
-{
-    cairo_set_line_width(cairo, 1);
-    cairo_set_source_rgb(cairo, 0.4, 0.4, 0.4);
-
-    cairo_rectangle(cairo, area->x + 0.5, area->y + 0.5, area->width - 1, area->height - 1);
-
-    cairo_stroke(cairo);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view   = composant GTK à mettre à jour.                      *
-*                buffer = tampon de lignes à encadrer.                        *
-*                                                                             *
-*  Description : Prend acte de l'association d'un tampon de lignes.           *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer)
-{
-    gint width;                             /* Largeur de l'objet actuelle */
-    gint height;                            /* Hauteur de l'objet actuelle */
-
-    if (view->buffer_view != NULL)
-    {
-        //g_object_unref(G_OBJECT(view->buffer));
-        g_object_unref(G_OBJECT(view->buffer_view));
-    }
-
-    //view->buffer = g_buffer_view_get_buffer(buffer);
-    //g_object_ref(G_OBJECT(view->buffer));
-
-    view->buffer_view = buffer;
-
-    /* Taille des marges */
-
-    view->line_height = g_buffer_view_get_line_height(view->buffer_view);
-    view->left_margin = 2 * view->line_height;
-    view->left_text = -2.5 * view->line_height;
-
-    /* Validation finale */
-
-    width = g_buffer_view_get_width(view->buffer_view, GTK_DISPLAY_PANEL(view)->display);
-    height = g_buffer_view_get_height(view->buffer_view);
-
-    width += -view->left_text + 1;
-    height += 1;
-
-    //gtk_widget_set_size_request(GTK_WIDGET(view), width, height);
-
-    gtk_widget_queue_draw(GTK_WIDGET(view));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view   = composant GTK à consulter.                          *
-*                                                                             *
-*  Description : Fournit la vue associée au tampon de lignes courant.         *
-*                                                                             *
-*  Retour      : Vue mise en place.                                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view)
-{
-    /* TODO : ref... */
-
-    return view->buffer_view;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                                ANIMATION DU CURSEUR                                */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à manipuler.                            *
-*                x    = abscisse proposée pour le nouvel emplacement.         *
-*                y    = ordonnée proposée pour le nouvel emplacement.         *
-*                                                                             *
-*  Description : Déplace le curseur à un emplacement défini.                  *
-*                                                                             *
-*  Retour      : true si un traitement a été effectué, false sinon.           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool _gtk_buffer_view_move_caret_to(GtkBufferView *view, gint x, gint y)
-{
-    size_t index;                           /* Indice de ligne de tampon   */
-    GBufferLine *line;                      /* Ligne à la position courante*/
-    GtkDisplayPanel *panel;                 /* Autre version du composant  */
-    const vmpa2t *addr;                     /* Position mémoire associée   */
-    GdkRectangle new;                       /* Nouvel emplacement calculé  */
-
-    if (x < view->left_margin) return false;
-
-    line = g_buffer_view_find_line_at(view->buffer_view, y, &index);
-    if (line == NULL) return false;
-
-    panel = GTK_DISPLAY_PANEL(view);
-
-    addr = g_buffer_view_compute_caret_full(view->buffer_view, line, index, x, panel->display, &new);
-
-    if (addr != NULL)
-        gtk_buffer_view_relocate_caret(view, &new, addr);
-
-    return (addr != NULL);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view      = composant GTK à manipuler.                       *
-*                beginning = précise le coin où se retrouvera le curseur.     *
-*                same_x    = tente de conserver une même abscisse ou NULL ?   *
-*                                                                             *
-*  Description : Déplace le curseur à un emplacement en extrémité.            *
-*                                                                             *
-*  Retour      : true si un traitement a été effectué, false sinon.           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool gtk_buffer_view_move_caret_to(GtkBufferView *view, bool beginning, gint *same_x)
-{
-    bool result;                            /* Bilan à remonter            */
-    gint x;                                 /* Abscisse d'emplacement      */
-    gint y;                                 /* Ordonnée d'emplacement      */
-
-    if (beginning)
-    {
-        x = same_x != NULL ? *same_x : view->left_margin * 2;
-        y = 0;
-    }
-    else
-    {
-        if (same_x != NULL) x = *same_x;
-        gtk_buffer_view_compute_requested_size(view, same_x != NULL ? NULL : &x, &y);
-        y--;
-    }
-
-    result = _gtk_buffer_view_move_caret_to(view, x, y);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à manipuler.                            *
-*                area = emplacement pour le dessin d'un curseur.              *
-*                addr = position dans la mémoire représentée du curseur.      *
-*                                                                             *
-*  Description : Déplace le curseur en effaçant son éventuelle position.      *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_buffer_view_relocate_caret(GtkBufferView *view, const GdkRectangle *area, const vmpa2t *addr)
-{
-    bool clear_old;                         /* Effacement chirurgical      */
-    GdkRectangle old_area;                  /* Mémorisation de l'ancien    */
-    bool need_redraw;                       /* Besoin de rafraîchissement ?*/
-
-    if (view->caret_addr != NULL)
-    {
-        clear_old = true;
-        old_area = view->caret;
-    }
-    else
-        clear_old = false;
-
-    view->caret = *area;
-    view->caret_addr = addr;
-
-    if (GTK_BUFFER_VIEW_GET_CLASS(view)->notify_caret != NULL)
-        need_redraw = GTK_BUFFER_VIEW_GET_CLASS(view)->notify_caret(view, area, addr);
-    else
-        need_redraw = false;
-
-    if (need_redraw)
-        gtk_widget_queue_draw(GTK_WIDGET(view));
-
-    else if (clear_old)
-    {
-        gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(view), &old_area.x, &old_area.y);
-
-        gtk_widget_queue_draw_area(GTK_WIDGET(view), old_area.x, old_area.y,
-                                   old_area.width, old_area.height);
-
-    }
-
-    restart_caret_blinking(view);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à manipuler.                            *
-*                                                                             *
-*  Description : Redémarre l'affichage du curseur à l'emplacement courant.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void restart_caret_blinking(GtkBufferView *view)
-{
-    if (view->caret_timer != 0)
-    {
-        g_source_remove(view->caret_timer);
-        view->caret_timer = 0;
-    }
-
-    if (view->caret_addr != NULL)
-    {
-        view->show_caret = false;
-        gtk_buffer_view_refresh_caret(view);
-
-        view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view);
-
-    }
-
-    g_signal_emit_by_name(view, "caret-moved", view->caret_addr);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à manipuler.                            *
-*                                                                             *
-*  Description : Bascule et relance l'affichage du curseur.                   *
-*                                                                             *
-*  Retour      : TRUE pour poursuivre les basculements automatiques.          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view)
-{
-    GtkWidget *widget;                      /* Autre version du composant  */
-    GdkWindow *window;                      /* Fenêtre de support associée */
-    GdkRectangle area;                      /* Région adaptée à traiter    */
-    cairo_t *cr;                            /* Contexte graphique          */
-    GdkRGBA *color;                         /* Couleur du curseur          */
-
-    widget = GTK_WIDGET(view);
-    window = gtk_widget_get_window(widget);
-
-    /**
-     * Si le composant n'est pas encore réalisé (ou caché, en cas de
-     * basculement entre les types de vues), gdk_cairo_create() ne va
-     * pas apprécier l'argument NULL. Donc on écourte l'opération.
-     */
-    if (window == NULL)
-    {
-        view->show_caret = !view->show_caret;
-        return TRUE;
-    }
-
-    area = view->caret;
-    gtk_display_panel_compute_relative_coords(GTK_DISPLAY_PANEL(view), &area.x, &area.y);
-
-    /* Réinitialisation de la surface */
-    if (view->show_caret)
-    {
-        view->show_caret = false;
-        gtk_widget_queue_draw_area(widget, area.x, area.y, area.width, area.height);
-    }
-
-    /* Dessin */
-    else
-    {
-        view->show_caret = true;
-
-        cr = gdk_cairo_create(gtk_widget_get_window(widget));
-
-        gtk_style_context_get(gtk_widget_get_style_context(widget),
-                              gtk_widget_get_state_flags(widget),
-                              GTK_STYLE_PROPERTY_COLOR, &color, NULL);
-
-        cairo_set_source_rgb(cr, color->red, color->green, color->blue);
-
-        cairo_rectangle(cr, area.x, area.y, area.width, area.height);
-        cairo_fill(cr);
-
-        cairo_destroy(cr);
-
-    }
-
-    return TRUE;
-
-}
diff --git a/src/gtkext/gtkbufferview.h b/src/gtkext/gtkbufferview.h
deleted file mode 100644
index 1b13ab0..0000000
--- a/src/gtkext/gtkbufferview.h
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkbufferview.h - prototypes pour l'affichage de tampons de lignes
- *
- * Copyright (C) 2010-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 _GTK_BUFFERVIEW_H
-#define _GTK_BUFFERVIEW_H
-
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-
-#include "../glibext/gbufferview.h"
-
-
-
-#define GTK_TYPE_BUFFER_VIEW                  (gtk_buffer_view_get_type())
-#define GTK_BUFFER_VIEW(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferView))
-#define GTK_BUFFER_VIEW_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUFFER_VIEW, GtkBufferViewClass))
-#define GTK_IS_BUFFER_VIEW(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUFFER_VIEW))
-#define GTK_IS_BUFFER_VIEW_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUFFER_VIEW))
-#define GTK_BUFFER_VIEW_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferViewClass))
-
-
-/* Composant d'affichage de tampon de lignes (instance) */
-typedef struct _GtkBufferView GtkBufferView;
-
-/* Composant d'affichage de tampon de lignes (classe) */
-typedef struct _GtkBufferViewClass GtkBufferViewClass;
-
-
-/* Détermine le type du composant d'affichage de tampon de lignes. */
-GType gtk_buffer_view_get_type(void);
-
-/* Prend acte de l'association d'un tampon de lignes. */
-void gtk_buffer_view_attach_buffer(GtkBufferView *, GBufferView *);
-
-/* Fournit la vue associée au tampon de lignes courant. */
-GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *);
-
-
-
-/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */
-
-
-/* Déplace le curseur à un emplacement en extrémité. */
-bool gtk_buffer_view_move_caret_to(GtkBufferView *, bool, gint *);
-
-
-
-#endif  /* _GTK_BUFFERVIEW_H */
diff --git a/src/gtkext/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h
index bc0e229..f6221d5 100644
--- a/src/gtkext/gtkdisplaypanel-int.h
+++ b/src/gtkext/gtkdisplaypanel-int.h
@@ -48,9 +48,6 @@ typedef void (* adjust_scroll_value_fc) (GtkDisplayPanel *, GtkAdjustment *, Gtk
 /* Réagit à la sélection externe d'une adresse. */
 typedef void (* define_address_fc) (GtkDisplayPanel *, const vmpa2t *);
 
-/* Actualise les besoins internes avant un redimensionnement. */
-typedef void (* prepare_resize_fc) (GtkDisplayPanel *);
-
 /* Indique la position courante du curseur. */
 typedef const vmpa2t * (* get_caret_location_fc) (const GtkDisplayPanel *);
 
@@ -84,9 +81,6 @@ struct _GtkDisplayPanel
 
     GLoadedBinary *binary;                  /* Binaire à visualiser        */
 
-    //define_address_fc define;               /* Centrage sur une partie     */
-    prepare_resize_fc resize;               /* Prépare une nouvelle taille */
-
 };
 
 /* Composant d'affichage générique (classe) */
diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c
index 6793d4e..66ec909 100644
--- a/src/gtkext/gtkdisplaypanel.c
+++ b/src/gtkext/gtkdisplaypanel.c
@@ -641,7 +641,8 @@ static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *adj, GtkDi
 
     orientation = (adj == panel->hadjustment ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
 
-    GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation);
+    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust != NULL)
+        GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation);
 
 }
 
@@ -832,9 +833,6 @@ static void on_view_panel_binary_display_change(GLoadedBinary *binary, BinaryVie
 {
     if (panel->content == view)
     {
-        if (panel->resize != NULL)
-            panel->resize(panel);
-
         gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel)));
         gtk_widget_queue_resize(GTK_WIDGET(panel));
         gtk_widget_queue_draw(GTK_WIDGET(panel));
@@ -924,23 +922,15 @@ void _gtk_display_panel_scroll_to_address(GtkDisplayPanel *panel, const vmpa2t *
     double value;                           /* Valeur courante             */
 
     /**
-     * Si une vue partielle se déplacer via cette fonction, il faut potentiellement
+     * Si une vue partielle se déplace via cette fonction, il faut potentiellement
      * rediriger l'appel vers la vue en graphiques parente.
      */
 
     parent = gtk_widget_get_parent(GTK_WIDGET(panel));
     parent = gtk_widget_get_parent(GTK_WIDGET(parent));
 
-    printf(" Widgets : %s -> %s\n",
-           G_OBJECT_TYPE_NAME(parent), G_OBJECT_TYPE_NAME(panel));
-
     if (GTK_IS_DISPLAY_PANEL(parent))
-    {
-        printf("reparent !\n");
         panel = GTK_DISPLAY_PANEL(parent);
-    }
-    else
-        printf("no need reparent !\n");
 
     if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->define != NULL)
         GTK_DISPLAY_PANEL_GET_CLASS(panel)->define(panel, addr);
diff --git a/src/gtkext/gtkgraphdisplay.c b/src/gtkext/gtkgraphdisplay.c
new file mode 100644
index 0000000..1d4f831
--- /dev/null
+++ b/src/gtkext/gtkgraphdisplay.c
@@ -0,0 +1,1226 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkgraphdisplay.c - affichage de morceaux de code sous forme graphique
+ *
+ * Copyright (C) 2009-2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "gtkgraphdisplay.h"
+
+
+#include <assert.h>
+
+
+#include "gtkblockdisplay.h"
+#include "gtkbufferdisplay.h"
+#include "gtkdisplaypanel-int.h"
+#include "graph/cluster.h"
+#include "../analysis/blocks/flow.h"
+#include "../format/format.h"
+#include "../gui/editem.h"
+
+
+
+/* Composant d'affichage sous forme graphique (instance) */
+struct _GtkGraphDisplay
+{
+    GtkDisplayPanel parent;                 /* A laisser en premier        */
+    GtkWidget *support;                     /* Support des vues en bloc    */
+    GtkWidget *extender;                    /* Force la taille du support  */
+
+    GBinRoutine *routine;                   /* Routine en cours d'affichage*/
+
+    segcnt_list *highlighted;               /* Segments mis en évidence    */
+
+    GGraphCluster *cluster;                 /* Disposition en graphique    */
+
+    GGraphEdge **edges;                     /* Liens entre les noeuds      */
+    size_t edges_count;                     /* Quantité de ces liens       */
+
+    gdouble start_x;                        /* Abscisse du point de souris */
+    gdouble start_y;                        /* Ordonnée du point de souris */
+    bool big_enough;                        /* Capacités de déplacement ?  */
+    gdouble ref_h;                          /* Position horizontale de ref.*/
+    gdouble ref_v;                          /* Position verticale de ref.  */
+
+};
+
+/* Composant d'affichage sous forme graphique (classe) */
+struct _GtkGraphDisplayClass
+{
+    GtkDisplayPanelClass parent;            /* A laisser en premier        */
+
+};
+
+
+/* Profondeur de l'ombre */
+#define SHADOW_SIZE 4
+
+/* Marges en bordure de graphique */
+#define GRAPH_MARGIN 23
+
+
+/* Initialise la classe générique des graphiques de code. */
+static void gtk_graph_display_class_init(GtkGraphDisplayClass *);
+
+/* Initialise une instance d'afficheur de code en graphique. */
+static void gtk_graph_display_init(GtkGraphDisplay *);
+
+/* Supprime toutes les références externes. */
+static void gtk_graph_display_dispose(GtkGraphDisplay *);
+
+/* Procède à la libération totale de la mémoire. */
+static void gtk_graph_display_finalize(GtkGraphDisplay *);
+
+/* S'adapte à la surface concédée par le composant parent. */
+static void gtk_graph_display_size_allocate(GtkWidget *, GtkAllocation *);
+
+/* Centre si possible le contenu du panneau d'affichage. */
+static void gtk_graph_display_update_support_margins(GtkGraphDisplay *, const GtkAllocation *);
+
+/* Indique les dimensions de travail du composant d'affichage. */
+static void gtk_graph_display_compute_requested_size(GtkGraphDisplay *, gint *, gint *);
+
+/* Réagit à un défilement chez une barre associée au composant. */
+static void gtk_graph_display_adjust_scroll_value(GtkGraphDisplay *, GtkAdjustment *, GtkOrientation);
+
+/*  Met à jour l'affichage de la vue sous forme graphique. */
+static gboolean gtk_graph_display_draw(GtkWidget *, cairo_t *, GtkGraphDisplay *);
+
+/* Assure la gestion des clics de souris sur le composant. */
+static gboolean gtk_graph_display_button_press(GtkWidget *, GdkEventButton *, GtkGraphDisplay *);
+
+/* Assure la gestion des clics de souris sur le composant. */
+static gboolean gtk_graph_display_button_release(GtkWidget *, GdkEventButton *, GtkGraphDisplay *);
+
+/* Assure la suivi des déplacements de souris sur le composant. */
+static gboolean gtk_graph_display_motion_notify(GtkWidget *, GdkEventMotion *, GtkGraphDisplay *);
+
+/* Réagit à la sélection externe d'une adresse. */
+static void gtk_graph_display_define_main_address(GtkGraphDisplay *, const vmpa2t *);
+
+/* Indique la position courante du curseur. */
+static const vmpa2t *gtk_graph_display_get_caret_location(const GtkGraphDisplay *);
+
+/* Indique la position d'affichage d'une adresse donnée. */
+static bool gtk_graph_display_get_address_coordinates(const GtkGraphDisplay *, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak);
+
+/* Déplace le curseur à un emplacement défini. */
+static bool gtk_graph_display_move_caret_to(GtkGraphDisplay *, gint, gint);
+
+/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
+static void gtk_graph_display_cache_glance(GtkGraphDisplay *, cairo_t *, const GtkAllocation *, double);
+
+/* Supprime tout contenu de l'afficheur de code en graphique. */
+static void gtk_graph_display_reset(GtkGraphDisplay *);
+
+/* Notifie un changement de surbrillance au sein d'un noeud. */
+static void gtk_graph_display_changed_highlights(GtkBlockDisplay *, GtkGraphDisplay *);
+
+/* Notifie une incapacité de déplacement au sein d'un noeud. */
+static void gtk_graph_display_reach_caret_limit(GtkBufferDisplay *, GdkScrollDirection, GtkGraphDisplay *);
+
+
+
+/* Détermine le type du composant d'affichage en graphique. */
+G_DEFINE_TYPE(GtkGraphDisplay, gtk_graph_display, GTK_TYPE_DISPLAY_PANEL)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe GTK à initialiser.                            *
+*                                                                             *
+*  Description : Initialise la classe générique des graphiques de code.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_class_init(GtkGraphDisplayClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GtkWidgetClass *widget_class;           /* Classe de haut niveau       */
+    GtkDisplayPanelClass *panel_class;      /* Classe parente              */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)gtk_graph_display_dispose;
+    object->finalize = (GObjectFinalizeFunc)gtk_graph_display_finalize;
+
+    widget_class = GTK_WIDGET_CLASS(class);
+
+    widget_class->size_allocate = gtk_graph_display_size_allocate;
+
+    panel_class = GTK_DISPLAY_PANEL_CLASS(class);
+
+    panel_class->compute_size = (compute_requested_size_fc)gtk_graph_display_compute_requested_size;
+    panel_class->adjust = (adjust_scroll_value_fc)gtk_graph_display_adjust_scroll_value;
+    panel_class->define = (define_address_fc)gtk_graph_display_define_main_address;
+
+    panel_class->get_caret_loc = (get_caret_location_fc)gtk_graph_display_get_caret_location;
+    panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_graph_display_get_address_coordinates;
+    panel_class->move_caret_to = (move_caret_to_fc)gtk_graph_display_move_caret_to;
+    panel_class->cache_glance = (cache_glance_fc)gtk_graph_display_cache_glance;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance GTK à initialiser.                        *
+*                                                                             *
+*  Description : Initialise une instance d'afficheur de code en graphique.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_init(GtkGraphDisplay *display)
+{
+    display->support = gtk_fixed_new();
+    gtk_widget_set_has_window(display->support, TRUE);
+    gtk_widget_set_can_focus(display->support, TRUE);
+
+    g_signal_connect(G_OBJECT(display->support), "draw",
+                     G_CALLBACK(gtk_graph_display_draw), display);
+
+    g_signal_connect(G_OBJECT(display->support), "button-press-event",
+                      G_CALLBACK(gtk_graph_display_button_press), display);
+    g_signal_connect(G_OBJECT(display->support), "button-release-event",
+                      G_CALLBACK(gtk_graph_display_button_release), display);
+    g_signal_connect(G_OBJECT(display->support), "motion-notify-event",
+                      G_CALLBACK(gtk_graph_display_motion_notify), display);
+
+    gtk_widget_add_events(display->support,
+                          GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+    gtk_widget_show(display->support);
+
+    gtk_fixed_put(GTK_FIXED(display), display->support, 0, 0);
+
+    display->extender = gtk_fixed_new();
+
+    gtk_widget_set_margin_end(display->extender, 1);
+    gtk_widget_set_margin_top(display->extender, 1);
+
+    gtk_widget_show(display->extender);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_dispose(GtkGraphDisplay *display)
+{
+    g_object_unref(G_OBJECT(display->extender));
+
+    gtk_graph_display_reset(display);
+
+    G_OBJECT_CLASS(gtk_graph_display_parent_class)->dispose(G_OBJECT(display));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_finalize(GtkGraphDisplay *display)
+{
+    G_OBJECT_CLASS(gtk_graph_display_parent_class)->finalize(G_OBJECT(display));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget     = composant GTK à mettre à jour.                  *
+*                allocation = étendue accordée à la vue.                      *
+*                                                                             *
+*  Description : S'adapte à la surface concédée par le composant parent.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+{
+    GtkGraphDisplay *display;                     /* Autre version du composant  */
+
+    GTK_WIDGET_CLASS(gtk_graph_display_parent_class)->size_allocate(widget, allocation);
+
+    display = GTK_GRAPH_DISPLAY(widget);
+
+    gtk_graph_display_update_support_margins(display, allocation);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display    = panneau dont le contenu est à déplacer.         *
+*                allocation = étendue accordée à la vue.                      *
+*                                                                             *
+*  Description : Centre si possible le contenu du panneau d'affichage.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_update_support_margins(GtkGraphDisplay *display, const GtkAllocation *allocation)
+{
+    gint width;                             /* Largeur totale du support   */
+    gint height;                            /* Hauteur totale du support   */
+    gint start;                             /* Bordure horizontale         */
+    gint top;                               /* Bordure verticale           */
+
+    gtk_graph_display_compute_requested_size(display, &width, &height);
+
+    if (width > allocation->width)
+        start = 0;
+    else
+        start = (allocation->width - width) / 2;
+
+    if (height > allocation->height)
+        top = 0;
+    else
+        top = (allocation->height - height) / 2;
+
+    gtk_widget_set_margin_start(display->support, start);
+    gtk_widget_set_margin_top(display->support, top);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à consulter.                         *
+*                width   = largeur requise à renseigner ou NULL. [OUT]        *
+*                height  = hauteur requise à renseigner ou NULL. [OUT]        *
+*                                                                             *
+*  Description : Indique les dimensions de travail du composant d'affichage.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_compute_requested_size(GtkGraphDisplay *display, gint *width, gint *height)
+{
+    GtkAllocation needed;                   /* Taille requise              */
+
+    if (display->cluster != NULL)
+    {
+        g_graph_cluster_compute_needed_alloc(display->cluster, &needed);
+        assert(needed.x == 0 && needed.y == 0);
+
+        needed.width += 2 * GRAPH_MARGIN;
+        needed.height += 2 * GRAPH_MARGIN;
+
+    }
+    else
+    {
+        needed.width = 0;
+        needed.height = 0;
+    }
+
+    if (width != NULL) *width = needed.width;
+    if (height != NULL) *height = needed.height;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display     = panneau d'affichage concerné.                  *
+*                adj         = défilement dont une valeur a changé.           *
+*                orientation = indication sur le défilement à traiter.        *
+*                                                                             *
+*  Description : Réagit à un défilement chez une barre associée au composant. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_adjust_scroll_value(GtkGraphDisplay *display, GtkAdjustment *adj, GtkOrientation orientation)
+{
+    gint fake_x;                            /* Abscisse virtuelle          */
+    gint fake_y;                            /* Ordonnée virtuelle          */
+
+    fake_x = 0;
+    fake_y = 0;
+    gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(display), &fake_x, &fake_y);
+
+    gtk_fixed_move(GTK_FIXED(display), display->support, fake_x, -fake_y);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget  = composant GTK à redessiner.                        *
+*                cr      = contexte graphique associé à l'événement.          *
+*                display = support maître à consulter.                        *
+*                                                                             *
+*  Description : Met à jour l'affichage de la vue sous forme graphique.       *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_graph_display_draw(GtkWidget *widget, cairo_t *cr, GtkGraphDisplay *display)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    void draw_shadow(GtkWidget *child, gpointer unused)
+    {
+        GtkAllocation alloc;                /* Emplacement de l'enfant     */
+        gint j;                             /* Boucle de parcours          */
+        cairo_pattern_t *pattern;           /* Zones d'application         */
+
+        /* On évite l'extenseur de support... */
+        if (!GTK_IS_DISPLAY_PANEL(child))
+            return;
+
+        gtk_widget_get_allocation(child, &alloc);
+
+        for (j = 1; j < SHADOW_SIZE; j++)
+        {
+            cairo_push_group(cr);
+
+            gtk_display_panel_define_border_path(GTK_DISPLAY_PANEL(child), cr, alloc.x + j, alloc.y + j);
+            cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+            cairo_fill(cr);
+
+            cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+
+            gtk_display_panel_define_border_path(GTK_DISPLAY_PANEL(child), cr, alloc.x, alloc.y);
+            cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
+            cairo_fill(cr);
+
+            pattern = cairo_pop_group(cr);
+
+            cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.3);
+            cairo_mask(cr, pattern);
+            cairo_fill(cr);
+
+            cairo_pattern_destroy(pattern);
+
+        }
+
+    }
+
+    gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)draw_shadow, NULL);
+
+    for (i = 0; i < display->edges_count; i++)
+        g_graph_edge_draw(display->edges[i], cr, true);
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget  = composant GTK visé par l'opération.                *
+*                event   = informations liées à l'événement.                  *
+*                display = support maître à consulter.                        *
+*                                                                             *
+*  Description : Assure la gestion des clics de souris sur le composant.      *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_graph_display_button_press(GtkWidget *widget, GdkEventButton *event, GtkGraphDisplay *display)
+{
+    gboolean result;                        /* Poursuite à faire suivre    */
+    GtkScrolledWindow *support;             /* Support défilant associé    */
+    GtkAdjustment *hadj;                    /* Gestionnaire du défilement  */
+    GtkAdjustment *vadj;                    /* Gestionnaire du défilement  */
+    GdkCursor *cursor;                      /* Pointeur pour la surface    */
+
+    result = FALSE;
+
+    if (event->button == 1)
+    {
+        support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(display)));
+
+        hadj = gtk_scrolled_window_get_hadjustment(support);
+        vadj = gtk_scrolled_window_get_vadjustment(support);
+
+        display->big_enough = (gtk_adjustment_get_upper(hadj) > gtk_adjustment_get_page_size(hadj)
+                            || gtk_adjustment_get_upper(vadj) > gtk_adjustment_get_page_size(vadj));
+
+        if (display->big_enough)
+        {
+            display->start_x = event->x_root;
+            display->start_y = event->y_root;
+
+            display->ref_h = gtk_adjustment_get_value(hadj);
+            display->ref_v = gtk_adjustment_get_value(vadj);
+
+            cursor = gdk_cursor_new(GDK_FLEUR);
+            gdk_window_set_cursor(gtk_widget_get_window(widget), cursor);
+            g_object_unref(G_OBJECT(cursor));
+
+            result = TRUE;
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget  = composant GTK visé par l'opération.                *
+*                event   = informations liées à l'événement.                  *
+*                display = support maître à consulter.                        *
+*                                                                             *
+*  Description : Assure la gestion des clics de souris sur le composant.      *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_graph_display_button_release(GtkWidget *widget, GdkEventButton *event, GtkGraphDisplay *display)
+{
+    if (event->button == 1 && display->big_enough)
+        gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget  = composant GTK visé par l'opération.                *
+*                event   = informations liées à l'événement.                  *
+*                display = support maître à consulter.                        *
+*                                                                             *
+*  Description : Assure la suivi des déplacements de souris sur le composant. *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_graph_display_motion_notify(GtkWidget *widget, GdkEventMotion *event, GtkGraphDisplay *display)
+{
+    gdouble diff_x;                         /* Evolution sur les abscisses */
+    gdouble diff_y;                         /* Evolution sur les ordonnées */
+    GtkScrolledWindow *support;             /* Support défilant associé    */
+    GtkAdjustment *hadj;                    /* Gestionnaire du défilement  */
+    GtkAdjustment *vadj;                    /* Gestionnaire du défilement  */
+    gdouble value;                          /* Nouvelle valeur bornée      */
+
+    if (event->state & GDK_BUTTON1_MASK && display->big_enough)
+    {
+        diff_x = display->start_x - event->x_root;
+        diff_y = display->start_y - event->y_root;
+
+        support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(display)));
+
+        hadj = gtk_scrolled_window_get_hadjustment(support);
+        vadj = gtk_scrolled_window_get_vadjustment(support);
+
+        value = CLAMP(display->ref_h + diff_x, gtk_adjustment_get_lower(hadj),
+                      gtk_adjustment_get_upper(hadj) - gtk_adjustment_get_page_size(hadj));
+        gtk_adjustment_set_value(hadj, value);
+
+        value = CLAMP(display->ref_v + diff_y, gtk_adjustment_get_lower(vadj),
+                      gtk_adjustment_get_upper(vadj) - gtk_adjustment_get_page_size(vadj));
+        gtk_adjustment_set_value(vadj, value);
+
+    }
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à mettre à jour.                     *
+*                addr    = adresse sélectionnée de manière externe.           *
+*                                                                             *
+*  Description : Réagit à la sélection externe d'une adresse.                 *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_define_main_address(GtkGraphDisplay *display, const vmpa2t *addr)
+{
+    bool need_update;                       /* Mise à jour du contenu ?    */
+    const mrange_t *range;                  /* Couverture courante         */
+    GExeFormat *format;                     /* Type de fichier chargé      */
+    GBinRoutine **routines;                 /* Liste des routines trouvées */
+    size_t routines_count;                  /* Nombre de ces routines      */
+    size_t i;                               /* Boucle de parcours          */
+    gint right;                             /* Abscisse du coin droit      */
+    gint bottom;                            /* Ordonnée du coin inférieur  */
+    GtkAllocation allocation;               /* Espace alloué au panneau    */
+
+    if (display->routine == NULL)
+        need_update = true;
+    else
+    {
+        range = g_binary_routine_get_range(display->routine);
+        need_update = !mrange_contains_addr(range, addr);
+    }
+
+    if (need_update)
+    {
+        gtk_graph_display_reset(display);
+
+        format = g_loaded_binary_get_format(GTK_DISPLAY_PANEL(display)->binary);
+        routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count);
+
+        for (i = 0; i < routines_count; i++)
+        {
+            range = g_binary_routine_get_range(routines[i]);
+
+            if (mrange_contains_addr(range, addr))
+            {
+                display->routine = routines[i];
+                g_object_ref(G_OBJECT(display->routine));
+
+                display->highlighted = init_segment_content_list();
+
+                /*
+                display->children = gtk_graph_display_load_nodes(display, GTK_DISPLAY_PANEL(display)->binary,
+                                                           routines[i]);
+
+                display->allocs = (GtkAllocation *)calloc(display->children_count,
+                                                       sizeof(GtkAllocation));
+
+                display->layout = g_graph_layout_new(g_binary_routine_get_basic_blocks(display->routine),
+                                                  display->children, display->children_count);
+
+                g_graph_layout_place(display->layout, display);
+                */
+
+                do
+                {
+
+                    GBlockList *list;
+
+                    list = g_binary_routine_get_basic_blocks(routines[i]);
+
+#if 0
+                    display->cluster = g_graph_cluster_new(GTK_DISPLAY_PANEL(display)->binary,
+                                                  list, 0/* FIXME */, display->highlighted);
+#endif
+
+
+                    display->cluster = bootstrap_graph_cluster(GTK_DISPLAY_PANEL(display)->binary,
+                                                            list, display->highlighted);
+
+
+
+                    g_graph_cluster_place(display->cluster, display);
+
+                    /**
+                     * Comme la taille du support ne peut pas être forcée et
+                     * étendue pour comprendre les ombres, on place un composant
+                     * minuscule à l'extrémité de ce support.
+                     */
+
+                    gtk_graph_display_compute_requested_size(display, &right, &bottom);
+
+                    g_object_ref(G_OBJECT(display->extender));
+                    gtk_fixed_put(GTK_FIXED(display->support), display->extender, right - 1, bottom - 1);
+
+                    /**
+                     * Si possible, on centre le contenu obtenu.
+                     */
+
+                    gtk_widget_get_allocation(GTK_WIDGET(display), &allocation);
+
+                    gtk_graph_display_update_support_margins(display, &allocation);
+
+
+
+                }
+                while (0);
+
+
+
+                break;
+
+            }
+
+        }
+
+        change_editor_items_current_view_content(GTK_DISPLAY_PANEL(display));
+
+        g_object_unref(G_OBJECT(format));
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                                                                             *
+*  Description : Indique la position courante du curseur.                     *
+*                                                                             *
+*  Retour      : Emplacement courant du curseur ou NULL si aucun.             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const vmpa2t *gtk_graph_display_get_caret_location(const GtkGraphDisplay *display)
+{
+    return NULL;    /* FIXME */
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à consulter.                         *
+*                addr    = adresse à présenter à l'écran.                     *
+*                x       = position horizontale au sein du composant. [OUT]   *
+*                y       = position verticale au sein du composant. [OUT]     *
+*                tweak   = adaptation finale à effectuer.                     *
+*                                                                             *
+*  Description : Indique la position d'affichage d'une adresse donnée.        *
+*                                                                             *
+*  Retour      : true si l'adresse fait partie du composant, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool gtk_graph_display_get_address_coordinates(const GtkGraphDisplay *display, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
+{
+    /* TODO */
+
+    return false;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                x       = abscisse proposée pour le nouvel emplacement.      *
+*                y       = ordonnée proposée pour le nouvel emplacement.      *
+*                                                                             *
+*  Description : Déplace le curseur à un emplacement défini.                  *
+*                                                                             *
+*  Retour      : true si un traitement a été effectué, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool gtk_graph_display_move_caret_to(GtkGraphDisplay *display, gint x, gint y)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = false;
+
+    void move_caret_to_sub_block(GtkWidget *child, gpointer unused)
+    {
+        GtkAllocation alloc;                /* Emplacement réservé         */
+        GtkDisplayPanel *panel;             /* Autre vision d'enfance      */
+        gint sub_x;                         /* Abscisse relative à l'enfant*/
+        gint sub_y;                         /* Ordonnée relative à l'enfant*/
+
+        if (result)
+            return;
+
+        if (!GTK_IS_BUFFER_DISPLAY(child))
+            return;
+
+        gtk_widget_get_allocation(child, &alloc);
+
+        if (x < alloc.x || x >= (alloc.x + alloc.width)) return;
+        if (y < alloc.y || y >= (alloc.y + alloc.height)) return;
+
+        panel = GTK_DISPLAY_PANEL(child);
+
+        sub_x = x - alloc.x;
+        sub_y = y - alloc.y;
+
+        result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->move_caret_to(panel, sub_x, sub_y);
+
+    }
+
+    gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)move_caret_to_sub_block, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à manipuler.                         *
+*                cr      = assistant pour la création de rendus.              *
+*                area    = taille de la surface réduite à disposition.        *
+*                scale   = échelle vis à vis de la taille réelle.             *
+*                                                                             *
+*  Description : Place en cache un rendu destiné à l'aperçu graphique rapide. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_cache_glance(GtkGraphDisplay *display, cairo_t *cr, const GtkAllocation *area, double scale)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    void draw_child_glance(GtkWidget *child, gpointer unused)
+    {
+        GtkAllocation sub_area;             /* Emplacement réservé         */
+
+        if (!GTK_IS_BUFFER_DISPLAY(child))
+            return;
+
+        gtk_widget_get_allocation(child, &sub_area);
+
+        sub_area.x *= scale;
+        sub_area.y *= scale;
+        sub_area.width = sub_area.width * scale + 1;
+        sub_area.height = sub_area.height * scale + 1;
+
+        gtk_display_panel_cache_glance(GTK_DISPLAY_PANEL(child), cr, &sub_area, scale);
+
+    }
+
+    gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)draw_child_glance, NULL);
+
+    cairo_scale(cr, scale, scale);
+
+    for (i = 0; i < display->edges_count; i++)
+        g_graph_edge_draw(display->edges[i], cr, false);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un nouveau composant pour l'affichage en graphique.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *gtk_graph_display_new(void)
+{
+    return g_object_new(GTK_TYPE_GRAPH_DISPLAY, NULL);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à mettre à jour.                     *
+*                widget  = composant GTK à insérer.                           *
+*                x       = abscisse du point d'insertion.                     *
+*                y       = ordonnée du point d'insertion.                     *
+*                                                                             *
+*  Description : Place une vue sous forme de bloc dans le graphique.          *
+*                                                                             *
+*  Retour      : Plutôt que de redéfinir *toutes* les méthodes de             *
+*                GtkContainer, on étend !                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_graph_display_put(GtkGraphDisplay *display, GtkWidget *widget, const GtkAllocation *alloc)
+{
+    g_signal_connect(widget, "reach-limit", G_CALLBACK(gtk_graph_display_reach_caret_limit), display);
+    g_signal_connect(widget, "highlight-changed", G_CALLBACK(gtk_graph_display_changed_highlights), display);
+
+    gtk_fixed_put(GTK_FIXED(display->support), widget, GRAPH_MARGIN + alloc->x, GRAPH_MARGIN + alloc->y);
+
+}
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK à mettre à jour.                     *
+*                edge    = lien entre noeuds à conserver.                     *
+*                                                                             *
+*  Description : Intègre un lien entre blocs graphiques dans l'afficheur.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_graph_display_add_edge(GtkGraphDisplay *display, GGraphEdge *edge)
+{
+    g_graph_edge_offset(edge, GRAPH_MARGIN, GRAPH_MARGIN);
+
+    display->edges = (GGraphEdge **)realloc(display->edges,
+                                         ++display->edges_count * sizeof(GGraphEdge *));
+
+    display->edges[display->edges_count - 1] = edge;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = instance GTK à réinitialiser.                      *
+*                                                                             *
+*  Description : Supprime tout contenu de l'afficheur de code en graphique.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_reset(GtkGraphDisplay *display)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+
+    void detach_all_blocks(GtkWidget *widget, GtkContainer *container)
+    {
+
+
+
+        gtk_container_remove(container, widget);
+
+
+    }
+
+
+    gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)detach_all_blocks, display->support);
+
+
+
+    if (display->routine != NULL)
+    {
+        g_object_unref(G_OBJECT(display->routine));
+        display->routine = NULL;
+    }
+
+    if (display->highlighted != NULL)
+        exit_segment_content_list(display->highlighted);
+
+    if (display->cluster != NULL)
+    {
+        g_object_unref(G_OBJECT(display->cluster));
+        display->cluster = NULL;
+    }
+
+    for (i = 0; i < display->edges_count; i++)
+        g_object_unref(G_OBJECT(display->edges[i]));
+
+    if (display->edges_count > 0)
+    {
+        free(display->edges);
+        display->edges = NULL;
+
+        display->edges_count = 0;
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node    = composant d'affichage impliqué dans la procédure.  *
+*                display = support graphique de tous les noeuds.              *
+*                                                                             *
+*  Description : Notifie un changement de surbrillance au sein d'un noeud.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_changed_highlights(GtkBlockDisplay *node, GtkGraphDisplay *display)
+{
+    void refresh_highlights(GtkWidget *child, gpointer unused)
+    {
+        if (!GTK_IS_BUFFER_DISPLAY(child))
+            return;
+
+        if (child != GTK_WIDGET(node))
+            gtk_widget_queue_draw(child);
+
+    }
+
+    gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)refresh_highlights, NULL);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node    = composant d'affichage impliqué dans la procédure.  *
+*                dir     = direction du déplacement souhaité et impossible.   *
+*                display = support graphique de tous les noeuds.              *
+*                                                                             *
+*  Description : Notifie une incapacité de déplacement au sein d'un noeud.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_display_reach_caret_limit(GtkBufferDisplay *node, GdkScrollDirection dir, GtkGraphDisplay *display)
+{
+    GBufferView *view;                      /* Vue d'un tampon global      */
+    vmpa2t first;                           /* Début d'un groupe de lignes */
+    vmpa2t last;                            /* Fin d'un groupe de lignes   */
+    const mrange_t *range;                  /* Couverture courante         */
+    GArchProcessor *proc;                   /* Processeur pour instructions*/
+    vmpa2t iaddr;                           /* Position de l'instructin    */
+    instr_iter_t *iter;                     /* Boucle de parcours          */
+    GArchInstruction *instr;                /* Instruction à venir visiter */
+#ifndef NDEBUG
+    bool is_return;                         /* Est-ce une instruc. finale ?*/
+#endif
+    GtkBufferDisplay *target;               /* Bloc suivant pour le focus  */
+
+    /* Détermination de l'instruction à cibler */
+
+    view = gtk_buffer_display_get_view(node);
+    g_buffer_view_get_restrictions(view, &first, &last);
+    g_object_unref(G_OBJECT(view));
+
+    range = g_binary_routine_get_range(display->routine);
+
+    proc = g_loaded_binary_get_processor(GTK_DISPLAY_PANEL(display)->binary);
+
+    init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+#ifndef NDEBUG
+    is_return = false;
+#endif
+
+    switch (dir)
+    {
+        case GDK_SCROLL_LEFT:
+        case GDK_SCROLL_UP:
+
+            if (cmp_vmpa(get_mrange_addr(range), &first) != 0)
+            {
+                iter = g_arch_processor_get_iter_from_address(proc, &first);
+
+                if (iter != NULL)
+                {
+                    instr = get_instruction_iterator_prev(iter);
+
+                    if (instr != NULL)
+                    {
+                        /* TODO : boucler si !HAS_CODE */
+
+                        if (mrange_contains_addr(range, &iaddr))
+                            copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(instr)));
+
+                        g_object_unref(G_OBJECT(instr));
+
+                    }
+
+                    delete_instruction_iterator(iter);
+
+                }
+
+            }
+
+            break;
+
+        case GDK_SCROLL_RIGHT:
+        case GDK_SCROLL_DOWN:
+
+            iter = g_arch_processor_get_iter_from_address(proc, &last);
+
+            if (iter != NULL)
+            {
+#ifndef NDEBUG
+                instr = get_instruction_iterator_current(iter);
+                if (instr != NULL)
+                {
+                    is_return = (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT);
+                    g_object_unref(G_OBJECT(instr));
+                }
+#endif
+
+                instr = get_instruction_iterator_next(iter);
+
+                if (instr != NULL)
+                {
+                    /* TODO : boucler si !HAS_CODE */
+
+                    copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(instr)));
+
+                    if (!mrange_contains_addr(range, &iaddr))
+                        init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+                    g_object_unref(G_OBJECT(instr));
+
+                }
+
+                delete_instruction_iterator(iter);
+
+            }
+
+            break;
+
+        case GDK_SCROLL_SMOOTH:
+            assert(false);  /* Argument jamais généré */
+            break;
+
+    }
+
+    g_object_unref(G_OBJECT(proc));
+
+    /* Recherche du bloc parent */
+
+    if (is_invalid_vmpa(&iaddr))
+        return;
+
+    target = NULL;
+
+    void find_target_block(GtkWidget *child, gpointer unused)
+    {
+        GtkBufferDisplay *test;             /* Candidat potentiel à tester */
+
+        if (!GTK_IS_BUFFER_DISPLAY(child))
+            return;
+
+        test = GTK_BUFFER_DISPLAY(child);
+
+        view = gtk_buffer_display_get_view(test);
+        g_buffer_view_get_restrictions(view, &first, &last);
+        g_object_unref(G_OBJECT(view));
+
+        if (cmp_vmpa(&first, &iaddr) <= 0 && cmp_vmpa(&iaddr, &last) <= 0)
+        {
+            assert(target == NULL);
+            assert(node != test);
+            target = test;
+            return;
+        }
+
+    }
+
+    gtk_container_foreach(GTK_CONTAINER(display->support), (GtkCallback)find_target_block, NULL);
+
+    assert(target != NULL || is_return);
+
+    /* Affichage du nouveau curseur */
+
+    /**
+     * Il se peut qu'aucune adresse suivante ne soit disponible : c'est typiquement
+     * le cas sous ARM, avec les valeurs brutes référencées dans le code. Ces valeurs
+     * sont incluses dans la surface couverte par la routine concernée, mais ne sont
+     * pas intégrées dans les blocs basiques associés.
+     */
+
+    if (target == NULL)
+        return;
+
+    gtk_widget_grab_focus(GTK_WIDGET(target));
+
+    switch (dir)
+    {
+        case GDK_SCROLL_UP:
+        case GDK_SCROLL_LEFT:
+            gtk_buffer_display_move_caret_to(target, false, NULL);
+            break;
+
+            break;
+
+        case GDK_SCROLL_RIGHT:
+        case GDK_SCROLL_DOWN:
+            gtk_buffer_display_move_caret_to(target, true, NULL);
+            break;
+
+            break;
+
+        case GDK_SCROLL_SMOOTH:
+            assert(false);  /* Argument jamais généré */
+            break;
+
+    }
+
+    /* TODO : scrolling... */
+
+}
diff --git a/src/gtkext/gtkgraphdisplay.h b/src/gtkext/gtkgraphdisplay.h
new file mode 100644
index 0000000..8d553b7
--- /dev/null
+++ b/src/gtkext/gtkgraphdisplay.h
@@ -0,0 +1,64 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkgraphdisplay.h - prototypes pour l'affichage de morceaux de code sous forme graphique
+ *
+ * Copyright (C) 2009-2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 _GTKEXT_GTKGRAPHDISPLAY_H
+#define _GTKEXT_GTKGRAPHDISPLAY_H
+
+
+#include <gtk/gtk.h>
+
+
+#include "graph/edge.h"
+
+
+
+#define GTK_TYPE_GRAPH_DISPLAY              (gtk_graph_display_get_type())
+#define GTK_GRAPH_DISPLAY(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_GRAPH_DISPLAY, GtkGraphDisplay))
+#define GTK_GRAPH_DISPLAY_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_GRAPH_DISPLAY, GtkGraphDisplayClass))
+#define GTK_IS_GRAPH_DISPLAY(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_GRAPH_DISPLAY))
+#define GTK_IS_GRAPH_DISPLAY_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_GRAPH_DISPLAY))
+#define GTK_GRAPH_DISPLAY_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_GRAPH_DISPLAY, GtkGraphDisplayClass))
+
+
+/* Composant d'affichage sous forme graphique (instance) */
+typedef struct _GtkGraphDisplay GtkGraphDisplay;
+
+/* Composant d'affichage sous forme graphique (classe) */
+typedef struct _GtkGraphDisplayClass GtkGraphDisplayClass;
+
+
+/* Détermine le type du composant d'affichage en graphique. */
+GType gtk_graph_display_get_type(void);
+
+/* Crée un nouveau composant pour l'affichage en graphique. */
+GtkWidget *gtk_graph_display_new(void);
+
+/* Place une vue sous forme de bloc dans le graphique. */
+void gtk_graph_display_put(GtkGraphDisplay *, GtkWidget *, const GtkAllocation *);
+
+/* Intègre un lien entre blocs graphiques dans l'afficheur. */
+void gtk_graph_display_add_edge(GtkGraphDisplay *, GGraphEdge *);
+
+
+
+#endif  /* _GTKEXT_GTKGRAPHDISPLAY_H */
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
deleted file mode 100644
index 57bbec0..0000000
--- a/src/gtkext/gtkgraphview.c
+++ /dev/null
@@ -1,1371 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkgraphview.c - affichage de morceaux de code sous forme graphique
- *
- * Copyright (C) 2009-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 "gtkgraphview.h"
-
-
-#include <assert.h>
-
-
-#include "gtkblockview.h"
-#include "gtkbufferview.h"
-#include "gtkdisplaypanel-int.h"
-#include "graph/cluster.h"
-#include "../analysis/blocks/flow.h"
-#include "../format/format.h"
-#include "../gui/editem.h"
-
-
-
-/* Composant d'affichage sous forme graphique (instance) */
-struct _GtkGraphView
-{
-    GtkDisplayPanel parent;                 /* A laisser en premier        */
-    GtkWidget *support;                     /* Support des vues en bloc    */
-    GtkWidget *extender;                    /* Force la taille du support  */
-
-    GBinRoutine *routine;                   /* Routine en cours d'affichage*/
-
-    segcnt_list *highlighted;               /* Segments mis en évidence    */
-    GtkBufferView **children;               /* Liste des sous-blocs        */
-    GtkAllocation *allocs;                  /* Emplacements prévisibles    */
-    size_t children_count;                  /* Taille de cette liste       */
-
-    //GGraphLayout *layout;                   /* Disposition en graphique    */
-    GGraphCluster *cluster;                 /* Disposition en graphique    */
-
-    GGraphEdge **edges;                     /* Liens entre les noeuds      */
-    size_t edges_count;                     /* Quantité de ces liens       */
-
-    gdouble start_x;                        /* Abscisse du point de souris */
-    gdouble start_y;                        /* Ordonnée du point de souris */
-    bool big_enough;                        /* Capacités de déplacement ?  */
-    gdouble ref_h;                          /* Position horizontale de ref.*/
-    gdouble ref_v;                          /* Position verticale de ref.  */
-
-};
-
-/* Composant d'affichage sous forme graphique (classe) */
-struct _GtkGraphViewClass
-{
-    GtkDisplayPanelClass parent;            /* A laisser en premier        */
-
-};
-
-
-/* Profondeur de l'ombre */
-#define SHADOW_SIZE 4
-
-
-/* Initialise la classe générique des graphiques de code. */
-static void gtk_graph_view_class_init(GtkGraphViewClass *);
-
-/* Initialise une instance d'afficheur de code en graphique. */
-static void gtk_graph_view_init(GtkGraphView *);
-
-/* Supprime toutes les références externes. */
-static void gtk_graph_view_dispose(GtkGraphView *);
-
-/* Procède à la libération totale de la mémoire. */
-static void gtk_graph_view_finalize(GtkGraphView *);
-
-/* S'adapte à la surface concédée par le composant parent. */
-static void gtk_graph_view_size_allocate(GtkWidget *, GtkAllocation *);
-
-/* Centre si possible le contenu du panneau d'affichage. */
-static void gtk_graph_view_update_support_margins(GtkGraphView *, const GtkAllocation *);
-
-/* Indique les dimensions de travail du composant d'affichage. */
-static void gtk_graph_view_compute_requested_size(GtkGraphView *, gint *, gint *);
-
-/* Réagit à un défilement chez une barre associée au composant. */
-static void gtk_graph_view_adjust_scroll_value(GtkGraphView *, GtkAdjustment *, GtkOrientation);
-
-/*  Met à jour l'affichage de la vue sous forme graphique. */
-static gboolean gtk_graph_view_draw(GtkWidget *, cairo_t *, GtkGraphView *);
-
-/* Assure la gestion des clics de souris sur le composant. */
-static gboolean gtk_graph_view_button_press(GtkWidget *, GdkEventButton *, GtkGraphView *);
-
-/* Assure la gestion des clics de souris sur le composant. */
-static gboolean gtk_graph_view_button_release(GtkWidget *, GdkEventButton *, GtkGraphView *);
-
-/* Assure la suivi des déplacements de souris sur le composant. */
-static gboolean gtk_graph_view_motion_notify(GtkWidget *, GdkEventMotion *, GtkGraphView *);
-
-/* Actualise les besoins internes avant un redimensionnement. */
-static void gtk_graph_view_prepare_resize(GtkGraphView *);
-
-/* Réagit à la sélection externe d'une adresse. */
-static void gtk_graph_view_define_main_address(GtkGraphView *, const vmpa2t *);
-
-/* Indique la position courante du curseur. */
-static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *);
-
-/* Indique la position d'affichage d'une adresse donnée. */
-static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak);
-
-/* Déplace le curseur à un emplacement défini. */
-static bool gtk_graph_view_move_caret_to(GtkGraphView *, gint, gint);
-
-/* Place en cache un rendu destiné à l'aperçu graphique rapide. */
-static void gtk_graph_view_cache_glance(GtkGraphView *, cairo_t *, const GtkAllocation *, double);
-
-/* Supprime tout contenu de l'afficheur de code en graphique. */
-static void gtk_graph_view_reset(GtkGraphView *);
-
-/* Définit la liste complète des éléments du futur graphique. */
-static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *, GLoadedBinary *, const GBinRoutine *);
-
-/* Notifie un changement de surbrillance au sein d'un noeud. */
-static void gtk_graph_view_changed_highlights(GtkBlockView *, GtkGraphView *);
-
-/* Notifie une incapacité de déplacement au sein d'un noeud. */
-static void gtk_graph_view_reach_caret_limit(GtkBufferView *, GdkScrollDirection, GtkGraphView *);
-
-
-
-/* Détermine le type du composant d'affichage en graphique. */
-G_DEFINE_TYPE(GtkGraphView, gtk_graph_view, GTK_TYPE_DISPLAY_PANEL)
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : class = classe GTK à initialiser.                            *
-*                                                                             *
-*  Description : Initialise la classe générique des graphiques de code.       *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_class_init(GtkGraphViewClass *class)
-{
-    GObjectClass *object;                   /* Autre version de la classe  */
-    GtkWidgetClass *widget_class;           /* Classe de haut niveau       */
-    GtkDisplayPanelClass *panel_class;      /* Classe parente              */
-
-    object = G_OBJECT_CLASS(class);
-
-    object->dispose = (GObjectFinalizeFunc/* ! */)gtk_graph_view_dispose;
-    object->finalize = (GObjectFinalizeFunc)gtk_graph_view_finalize;
-
-    widget_class = GTK_WIDGET_CLASS(class);
-
-    widget_class->size_allocate = gtk_graph_view_size_allocate;
-
-    panel_class = GTK_DISPLAY_PANEL_CLASS(class);
-
-    panel_class->compute_size = (compute_requested_size_fc)gtk_graph_view_compute_requested_size;
-    panel_class->adjust = (adjust_scroll_value_fc)gtk_graph_view_adjust_scroll_value;
-    panel_class->define = (define_address_fc)gtk_graph_view_define_main_address;
-
-    panel_class->get_caret_loc = (get_caret_location_fc)gtk_graph_view_get_caret_location;
-    panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
-    panel_class->move_caret_to = (move_caret_to_fc)gtk_graph_view_move_caret_to;
-    panel_class->cache_glance = (cache_glance_fc)gtk_graph_view_cache_glance;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = instance GTK à initialiser.                           *
-*                                                                             *
-*  Description : Initialise une instance d'afficheur de code en graphique.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_init(GtkGraphView *view)
-{
-    GtkDisplayPanel *panel;                 /* Instance parente #1         */
-    //GtkBinView *binview;                    /* Instance parente #2         */
-
-    panel = GTK_DISPLAY_PANEL(view);
-
-    panel->resize = (prepare_resize_fc)gtk_graph_view_prepare_resize;
-    ////////viewpanel->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
-
-    //binview = GTK_BIN_VIEW(view);
-
-    //binview->set_lines = (set_rendering_lines_fc)gtk_graph_view_set_rendering_lines;
-    //binview->define_address = (define_main_address_fc)gtk_graph_view_define_main_address;
-    //binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
-
-    view->support = gtk_fixed_new();
-    gtk_widget_set_has_window(view->support, TRUE);
-    gtk_widget_set_can_focus(view->support, TRUE);
-
-    g_signal_connect(G_OBJECT(view->support), "draw",
-                     G_CALLBACK(gtk_graph_view_draw), view);
-
-    g_signal_connect(G_OBJECT(view->support), "button-press-event",
-                      G_CALLBACK(gtk_graph_view_button_press), view);
-    g_signal_connect(G_OBJECT(view->support), "button-release-event",
-                      G_CALLBACK(gtk_graph_view_button_release), view);
-    g_signal_connect(G_OBJECT(view->support), "motion-notify-event",
-                      G_CALLBACK(gtk_graph_view_motion_notify), view);
-
-    gtk_widget_add_events(view->support,
-                          GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
-
-    gtk_widget_show(view->support);
-
-    gtk_fixed_put(GTK_FIXED(view), view->support, 0, 0);
-
-    //view->mutex = g_mutex_new();
-    //view->cond = g_cond_new();
-
-
-    view->extender = gtk_fixed_new();
-
-    gtk_widget_set_margin_end(view->extender, 1);
-    gtk_widget_set_margin_top(view->extender, 1);
-
-    gtk_widget_show(view->extender);
-
-
-    view->cluster = NULL;
-
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = instance d'objet GLib à traiter.                      *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_dispose(GtkGraphView *view)
-{
-    g_object_unref(G_OBJECT(view->extender));
-
-    if (view->cluster != NULL)
-    {
-        g_object_unref(G_OBJECT(view->cluster));
-        view->cluster = NULL;
-    }
-
-    G_OBJECT_CLASS(gtk_graph_view_parent_class)->dispose(G_OBJECT(view));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = instance d'objet GLib à traiter.                      *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_finalize(GtkGraphView *view)
-{
-    G_OBJECT_CLASS(gtk_graph_view_parent_class)->finalize(G_OBJECT(view));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget     = composant GTK à mettre à jour.                  *
-*                allocation = étendue accordée à la vue.                      *
-*                                                                             *
-*  Description : S'adapte à la surface concédée par le composant parent.      *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
-    GtkGraphView *view;                     /* Autre version du composant  */
-
-    GTK_WIDGET_CLASS(gtk_graph_view_parent_class)->size_allocate(widget, allocation);
-
-    view = GTK_GRAPH_VIEW(widget);
-
-    gtk_graph_view_update_support_margins(view, allocation);
-
-}
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view       = panneau dont le contenu est à déplacer.         *
-*                allocation = étendue accordée à la vue.                      *
-*                                                                             *
-*  Description : Centre si possible le contenu du panneau d'affichage.        *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_update_support_margins(GtkGraphView *view, const GtkAllocation *allocation)
-{
-    gint width;                             /* Largeur totale du support   */
-    gint height;                            /* Hauteur totale du support   */
-    gint start;                             /* Bordure horizontale         */
-    gint top;                               /* Bordure verticale           */
-
-    gtk_graph_view_compute_requested_size(view, &width, &height);
-
-    if (width > allocation->width)
-        start = 0;
-    else
-        start = (allocation->width - width) / 2;
-
-    if (height > allocation->height)
-        top = 0;
-    else
-        top = (allocation->height - height) / 2;
-
-    gtk_widget_set_margin_start(view->support, start);
-    gtk_widget_set_margin_top(view->support, top);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view   = composant GTK à consulter.                          *
-*                width  = largeur requise à renseigner ou NULL. [OUT]         *
-*                height = hauteur requise à renseigner ou NULL. [OUT]         *
-*                                                                             *
-*  Description : Indique les dimensions de travail du composant d'affichage.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_compute_requested_size(GtkGraphView *view, gint *width, gint *height)
-{
-    GtkAllocation needed;                   /* Taille requise              */
-    gint rwidth;                            /* Largeur demandée            */
-    gint rheight;                           /* Hauteur demandée            */
-
-    if (view->cluster != NULL)
-    {
-        g_graph_cluster_compute_needed_alloc(view->cluster, &needed);
-        assert(needed.x == 0 && needed.y == 0);
-
-        /* TODO : marges ou centrage */
-
-    }
-    else
-    {
-        needed.width = 0;
-        needed.height = 0;
-    }
-
-    if (width != NULL) *width = needed.width + SHADOW_SIZE;
-    if (height != NULL) *height = needed.height + SHADOW_SIZE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view        = panneau d'affichage concerné.                  *
-*                adj         = défilement dont une valeur a changé.           *
-*                orientation = indication sur le défilement à traiter.        *
-*                                                                             *
-*  Description : Réagit à un défilement chez une barre associée au composant. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_adjust_scroll_value(GtkGraphView *view, GtkAdjustment *adj, GtkOrientation orientation)
-{
-    gint fake_x;                            /* Abscisse virtuelle          */
-    gint fake_y;                            /* Ordonnée virtuelle          */
-
-    fake_x = 0;
-    fake_y = 0;
-    gtk_display_panel_compute_fake_coord(GTK_DISPLAY_PANEL(view), &fake_x, &fake_y);
-
-    gtk_fixed_move(GTK_FIXED(view), view->support, fake_x, -fake_y);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant GTK à redessiner.                         *
-*                cr     = contexte graphique associé à l'événement.           *
-*                view   = support maître à consulter.                         *
-*                                                                             *
-*  Description : Met à jour l'affichage de la vue sous forme graphique.       *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_graph_view_draw(GtkWidget *widget, cairo_t *cr, GtkGraphView *view)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    void draw_shadow(GtkWidget *child, gpointer unused)
-    {
-        GtkAllocation alloc;                /* Emplacement de l'enfant     */
-        gint j;                             /* Boucle de parcours          */
-        cairo_pattern_t *pattern;           /* Zones d'application         */
-
-        gtk_widget_get_allocation(child, &alloc);
-
-        for (j = 1; j < SHADOW_SIZE; j++)
-        {
-            cairo_push_group(cr);
-
-            gtk_display_panel_define_border_path(GTK_DISPLAY_PANEL(child), cr, alloc.x + j, alloc.y + j);
-            cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
-            cairo_fill(cr);
-
-            cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
-
-            gtk_display_panel_define_border_path(GTK_DISPLAY_PANEL(child), cr, alloc.x, alloc.y);
-            cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
-            cairo_fill(cr);
-
-            pattern = cairo_pop_group(cr);
-
-            cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.3);
-            cairo_mask(cr, pattern);
-            cairo_fill(cr);
-
-            cairo_pattern_destroy(pattern);
-
-        }
-
-    }
-
-    gtk_container_foreach(GTK_CONTAINER(view->support), (GtkCallback)draw_shadow, NULL);
-
-
-    for (i = 0; i < view->edges_count; i++)
-        g_graph_edge_draw(view->edges[i], cr, true);
-
-
-    /*
-    if (view->layout != NULL)
-        g_graph_layout_draw(view->layout, cr, true);
-    */
-
-    return FALSE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant GTK visé par l'opération.                 *
-*                event  = informations liées à l'événement.                   *
-*                view   = support maître à consulter.                         *
-*                                                                             *
-*  Description : Assure la gestion des clics de souris sur le composant.      *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_graph_view_button_press(GtkWidget *widget, GdkEventButton *event, GtkGraphView *view)
-{
-    gboolean result;                        /* Poursuite à faire suivre    */
-    GtkScrolledWindow *support;             /* Support défilant associé    */
-    GtkAdjustment *hadj;                    /* Gestionnaire du défilement  */
-    GtkAdjustment *vadj;                    /* Gestionnaire du défilement  */
-    GdkCursor *cursor;                      /* Pointeur pour la surface    */
-
-    result = FALSE;
-
-    if (event->button == 1)
-    {
-        support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(view)));
-
-        hadj = gtk_scrolled_window_get_hadjustment(support);
-        vadj = gtk_scrolled_window_get_vadjustment(support);
-
-        view->big_enough = (gtk_adjustment_get_upper(hadj) > gtk_adjustment_get_page_size(hadj)
-                            || gtk_adjustment_get_upper(vadj) > gtk_adjustment_get_page_size(vadj));
-
-        if (view->big_enough)
-        {
-            view->start_x = event->x_root;
-            view->start_y = event->y_root;
-
-            view->ref_h = gtk_adjustment_get_value(hadj);
-            view->ref_v = gtk_adjustment_get_value(vadj);
-
-            cursor = gdk_cursor_new(GDK_FLEUR);
-            gdk_window_set_cursor(gtk_widget_get_window(widget), cursor);
-            g_object_unref(G_OBJECT(cursor));
-
-            result = TRUE;
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant GTK visé par l'opération.                 *
-*                event  = informations liées à l'événement.                   *
-*                view   = support maître à consulter.                         *
-*                                                                             *
-*  Description : Assure la gestion des clics de souris sur le composant.      *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_graph_view_button_release(GtkWidget *widget, GdkEventButton *event, GtkGraphView *view)
-{
-    if (event->button == 1 && view->big_enough)
-        gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
-
-    return FALSE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant GTK visé par l'opération.                 *
-*                event  = informations liées à l'événement.                   *
-*                view   = support maître à consulter.                         *
-*                                                                             *
-*  Description : Assure la suivi des déplacements de souris sur le composant. *
-*                                                                             *
-*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean gtk_graph_view_motion_notify(GtkWidget *widget, GdkEventMotion *event, GtkGraphView *view)
-{
-    gdouble diff_x;                         /* Evolution sur les abscisses */
-    gdouble diff_y;                         /* Evolution sur les ordonnées */
-    GtkScrolledWindow *support;             /* Support défilant associé    */
-    GtkAdjustment *hadj;                    /* Gestionnaire du défilement  */
-    GtkAdjustment *vadj;                    /* Gestionnaire du défilement  */
-    gdouble value;                          /* Nouvelle valeur bornée      */
-
-    if (event->state & GDK_BUTTON1_MASK && view->big_enough)
-    {
-        diff_x = view->start_x - event->x_root;
-        diff_y = view->start_y - event->y_root;
-
-        support = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(GTK_WIDGET(view)));
-
-        hadj = gtk_scrolled_window_get_hadjustment(support);
-        vadj = gtk_scrolled_window_get_vadjustment(support);
-
-        value = CLAMP(view->ref_h + diff_x, gtk_adjustment_get_lower(hadj),
-                      gtk_adjustment_get_upper(hadj) - gtk_adjustment_get_page_size(hadj));
-        gtk_adjustment_set_value(hadj, value);
-
-        value = CLAMP(view->ref_v + diff_y, gtk_adjustment_get_lower(vadj),
-                      gtk_adjustment_get_upper(vadj) - gtk_adjustment_get_page_size(vadj));
-        gtk_adjustment_set_value(vadj, value);
-
-    }
-
-    return FALSE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à mettre à jour.                        *
-*                                                                             *
-*  Description : Actualise les besoins internes avant un redimensionnement.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_prepare_resize(GtkGraphView *view)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    if (view->children_count > 0)
-    {
-        for (i = 0; i < view->children_count; i++)
-            gtk_widget_queue_resize(GTK_WIDGET(view->children[i]));
-
-        /*
-        g_graph_layout_refresh(view->layout);
-        g_graph_layout_place(view->layout, view);
-        */
-
-        change_editor_items_current_view_content(GTK_DISPLAY_PANEL(view));
-
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à mettre à jour.                        *
-*                addr = adresse sélectionnée de manière externe.              *
-*                                                                             *
-*  Description : Réagit à la sélection externe d'une adresse.                 *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t *addr)
-{
-    bool need_update;                       /* Mise à jour du contenu ?    */
-    const mrange_t *range;                  /* Couverture courante         */
-    GExeFormat *format;                     /* Type de fichier chargé      */
-    GBinRoutine **routines;                 /* Liste des routines trouvées */
-    size_t routines_count;                  /* Nombre de ces routines      */
-    size_t i;                               /* Boucle de parcours          */
-    gint right;                             /* Abscisse du coin droit      */
-    gint bottom;                            /* Ordonnée du coin inférieur  */
-    GtkAllocation allocation;               /* Espace alloué au panneau    */
-
-    if (view->routine == NULL)
-        need_update = true;
-    else
-    {
-        range = g_binary_routine_get_range(view->routine);
-        need_update = !mrange_contains_addr(range, addr);
-    }
-
-    if (need_update)
-    {
-        gtk_graph_view_reset(view);
-
-        format = g_loaded_binary_get_format(GTK_DISPLAY_PANEL(view)->binary);
-        routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count);
-
-        for (i = 0; i < routines_count; i++)
-        {
-            range = g_binary_routine_get_range(routines[i]);
-
-            if (mrange_contains_addr(range, addr))
-            {
-                view->routine = routines[i];
-                g_object_ref(G_OBJECT(view->routine));
-
-                view->highlighted = init_segment_content_list();
-
-                /*
-                view->children = gtk_graph_view_load_nodes(view, GTK_DISPLAY_PANEL(view)->binary,
-                                                           routines[i]);
-
-                view->allocs = (GtkAllocation *)calloc(view->children_count,
-                                                       sizeof(GtkAllocation));
-
-                view->layout = g_graph_layout_new(g_binary_routine_get_basic_blocks(view->routine),
-                                                  view->children, view->children_count);
-
-                g_graph_layout_place(view->layout, view);
-                */
-
-                do
-                {
-
-                    GBlockList *list;
-
-                    list = g_binary_routine_get_basic_blocks(routines[i]);
-
-#if 0
-                    view->cluster = g_graph_cluster_new(GTK_DISPLAY_PANEL(view)->binary,
-                                                  list, 0/* FIXME */, view->highlighted);
-#endif
-
-
-                    view->cluster = bootstrap_graph_cluster(GTK_DISPLAY_PANEL(view)->binary,
-                                                            list, view->highlighted);
-
-
-
-                    g_graph_cluster_place(view->cluster, view);
-
-                    /**
-                     * Comme la taille du support ne peut pas être forcée et
-                     * étendue pour comprendre les ombres, on place un composant
-                     * minuscule à l'extrémité de ce support.
-                     */
-
-                    gtk_graph_view_compute_requested_size(view, &right, &bottom);
-
-                    g_object_ref(G_OBJECT(view->extender));
-                    gtk_fixed_put(GTK_FIXED(view->support), view->extender, right, bottom);
-
-                    /**
-                     * Si possible, on centre le contenu obtenu.
-                     */
-
-                    gtk_widget_get_allocation(GTK_WIDGET(view), &allocation);
-
-                    gtk_graph_view_update_support_margins(view, &allocation);
-
-
-
-                }
-                while (0);
-
-
-
-                break;
-
-            }
-
-        }
-
-        change_editor_items_current_view_content(GTK_DISPLAY_PANEL(view));
-
-        g_object_unref(G_OBJECT(format));
-
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à manipuler.                            *
-*                                                                             *
-*  Description : Indique la position courante du curseur.                     *
-*                                                                             *
-*  Retour      : Emplacement courant du curseur ou NULL si aucun.             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static const vmpa2t *gtk_graph_view_get_caret_location(const GtkGraphView *view)
-{
-    return NULL;    /* FIXME */
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = composant GTK à consulter.                           *
-*                addr  = adresse à présenter à l'écran.                       *
-*                x     = position horizontale au sein du composant. [OUT]     *
-*                y     = position verticale au sein du composant. [OUT]       *
-*                tweak = adaptation finale à effectuer.                       *
-*                                                                             *
-*  Description : Indique la position d'affichage d'une adresse donnée.        *
-*                                                                             *
-*  Retour      : true si l'adresse fait partie du composant, false sinon.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, const vmpa2t *addr, gint *x, gint *y, ScrollPositionTweak tweak)
-{
-    /* TODO */
-
-    return false;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à manipuler.                            *
-*                x    = abscisse proposée pour le nouvel emplacement.         *
-*                y    = ordonnée proposée pour le nouvel emplacement.         *
-*                                                                             *
-*  Description : Déplace le curseur à un emplacement défini.                  *
-*                                                                             *
-*  Retour      : true si un traitement a été effectué, false sinon.           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool gtk_graph_view_move_caret_to(GtkGraphView *view, gint x, gint y)
-{
-    bool result;                            /* Bilan à retourner           */
-    size_t i;                               /* Boucle de parcours          */
-    GtkDisplayPanel *panel;                 /* Autre vision d'enfance      */
-    gint sub_x;                             /* Abscisse relative à l'enfant*/
-    gint sub_y;                             /* Ordonnée relative à l'enfant*/
-
-    result = false;
-
-    for (i = 0; i < view->children_count; i++)
-    {
-        if (x < view->allocs[i].x || x >= (view->allocs[i].x + view->allocs[i].width)) continue;
-        if (y < view->allocs[i].y || y >= (view->allocs[i].y + view->allocs[i].height)) continue;
-
-        panel = GTK_DISPLAY_PANEL(view->children[i]);
-
-        sub_x = x - view->allocs[i].x;
-        sub_y = y - view->allocs[i].y;
-
-        result = GTK_DISPLAY_PANEL_GET_CLASS(panel)->move_caret_to(panel, sub_x, sub_y);
-        break;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view  = composant GTK à manipuler.                           *
-*                cairo = assistant pour la création de rendus.                *
-*                area  = taille de la surface réduite à disposition.          *
-*                scale = échelle vis à vis de la taille réelle.               *
-*                                                                             *
-*  Description : Place en cache un rendu destiné à l'aperçu graphique rapide. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_cache_glance(GtkGraphView *view, cairo_t *cairo, const GtkAllocation *area, double scale)
-{
-    size_t i;                               /* Boucle de parcours          */
-    GtkAllocation sub_area;                 /* Emplacement réservé         */
-
-    for (i = 0; i < view->children_count; i++)
-    {
-        sub_area.x = view->allocs[i].x * scale;
-        sub_area.y = view->allocs[i].y * scale;
-        sub_area.width = view->allocs[i].width * scale + 1;
-        sub_area.height = view->allocs[i].height * scale + 1;
-
-        gtk_display_panel_cache_glance(GTK_DISPLAY_PANEL(view->children[i]), cairo, &sub_area, scale);
-
-    }
-
-    cairo_scale(cairo, scale, scale);
-
-    /*
-    if (view->layout != NULL)
-        g_graph_layout_draw(view->layout, cairo, false);
-    */
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée un nouveau composant pour l'affichage en graphique.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GtkWidget *gtk_graph_view_new(void)
-{
-    return g_object_new(GTK_TYPE_GRAPH_VIEW, NULL);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view   = composant GTK à mettre à jour.                      *
-*                widget = composant GTK à insérer.                            *
-*                x      = abscisse du point d'insertion.                      *
-*                y      = ordonnée du point d'insertion.                      *
-*                                                                             *
-*  Description : Place une vue sous forme de bloc dans le graphique.          *
-*                                                                             *
-*  Retour      : Plutôt que de redéfinir *toutes* les méthodes de             *
-*                GtkContainer, on étend !                                     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, const GtkAllocation *alloc)
-{
-    size_t i;                               /* Boucle de parcours          */
-    GtkWidget *parent;                      /* Parent en cas de réajustemt.*/
-
-    /*
-    for (i = 0; i < view->children_count; i++)
-        if (GTK_WIDGET(view->children[i]) == widget)
-        {
-            view->allocs[i] = *alloc;
-            break;
-        }
-
-    parent = gtk_widget_get_parent(widget);
-
-    if (parent != NULL)
-    {
-        g_object_ref(G_OBJECT(widget));
-        gtk_container_remove(GTK_CONTAINER(parent), widget);
-    }
-    */
-
-    gtk_fixed_put(GTK_FIXED(view->support), widget, alloc->x, alloc->y);
-
-    /*
-    if (parent != NULL)
-        g_object_unref(G_OBJECT(widget));
-    */
-
-}
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à mettre à jour.                        *
-*                edge = lien entre noeuds à conserver.                        *
-*                                                                             *
-*  Description : Intègre un lien entre blocs graphiques dans l'afficheur.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void gtk_graph_view_add_edge(GtkGraphView *view, GGraphEdge *edge)
-{
-    view->edges = (GGraphEdge **)realloc(view->edges,
-                                         ++view->edges_count * sizeof(GGraphEdge *));
-
-    view->edges[view->edges_count - 1] = edge;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = instance GTK à réinitialiser.                         *
-*                                                                             *
-*  Description : Supprime tout contenu de l'afficheur de code en graphique.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_reset(GtkGraphView *view)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-
-    void detach_all_blocks(GtkWidget *widget, GtkContainer *container)
-    {
-
-
-
-        gtk_container_remove(container, widget);
-
-
-    }
-
-
-    gtk_container_foreach(GTK_CONTAINER(view->support), (GtkCallback)detach_all_blocks, view->support);
-
-
-    if (view->cluster != NULL)
-    {
-        g_object_unref(G_OBJECT(view->cluster));
-        view->cluster = NULL;
-    }
-
-    for (i = 0; i < view->edges_count; i++)
-        g_object_unref(G_OBJECT(view->edges[i]));
-
-    if (view->edges_count > 0)
-    {
-        free(view->edges);
-        view->edges = NULL;
-
-        view->edges_count = 0;
-
-    }
-
-
-    /*
-    for (i = 0; i < view->links_count; i++)
-        gtk_object_destroy(GTK_OBJECT(view->links[i]));
-
-    if (view->links_count > 0)
-    {
-        free(view->links);
-        view->links = NULL;
-
-        view->links_count = 0;
-
-    }
-    */
-
-    if (view->highlighted)
-        exit_segment_content_list(view->highlighted);
-
-    for (i = 0; i < view->children_count; i++)
-    {
-        g_signal_handlers_disconnect_by_func(view->children[i], gtk_graph_view_reach_caret_limit, view);
-        gtk_widget_destroy(GTK_WIDGET(view->children[i]));
-    }
-
-    if (view->children_count > 0)
-    {
-        free(view->children);
-        view->children = NULL;
-        free(view->allocs);
-        view->allocs = NULL;
-
-        view->children_count = 0;
-
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view    = composant d'affichage GTK à mettre à jour.         *
-*                routine = routine à présenter via ledit composant.           *
-*                                                                             *
-*  Description : Définit la liste complète des éléments du futur graphique.   *
-*                                                                             *
-*  Retour      : Liste d'éléments du graphique à placer.                      *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinary *binary, const GBinRoutine *routine)
-{
-    GtkBufferView **result;                 /* Liste à retourner           */
-    GCodeBuffer *buffer;                    /* Tampon brut à découper      */
-    size_t *count;                          /* Nombre d'éléments créés.    */
-    GInstrBlock *main_block;                /* Premier bloc rattaché       */
-    GInstrBlock **blocks;                   /* Liste des blocs basiques    */
-    size_t i;                               /* Boucle de parcours          */
-    vmpa2t first;                           /* Début d'un groupe de lignes */
-    vmpa2t last;                            /* Fin d'un groupe de lignes   */
-    GBufferView *subview;                   /* Partie affichée du tampon   */
-
-    buffer = g_loaded_binary_get_disassembled_buffer(binary);
-
-    count = &view->children_count;
-
-    main_block = g_binary_routine_get_basic_blocks(routine);
-
-    blocks = NULL;
-    *count = 0;
-    g_instr_block_list_all_blocks(main_block, &blocks, count);
-
-    result = (GtkBufferView **)calloc(*count, sizeof(GtkBufferView *));
-
-    for (i = 0; i < *count; i++)
-    {
-        result[i] = GTK_BUFFER_VIEW(gtk_block_view_new());
-        g_signal_connect(result[i], "reach-limit", G_CALLBACK(gtk_graph_view_reach_caret_limit), view);
-        g_signal_connect(result[i], "highlight-changed", G_CALLBACK(gtk_graph_view_changed_highlights), view);
-
-        gtk_widget_show(GTK_WIDGET(result[i]));
-        gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result[i]), binary, BVW_GRAPH);
-
-        gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result[i]), true);
-
-        g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(blocks[i]), &first, &last);
-
-        subview = g_buffer_view_new(buffer, view->highlighted);
-        g_buffer_view_restrict(subview, &first, &last);
-        gtk_buffer_view_attach_buffer(result[i], subview);
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : node = composant d'affichage GTK impliqué dans la procédure. *
-*                view = support graphique de tous les noeuds.                 *
-*                                                                             *
-*  Description : Notifie un changement de surbrillance au sein d'un noeud.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_changed_highlights(GtkBlockView *node, GtkGraphView *view)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    for (i = 0; i < view->children_count; i++)
-    {
-        if (view->children[i] == GTK_BUFFER_VIEW(node))
-            continue;
-
-        gtk_widget_queue_draw(GTK_WIDGET(view->children[i]));
-
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : node = composant d'affichage GTK impliqué dans la procédure. *
-*                dir  = direction du déplacement souhaité et impossible.      *
-*                view = support graphique de tous les noeuds.                 *
-*                                                                             *
-*  Description : Notifie une incapacité de déplacement au sein d'un noeud.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirection dir, GtkGraphView *view)
-{
-    GBufferView *bview;                     /* Vue d'un tampon global      */
-    vmpa2t first;                           /* Début d'un groupe de lignes */
-    vmpa2t last;                            /* Fin d'un groupe de lignes   */
-    const mrange_t *range;                  /* Couverture courante         */
-    GArchProcessor *proc;                   /* Processeur pour instructions*/
-    vmpa2t iaddr;                           /* Adresse du prochain saut    */
-    instr_iter_t *iter;                     /* Boucle de parcours          */
-    GArchInstruction *instr;                /* Instruction à venir visiter */
-#ifndef NDEBUG
-    bool is_return;                         /* Est-ce une instruc. finale ?*/
-#endif
-    size_t i;                               /* Boucle de parcours          */
-    bool updated;                           /* Besoin d'une mise à jour ?  */
-
-    /* Détermination de l'instruction à cibler */
-
-    bview = gtk_buffer_view_get_buffer(node);
-    g_buffer_view_get_restrictions(bview, &first, &last);
-
-    range = g_binary_routine_get_range(view->routine);
-
-    proc = g_loaded_binary_get_processor(GTK_DISPLAY_PANEL(view)->binary);
-
-    init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
-
-#ifndef NDEBUG
-    is_return = false;
-#endif
-
-    switch (dir)
-    {
-        case GDK_SCROLL_LEFT:
-        case GDK_SCROLL_UP:
-
-            if (cmp_vmpa(get_mrange_addr(range), &first) != 0)
-            {
-                iter = g_arch_processor_get_iter_from_address(proc, &first);
-
-                if (iter != NULL)
-                {
-                    instr = get_instruction_iterator_prev(iter);
-
-                    if (instr != NULL)
-                    {
-                        /* TODO : boucler si !HAS_CODE */
-
-                        if (mrange_contains_addr(range, &iaddr))
-                            copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(instr)));
-
-                        g_object_unref(G_OBJECT(instr));
-
-                    }
-
-                    delete_instruction_iterator(iter);
-
-                }
-
-            }
-
-            break;
-
-        case GDK_SCROLL_RIGHT:
-        case GDK_SCROLL_DOWN:
-
-            iter = g_arch_processor_get_iter_from_address(proc, &last);
-
-            if (iter != NULL)
-            {
-#ifndef NDEBUG
-                instr = get_instruction_iterator_current(iter);
-                if (instr != NULL)
-                {
-                    is_return = (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT);
-                    g_object_unref(G_OBJECT(instr));
-                }
-#endif
-
-                instr = get_instruction_iterator_next(iter);
-
-                if (instr != NULL)
-                {
-                    /* TODO : boucler si !HAS_CODE */
-
-                    copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(instr)));
-
-                    if (!mrange_contains_addr(range, &iaddr))
-                        init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
-
-                    g_object_unref(G_OBJECT(instr));
-
-                }
-
-                delete_instruction_iterator(iter);
-
-            }
-
-            break;
-
-        case GDK_SCROLL_SMOOTH:
-            assert(0);  /* Argument jamais généré */
-            break;
-
-    }
-
-    g_object_unref(G_OBJECT(proc));
-
-    /* Recherche du bloc parent */
-
-    /* FIXME : valid ! */
-    if (iaddr.physical == VMPA_NO_PHYSICAL && iaddr.virtual == VMPA_NO_VIRTUAL)
-        return;
-
-    for (i = 0; i < view->children_count; i++)
-    {
-        bview = gtk_buffer_view_get_buffer(view->children[i]);
-        g_buffer_view_get_restrictions(bview, &first, &last);
-
-        if (cmp_vmpa(&first, &iaddr) <= 0 && cmp_vmpa(&iaddr, &last) <= 0)
-        {
-            assert(node != view->children[i]);
-            break;
-        }
-
-    }
-
-    assert(i < view->children_count || is_return);
-
-    /* Affichage du nouveau curseur */
-
-    /**
-     * Il se peut qu'aucune adresse suivante ne soit disponible : c'est typiquement
-     * le cas sous ARM, avec les valeurs brutes référencées dans le code. Ces valeurs
-     * sont incluses dans la surface couverte par la routine concernée, mais ne sont
-     * pas intégrées dans les blocs basiques associés.
-     */
-
-    if (i == view->children_count)
-        return;
-
-    gtk_widget_grab_focus(GTK_WIDGET(view->children[i]));
-
-    switch (dir)
-    {
-        case GDK_SCROLL_LEFT:
-            updated = gtk_buffer_view_move_caret_to(view->children[i], false, NULL);
-            break;
-
-        case GDK_SCROLL_UP:
-            break;
-
-        case GDK_SCROLL_RIGHT:
-            updated = gtk_buffer_view_move_caret_to(view->children[i], true, NULL);
-            break;
-
-        case GDK_SCROLL_DOWN:
-            break;
-
-        case GDK_SCROLL_SMOOTH:
-            assert(0);  /* Argument jamais généré */
-            break;
-
-    }
-
-    /* TODO : scrolling... */
-
-}
diff --git a/src/gtkext/gtkgraphview.h b/src/gtkext/gtkgraphview.h
deleted file mode 100644
index eb3e6ad..0000000
--- a/src/gtkext/gtkgraphview.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtkgraphview.h - prototypes pour l'affichage de morceaux de code sous forme graphique
- *
- * Copyright (C) 2009-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 _GTKEXT_GTKGRAPHVIEW_H
-#define _GTKEXT_GTKGRAPHVIEW_H
-
-
-#include <gtk/gtk.h>
-
-
-#include "graph/edge.h"
-
-
-
-#define GTK_TYPE_GRAPH_VIEW                  (gtk_graph_view_get_type())
-#define GTK_GRAPH_VIEW(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_GRAPH_VIEW, GtkGraphView))
-#define GTK_GRAPH_VIEW_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_GRAPH_VIEW, GtkGraphViewClass))
-#define GTK_IS_GRAPH_VIEW(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_GRAPH_VIEW))
-#define GTK_IS_GRAPH_VIEW_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_GRAPH_VIEW))
-#define GTK_GRAPH_VIEW_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_GRAPH_VIEW, GtkGraphViewClass))
-
-
-/* Composant d'affichage sous forme graphique (instance) */
-typedef struct _GtkGraphView GtkGraphView;
-
-/* Composant d'affichage sous forme graphique (classe) */
-typedef struct _GtkGraphViewClass GtkGraphViewClass;
-
-
-/* Détermine le type du composant d'affichage en graphique. */
-GType gtk_graph_view_get_type(void);
-
-/* Crée un nouveau composant pour l'affichage en graphique. */
-GtkWidget *gtk_graph_view_new(void);
-
-/* Place une vue sous forme de bloc dans le graphique. */
-void gtk_graph_view_put(GtkGraphView *, GtkWidget *, const GtkAllocation *);
-
-/* Intègre un lien entre blocs graphiques dans l'afficheur. */
-void gtk_graph_view_add_edge(GtkGraphView *, GGraphEdge *);
-
-
-
-#endif  /* _GTKEXT_GTKGRAPHVIEW_H */
diff --git a/src/gtkext/gtksourceview.c b/src/gtkext/gtksourceview.c
deleted file mode 100644
index 0d2670b..0000000
--- a/src/gtkext/gtksourceview.c
+++ /dev/null
@@ -1,156 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtksourceview.c - affichage de code source
- *
- * Copyright (C) 2010-2012 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 "gtksourceview.h"
-
-
-#include "gtkbufferview-int.h"
-
-
-
-/* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */
-
-
-/* Composant d'affichage de code source (instance) */
-struct _GtkSourceView
-{
-    GtkBufferView parent;                   /* A laisser en premier        */
-
-};
-
-/* Composant d'affichage de code source (classe) */
-struct _GtkSourceViewClass
-{
-    GtkBufferViewClass parent;              /* A laisser en premier        */
-
-};
-
-
-/* Procède à l'initialisation de l'afficheur de code source. */
-static void gtk_source_view_class_init(GtkSourceViewClass *);
-
-/* Procède à l'initialisation de l'afficheur de code source. */
-static void gtk_source_view_init(GtkSourceView *);
-
-/* Prend acte de l'association d'un binaire chargé. */
-static void gtk_source_view_attach_binary(GtkSourceView *, GLoadedBinary *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            INTERACTION DIRECTE AVEC GTK                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Détermine le type du composant d'affichage de code source. */
-G_DEFINE_TYPE(GtkSourceView, gtk_source_view, GTK_TYPE_BUFFER_VIEW)
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : class = classe GTK à initialiser.                            *
-*                                                                             *
-*  Description : Procède à l'initialisation de l'afficheur de code source.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_source_view_class_init(GtkSourceViewClass *class)
-{
-    GtkDisplayPanelClass *panel_class;      /* Classe parente              */
-
-    panel_class = GTK_DISPLAY_PANEL_CLASS(class);
-
-    panel_class->attach = (attach_binary_fc)gtk_source_view_attach_binary;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view = composant GTK à initialiser.                          *
-*                                                                             *
-*  Description : Procède à l'initialisation de l'afficheur de code source.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_source_view_init(GtkSourceView *view)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée un nouveau composant pour l'affichage de code source.   *
-*                                                                             *
-*  Retour      : Composant GTK créé.                                          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GtkWidget *gtk_source_view_new(void)
-{
-    GtkSourceView *result;                  /* Composant à retourner       */
-
-    result = g_object_new(GTK_TYPE_SOURCE_VIEW, NULL);
-
-    return GTK_WIDGET(result);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : view   = composant GTK à mettre à jour.                      *
-*                binary = binaire associé à intégrer.                         *
-*                                                                             *
-*  Description : Prend acte de l'association d'un binaire chargé.             *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_source_view_attach_binary(GtkSourceView *view, GLoadedBinary *binary)
-{
-    GCodeBuffer *buffer;                    /* Tampon par défaut           */
-
-    buffer = g_loaded_binary_get_decompiled_buffer(binary, -1);
-
-    /* Si une source existe... */
-    if (buffer != NULL)
-        gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), g_buffer_view_new(buffer, NULL));
-
-}
diff --git a/src/gtkext/gtksourceview.h b/src/gtkext/gtksourceview.h
deleted file mode 100644
index 3e4c7c6..0000000
--- a/src/gtkext/gtksourceview.h
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gtksourceview.h - prototypes pour l'affichage de code source
- *
- * Copyright (C) 2010-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide 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 _GTK_SOURCEVIEW_H
-#define _GTK_SOURCEVIEW_H
-
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-
-
-#define GTK_TYPE_SOURCE_VIEW                  (gtk_source_view_get_type())
-#define GTK_SOURCE_VIEW(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_SOURCE_VIEW, GtkSourceView))
-#define GTK_SOURCE_VIEW_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_SOURCE_VIEW, GtkSourceViewClass))
-#define GTK_IS_SOURCE_VIEW(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_SOURCE_VIEW))
-#define GTK_IS_SOURCE_VIEW_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_SOURCE_VIEW))
-#define GTK_SOURCE_VIEW_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_SOURCE_VIEW, GtkSourceViewClass))
-
-
-/* Composant d'affichage de code source (instance) */
-typedef struct _GtkSourceView GtkSourceView;
-
-/* Composant d'affichage de code source (classe) */
-typedef struct _GtkSourceViewClass GtkSourceViewClass;
-
-
-/* Détermine le type du composant d'affichage de code source. */
-GType gtk_source_view_get_type(void);
-
-/* Crée un nouveau composant pour l'affichage de code source. */
-GtkWidget *gtk_source_view_new(void);
-
-
-
-#endif  /* _GTK_SOURCEVIEW_H */
diff --git a/src/gui/dialogs/export.c b/src/gui/dialogs/export.c
index c16e7d8..b39a5c1 100644
--- a/src/gui/dialogs/export.c
+++ b/src/gui/dialogs/export.c
@@ -49,7 +49,7 @@ static void export_assistant_cancel(GtkAssistant *, gpointer);
 static void export_assistant_close(GtkAssistant *, GObject *);
 
 /* Réalise l'exportation d'un contenu binaire comme demandé. */
-static void do_binary_export(GCodeBuffer *, const vmpa2t *, const vmpa2t *, buffer_export_context *, BufferExportType, const bool *);
+static void do_binary_export(void/*GCodeBuffer*/ *, const vmpa2t *, const vmpa2t *, buffer_export_context *, BufferExportType, const bool *);
 
 
 
@@ -181,6 +181,8 @@ static void export_assistant_cancel(GtkAssistant *assistant, gpointer data)
 
 static void export_assistant_close(GtkAssistant *assistant, GObject *ref)
 {
+#if 0
+
     GtkComboBox *combo;                     /* Selection du format         */
     BufferExportType type;                  /* Type d'exportation requise  */
     buffer_export_context ctx;              /* Contexte à constituer       */
@@ -283,7 +285,7 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref)
 
     support = G_OBJECT(g_object_get_data(G_OBJECT(assistant), "html_options"));
     if (support != NULL) g_object_unref(support);
-
+#endif
     gtk_widget_destroy(GTK_WIDGET(assistant));
 
 }
@@ -306,8 +308,9 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref)
 *                                                                             *
 ******************************************************************************/
 
-static void do_binary_export(GCodeBuffer *buffer, const vmpa2t *start, const vmpa2t *end, buffer_export_context *ctx, BufferExportType type, const bool *display)
+static void do_binary_export(void/*GCodeBuffer*/ *buffer, const vmpa2t *start, const vmpa2t *end, buffer_export_context *ctx, BufferExportType type, const bool *display)
 {
+#if 0
     typedef struct _export_data
     {
         buffer_export_context *ctx;         /* Contexte d'exportation      */
@@ -373,7 +376,7 @@ static void do_binary_export(GCodeBuffer *buffer, const vmpa2t *start, const vmp
         default:
             break;
     }
-
+#endif
 }
 
 
diff --git a/src/gui/dialogs/gotox.c b/src/gui/dialogs/gotox.c
index 872cd4f..abd9377 100644
--- a/src/gui/dialogs/gotox.c
+++ b/src/gui/dialogs/gotox.c
@@ -342,6 +342,7 @@ GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *parent, GLoadedBi
 
 static void add_new_location_to_list(GtkTreeStore *store, GLoadedBinary *binary, const vmpa2t *addr, GBinSymbol *hint)
 {
+#if 0
     GCodeBuffer *buffer;                    /* Tampon de désassemblage     */
     GBufferLine *line;                      /* Ligne présente à l'adresse  */
     char *virtual;                          /* Transcription d'adresse     */
@@ -465,7 +466,7 @@ static void add_new_location_to_list(GtkTreeStore *store, GLoadedBinary *binary,
 
     if (line != NULL)
         g_object_unref(G_OBJECT(line));
-
+#endif
 }
 
 
diff --git a/src/gui/editem-int.h b/src/gui/editem-int.h
index 919e8ae..f77cf99 100644
--- a/src/gui/editem-int.h
+++ b/src/gui/editem-int.h
@@ -33,7 +33,6 @@
 
 
 #include "../common/dllist.h"
-#include "../gtkext/gtkbufferview.h"
 #include "../gtkext/gtkdisplaypanel.h"
 
 
diff --git a/src/gui/editem.c b/src/gui/editem.c
index fc502a0..0ec2d72 100644
--- a/src/gui/editem.c
+++ b/src/gui/editem.c
@@ -27,7 +27,6 @@
 
 #include "editem-int.h"
 #include "../analysis/db/items/move.h"
-#include "../gtkext/gtkblockview.h"
 
 
 
@@ -250,10 +249,14 @@ void change_editor_items_current_binary(GObject *ref, GLoadedBinary *binary)
     GEditorItem *iter;                      /* Boucle de parcours          */
     GEditorItemClass *klass;                /* Classe correspondante       */
 
-    if (binary != NULL)
-        g_object_ref(G_OBJECT(binary));
+    if (binary == NULL)
+        g_object_set_data(ref, "current_binary", NULL);
 
-    g_object_set_data_full(ref, "current_binary", binary, g_object_unref);
+    else
+    {
+        g_object_ref(G_OBJECT(binary));
+        g_object_set_data_full(ref, "current_binary", binary, g_object_unref);
+    }
 
     editem_list_for_each(iter, _editem_list)
     {
diff --git a/src/gui/editor.c b/src/gui/editor.c
index f8922a1..7322ed7 100644
--- a/src/gui/editor.c
+++ b/src/gui/editor.c
@@ -41,7 +41,6 @@
 #include "panels/panel.h"
 #include "panels/welcome.h"
 #include "tb/portions.h"
-#include "tb/source.h"
 #include "../analysis/project.h"
 #include "../common/extstr.h"
 #include "../core/params.h"
@@ -481,9 +480,6 @@ static GtkWidget *build_editor_toolbar(GObject *ref)
     g_object_set_data(ref, "toolbar", result);
 
 
-    item = create_source_tb_item(ref);
-    register_editor_item(item);
-
     item = create_portions_tb_item(ref);
     register_editor_item(item);
 
@@ -1097,7 +1093,7 @@ void on_panel_item_dock_request(GPanelItem *panel, void *unused)
                 if (!g_welcome_panel_get_user_origin(G_WELCOME_PANEL(welcome)))
                 {
                     /* Equivalent d'un appel "g_panel_item_undock(welcome)", avec effet immédiat */
-                    on_panel_item_undock_request(welcome, NULL);
+                    /////on_panel_item_undock_request(welcome, NULL);
                 }
 
             }
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index 89b5fe9..d5ef541 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -37,7 +37,6 @@
 #include "../../analysis/db/items/switcher.h"
 #include "../../arch/target.h"
 #include "../../gtkext/easygtk.h"
-#include "../../gtkext/gtkbufferview.h"
 
 
 
diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c
index 9447724..2b3f37e 100644
--- a/src/gui/menus/view.c
+++ b/src/gui/menus/view.c
@@ -25,6 +25,9 @@
 #include "view.h"
 
 
+#include <assert.h>
+
+
 #include <i18n.h>
 
 
@@ -32,6 +35,8 @@
 #include "../core/panels.h"
 #include "../../analysis/project.h"
 #include "../../gtkext/easygtk.h"
+#include "../../gtkext/gtkblockdisplay.h"
+#include "../../gtkext/gtkgraphdisplay.h"
 
 
 
@@ -100,6 +105,7 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
                                              G_CALLBACK(mcb_view_change_support), bar);
     add_accelerator_to_menu_item(submenuitem, "F3", accgroup);
     g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_BLOCK));
+    g_object_set_data(G_OBJECT(submenuitem), "kind_of_display", GSIZE_TO_POINTER(GTK_TYPE_BLOCK_DISPLAY));
     gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
     rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem));
@@ -108,14 +114,7 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
                                              G_CALLBACK(mcb_view_change_support), bar);
     add_accelerator_to_menu_item(submenuitem, "F4", accgroup);
     g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_GRAPH));
-    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
-    rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem));
-
-    submenuitem = qck_create_radio_menu_item(ref, "mnu_view_switch_sourceview", rgroup, _("Source code"),
-                                             G_CALLBACK(mcb_view_change_support), bar);
-    add_accelerator_to_menu_item(submenuitem, "F5", accgroup);
-    g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_SOURCE));
+    g_object_set_data(G_OBJECT(submenuitem), "kind_of_display", GSIZE_TO_POINTER(GTK_TYPE_GRAPH_DISPLAY));
     gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
     /* - */
@@ -174,6 +173,9 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
 void update_menu_view_for_view(GtkWidget *widget, GtkDisplayPanel *panel, GMenuBar *bar)
 {
     GObject *ref;                           /* Espace de référencements    */
+    GtkRadioMenuItem *item;                 /* Elément de menu arbitraire  */
+    GSList *radios;                         /* Liste des menus d'affichage */
+    GSList *found;                          /* Elément de menu à activer   */
     GLoadedBinary *binary;                  /* Binaire courant             */
     BinaryView content;                     /* Type de vue active          */
     const bool *display;                    /* Règles d'affichage courantes*/
@@ -182,6 +184,49 @@ void update_menu_view_for_view(GtkWidget *widget, GtkDisplayPanel *panel, GMenuB
 
     ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar));
 
+    /* Types de panneau de code */
+
+    item = GTK_RADIO_MENU_ITEM(g_object_get_data(ref, "mnu_view_switch_graphview"));
+
+    radios = gtk_radio_menu_item_get_group(item);
+
+    void disconnect_display_radio(GtkWidget *wgt, gpointer unused)
+    {
+        g_signal_handlers_disconnect_by_func(wgt, G_CALLBACK(mcb_view_change_support), bar);
+
+    }
+
+    g_slist_foreach(radios, (GFunc)disconnect_display_radio, NULL);
+
+    gint find_suitable_display_radio(GObject *rdo, GObject *pnl)
+    {
+        GType rdo_type;                     /* Type d'affichage supporté   */
+        GType pnl_type;                     /* Type du panneau affiché     */
+
+        rdo_type = GPOINTER_TO_SIZE(g_object_get_data(rdo, "kind_of_display"));
+
+        pnl_type = G_OBJECT_TYPE(pnl);
+
+        return (rdo_type == pnl_type ? 0 : -1);
+
+    }
+
+    found = g_slist_find_custom(radios, G_OBJECT(panel), (GCompareFunc)find_suitable_display_radio);
+
+    assert(found != NULL);
+
+    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(found->data), TRUE);
+
+    void reconnect_display_radio(GtkWidget *wgt, gpointer unused)
+    {
+        g_signal_connect(wgt, "toggled", G_CALLBACK(mcb_view_change_support), bar);
+
+    }
+
+    g_slist_foreach(radios, (GFunc)reconnect_display_radio, NULL);
+
+    /* - */
+
     binary = g_editor_item_get_current_binary(G_EDITOR_ITEM(bar));
 
     content = gtk_display_panel_describe_content(panel);
@@ -246,17 +291,6 @@ void update_access_in_menu_view(GObject *ref, GtkDisplayPanel *panel)
 
     access = (panel != NULL);
 
-    /* Types de panneau de code */
-
-    item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_textview"));
-    gtk_widget_set_sensitive(item, access);
-
-    item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_graphview"));
-    gtk_widget_set_sensitive(item, access);
-
-    item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_sourceview"));
-    gtk_widget_set_sensitive(item, access);
-
     /* Affichage des données */
 
     item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_display_off"));
@@ -450,7 +484,8 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, GMenuBar *bar)
         station = get_dock_station_for_view_panel(panel);
 
         /* En vue du retrait de la station d'accueil... */
-        g_object_ref(G_OBJECT(panel));
+        scroll = get_scroll_window_for_view_panel(panel);
+        g_object_ref(G_OBJECT(scroll));
 
         panel = get_alt_view_for_view_panel(panel, wanted);
         scroll = get_scroll_window_for_view_panel(panel);
diff --git a/src/gui/status.c b/src/gui/status.c
index fc8eafd..daa5f91 100644
--- a/src/gui/status.c
+++ b/src/gui/status.c
@@ -36,8 +36,7 @@
 #include "editem-int.h"
 #include "core/global.h"
 #include "../common/extstr.h"
-#include "../gtkext/gtkbufferview.h"
-#include "../gtkext/gtkblockview.h"
+#include "../gtkext/gtkbufferdisplay.h"
 #include "../gtkext/gtkstatusstack.h"
 
 
@@ -71,7 +70,7 @@ static void g_status_info_dispose(GStatusInfo *);
 static void g_status_info_finalize(GStatusInfo *);
 
 /* Imprime la position du parcours courant dans le statut. */
-static void track_caret_address_for_status_info(GStatusInfo *, GtkBufferView *, const vmpa2t *);
+static void track_caret_address_for_status_info(GStatusInfo *, GtkBufferDisplay *, const vmpa2t *);
 
 /* Concentre l'attention de l'ensemble sur une adresse donnée. */
 static void focus_address_in_status_info(GStatusInfo *, GLoadedBinary *, const vmpa2t *);
@@ -209,9 +208,9 @@ GEditorItem *g_status_info_new(GObject *ref)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : info = barre de statut présentant les informations.          *
-*                view = composant d'affichage parcouru.                       *
-*                addr = nouvelle adresse du curseur courant.                  *
+*  Paramètres  : info    = barre de statut présentant les informations.       *
+*                display = composant d'affichage parcouru.                    *
+*                addr    = nouvelle adresse du curseur courant.               *
 *                                                                             *
 *  Description : Imprime la position du parcours courant dans le statut.      *
 *                                                                             *
@@ -221,7 +220,7 @@ GEditorItem *g_status_info_new(GObject *ref)
 *                                                                             *
 ******************************************************************************/
 
-static void track_caret_address_for_status_info(GStatusInfo *info, GtkBufferView *view, const vmpa2t *addr)
+static void track_caret_address_for_status_info(GStatusInfo *info, GtkBufferDisplay *display, const vmpa2t *addr)
 {
     GEditorItem *item;                      /* Autre version de l'élément  */
     GLoadedBinary *binary;                  /* Binaire courant             */
@@ -257,7 +256,7 @@ static void focus_address_in_status_info(GStatusInfo *info, GLoadedBinary *binar
 
     item = G_EDITOR_ITEM(info);
 
-    if (addr == NULL)
+    if (is_invalid_vmpa(addr))
         gtk_status_stack_reset_current_instruction(GTK_STATUS_STACK(item->widget));
 
     else
diff --git a/src/gui/tb/Makefile.am b/src/gui/tb/Makefile.am
index 60aa031..b8559f7 100644
--- a/src/gui/tb/Makefile.am
+++ b/src/gui/tb/Makefile.am
@@ -3,7 +3,6 @@ noinst_LTLIBRARIES  = libguitb.la
 
 libguitb_la_SOURCES =					\
 	portions.h portions.c				\
-	source.h source.c					\
 	tbitem-int.h						\
 	tbitem.h tbitem.c
 
diff --git a/src/gui/tb/source.c b/src/gui/tb/source.c
deleted file mode 100644
index 504c532..0000000
--- a/src/gui/tb/source.c
+++ /dev/null
@@ -1,321 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * source.c - sélection du fichier ciblé lors d'une décompilation
- *
- * Copyright (C) 2010-2013 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "source.h"
-
-
-#include <i18n.h>
-
-
-#include "tbitem-int.h"
-#include "../../format/format.h"
-#include "../../gtkext/easygtk.h"
-#include "../../gtkext/gtkbufferview.h"
-#include "../../gtkext/gtksourceview.h"
-
-
-
-/* Elément réactif listant les fichiers décompilés (instance) */
-struct _GSourceTbItem
-{
-    GToolbarItem parent;                    /* A laisser en premier        */
-
-};
-
-
-/* Elément réactif listant les fichiers décompilés (classe) */
-struct _GSourceTbItemClass
-{
-    GToolbarItemClass parent;               /* A laisser en premier        */
-
-};
-
-
-
-/* Initialise la classe des éléments réactifs de l'éditeur. */
-static void g_source_tbitem_class_init(GSourceTbItemClass *);
-
-/* Initialise une instance d'élément réactif pour l'éditeur. */
-static void g_source_tbitem_init(GSourceTbItem *);
-
-/* Supprime toutes les références externes. */
-static void g_source_tbitem_dispose(GSourceTbItem *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_source_tbitem_finalize(GSourceTbItem *);
-
-/* Réagit à un changement du binaire courant. */
-static void update_source_item_binary(GEditorItem *, GLoadedBinary *);
-
-/* Réagit à un changement de panneau d'affichage courant. */
-static void update_source_item_view(GEditorItem *, GtkDisplayPanel *);
-
-/* Réagit à un changement de sélection de la source courante. */
-static void change_selected_source(GtkComboBox *, GSourceTbItem *);
-
-
-
-/* Indique le type défini pour une liste de fichiers destinée à une barre d'outils. */
-G_DEFINE_TYPE(GSourceTbItem, g_source_tbitem, G_TYPE_TOOLBAR_ITEM);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des éléments réactifs de l'éditeur.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_source_tbitem_class_init(GSourceTbItemClass *klass)
-{
-    GObjectClass *object;                   /* Autre version de la classe  */
-    GEditorItemClass *item;                 /* Encore une autre vision     */
-
-    object = G_OBJECT_CLASS(klass);
-    item = G_EDITOR_ITEM_CLASS(klass);
-
-    object->dispose = (GObjectFinalizeFunc/* ! */)g_source_tbitem_dispose;
-    object->finalize = (GObjectFinalizeFunc)g_source_tbitem_finalize;
-
-    item->update_binary = update_source_item_binary;
-    item->update_view = update_source_item_view;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : item = instance à initialiser.                               *
-*                                                                             *
-*  Description : Initialise une instance d'élément réactif pour l'éditeur.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_source_tbitem_init(GSourceTbItem *item)
-{
-    GtkWidget *widget;                      /* Composant principal         */
-    GtkWidget *hbox;                        /* Support interne             */
-    GtkWidget *label;                       /* Etiquette d'introduction    */
-    GtkWidget *comboboxentry;               /* Liste de fichiers           */
-
-    widget = GTK_WIDGET(gtk_tool_item_new());
-    gtk_widget_show(widget);
-
-    G_EDITOR_ITEM(item)->widget = widget;
-
-    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
-    gtk_widget_show(hbox);
-    gtk_container_add(GTK_CONTAINER(widget), hbox);
-
-    label = qck_create_label(G_OBJECT(widget), "label", _(" Source: "));
-    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
-    comboboxentry = qck_create_combobox2(G_OBJECT(widget), "combo",
-                                        G_CALLBACK(change_selected_source), item);
-    gtk_box_pack_start(GTK_BOX(hbox), comboboxentry, TRUE, TRUE, 0);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : item = instance d'objet GLib à traiter.                      *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_source_tbitem_dispose(GSourceTbItem *item)
-{
-    G_OBJECT_CLASS(g_source_tbitem_parent_class)->dispose(G_OBJECT(item));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : item = instance d'objet GLib à traiter.                      *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_source_tbitem_finalize(GSourceTbItem *item)
-{
-    G_OBJECT_CLASS(g_source_tbitem_parent_class)->finalize(G_OBJECT(item));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : ref = espace de référencement global.                        *
-*                                                                             *
-*  Description : Crée un élément réactif présentant des source de binaire.  *
-*                                                                             *
-*  Retour      : Adresse de la structure d'encadrement mise en place.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GEditorItem *create_source_tb_item(GObject *ref)
-{
-    GSourceTbItem *result;                /* Structure à retourner       */
-
-    result = g_object_new(G_TYPE_SOURCE_TBITEM, NULL);
-
-    return g_toolbar_item_setup(G_TOOLBAR_ITEM(result), ref, "source", _("Source files"));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : item   = élément réactif sollicité.                          *
-*                binary = binaire chargé nouvellement affiché.                *
-*                                                                             *
-*  Description : Réagit à un changement du binaire courant.                   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void update_source_item_binary(GEditorItem *item, GLoadedBinary *binary)
-{
-#if 0
-    GtkComboBoxText *combo;                 /* Liste de sélection          */
-    GtkTreeModel *model;                    /* Gestionnaire d'éléments     */
-    GtkTreeIter iter;                       /* Boucle de parcours #2       */
-    GExeFormat *format;                     /* Format d'exécutable associé */
-    size_t count;                           /* Quantité de fichiers        */
-    size_t defsrc;                          /* Fichier source principal    */
-    const char * const *files;              /* Liste de fichiers source    */
-    size_t i;                               /* Boucle de parcours #2       */
-
-    combo = GTK_COMBO_BOX_TEXT(g_object_get_data(G_OBJECT(item->widget), "combo"));
-
-    /* Réinitialisation */
-
-    g_signal_handlers_block_by_func(combo, G_CALLBACK(change_selected_source), item);
-
-    /* FIXME : 3.0 */
-    //gtk_combo_box_text_remove_all(combo);
-
-    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
-
-    while (gtk_tree_model_get_iter_first(model, &iter))
-        gtk_combo_box_text_remove(combo, 0);
-
-    /* Inscriptions */
-
-    format = g_loaded_binary_get_format(binary);
-    files = g_binary_format_get_source_files(G_BIN_FORMAT(format), &count, &defsrc);
-
-    for (i = 0; i < count; i++)
-        gtk_combo_box_text_append_text(combo, files[i]);
-
-    /* Réactivation */
-
-    g_signal_handlers_unblock_by_func(combo, G_CALLBACK(change_selected_source), item);
-
-    //gtk_combo_box_set_active(combo, defsrc);
-
-    g_object_unref(G_OBJECT(format));
-
-#endif
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : item  = élément réactif sollicité.                           *
-*                panel = nouveau panneau d'affichage actif.                   *
-*                                                                             *
-*  Description : Réagit à un changement de panneau d'affichage courant.       *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void update_source_item_view(GEditorItem *item, GtkDisplayPanel *panel)
-{
-    gtk_widget_set_sensitive(item->widget, GTK_IS_SOURCE_VIEW(panel));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : widget = composant GTK en cause.                             *
-*                item   = élément réactif associé.                            *
-*                                                                             *
-*  Description : Réagit à un changement de sélection de la source courante.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void change_selected_source(GtkComboBox *widget, GSourceTbItem *item)
-{
-#if 0
-    gint index;                             /* Nouvelle source ciblée      */
-    GLoadedBinary *binary;                  /* Binaire chargé courant      */
-    GCodeBuffer *buffer;                    /* Nouveau tampon à présenter  */
-    GtkBufferView *view;                    /* Afficheur de tampons        */
-
-    index = gtk_combo_box_get_active(widget);
-
-    binary = G_LOADED_BINARY(g_object_get_data(ref, "current_binary"));
-    buffer = g_loaded_binary_get_decompiled_buffer(binary, index);
-
-    view = GTK_BUFFER_VIEW(g_object_get_data(ref, /*"current_view"*/)); /* TODO : utiliser g_editor_item_get_current_view() */
-    if (GTK_IS_BUFFER_VIEW(view))
-        gtk_buffer_view_attach_buffer(view, buffer,
-                                      g_loaded_binary_display_decomp_lines(binary), NULL);
-#endif
-}
diff --git a/src/gui/tb/source.h b/src/gui/tb/source.h
deleted file mode 100644
index 760238d..0000000
--- a/src/gui/tb/source.h
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * source.h - prototypes pour la sélection du fichier ciblé lors d'une décompilation
- *
- * Copyright (C) 2010-2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide 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.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef _GUI_TB_SOURCE_H
-#define _GUI_TB_SOURCE_H
-
-
-#include "tbitem.h"
-
-
-
-#define G_TYPE_SOURCE_TBITEM               g_source_tbitem_get_type()
-#define G_SOURCE_TBITEM(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_source_tbitem_get_type(), GToolbarItem))
-#define G_IS_SOURCE_TBITEM(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_source_tbitem_get_type()))
-#define G_SOURCE_TBITEM_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SOURCE_TBITEM, GToolbarItemClass))
-#define G_IS_SOURCE_TBITEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SOURCE_TBITEM))
-#define G_SOURCE_TBITEM_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SOURCE_TBITEM, GToolbarItemClass))
-
-
-/* Elément réactif listant les fichiers décompilés (instance) */
-typedef struct _GSourceTbItem GSourceTbItem;
-
-/* Elément réactif listant les fichiers décompilés (classe) */
-typedef struct _GSourceTbItemClass GSourceTbItemClass;
-
-
-/* Indique le type défini pour une liste de fichiers destinée à une barre d'outils. */
-GType g_source_tbitem_get_type(void);
-
-/* Crée une sélection de fichier réactive pour barre d'outils. */
-GEditorItem *create_source_tb_item(GObject *ref);
-
-
-
-#endif  /* _GUI_TB_SOURCE_H */
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index fda42e4..4c6ffa6 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -32,6 +32,7 @@
 #include "plugin-def.h"
 #include "../analysis/binary.h"
 #include "../format/format.h"
+#include "../gtkext/gtkstatusstack.h"
 
 
 
-- 
cgit v0.11.2-87-g4458