From bea3337108fa5b59b8f6fdbe016d5ed6a6300bc6 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 14 Jul 2018 13:48:54 +0200
Subject: Begun to switch to abstract locations in internal rendering buffers.

---
 plugins/pychrysalide/glibext/linegen.c | 12 +++--
 src/analysis/db/items/comment.c        | 28 ++++++----
 src/arch/instruction.c                 | 28 ++++++----
 src/format/symbol.c                    | 28 ++++++----
 src/glibext/gbinarycursor.c            | 41 +++++++++++++--
 src/glibext/gbinportion.c              | 28 ++++++----
 src/glibext/gbuffercache.c             | 96 +++++++++++++++++++++++-----------
 src/glibext/gbuffercache.h             |  2 +-
 src/glibext/gbufferview.c              | 30 +++++------
 src/glibext/gbufferview.h              |  4 +-
 src/glibext/generators/prologue.c      | 32 ++++++++----
 src/glibext/generators/rborder.c       | 32 ++++++++----
 src/glibext/glinecursor-int.h          |  6 +++
 src/glibext/glinecursor.c              | 29 ++++++++++
 src/glibext/glinecursor.h              |  3 ++
 src/glibext/linegen-int.h              |  4 +-
 src/glibext/linegen.c                  | 12 ++---
 src/glibext/linegen.h                  |  5 +-
 src/gtkext/gtkbufferdisplay.c          | 24 +++++++--
 19 files changed, 314 insertions(+), 130 deletions(-)

diff --git a/plugins/pychrysalide/glibext/linegen.c b/plugins/pychrysalide/glibext/linegen.c
index b6aad6b..8368548 100644
--- a/plugins/pychrysalide/glibext/linegen.c
+++ b/plugins/pychrysalide/glibext/linegen.c
@@ -43,10 +43,10 @@
 static PyObject *py_line_generator_count_lines(PyObject *, PyObject *);
 
 /* Retrouve l'emplacement correspondant à une position donnée. */
-static PyObject *py_line_generator_compute_addr(PyObject *, PyObject *);
+//static PyObject *py_line_generator_compute_addr(PyObject *, PyObject *);
 
 /* Détermine si le conteneur s'inscrit dans une plage donnée. */
-static PyObject *py_line_generator_contains_addr(PyObject *, PyObject *);
+//static PyObject *py_line_generator_contains_addr(PyObject *, PyObject *);
 
 /* Renseigne sur les propriétés liées à un générateur. */
 static PyObject *py_line_generator_get_flags(PyObject *, PyObject *);
@@ -98,7 +98,7 @@ static PyObject *py_line_generator_count_lines(PyObject *self, PyObject *args)
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
-
+#if 0
 static PyObject *py_line_generator_compute_addr(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Localisation à retourner    */
@@ -121,6 +121,7 @@ static PyObject *py_line_generator_compute_addr(PyObject *self, PyObject *args)
     return result;
 
 }
+#endif
 
 
 /******************************************************************************
@@ -135,7 +136,7 @@ static PyObject *py_line_generator_compute_addr(PyObject *self, PyObject *args)
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
-
+#if 0
 static PyObject *py_line_generator_contains_addr(PyObject *self, PyObject *args)
 {
     GLineGenerator *generator;              /* Version native              */
@@ -158,6 +159,7 @@ static PyObject *py_line_generator_contains_addr(PyObject *self, PyObject *args)
     Py_RETURN_NONE;
 
 }
+#endif
 
 
 /******************************************************************************
@@ -329,6 +331,7 @@ PyTypeObject *get_python_line_generator_type(void)
             METH_NOARGS,
             "count_lines($self, /)\n--\n\nCount the number of lines which can be displayed."
         },
+#if 0
         {
             "compute_addr", py_line_generator_compute_addr,
             METH_VARARGS,
@@ -339,6 +342,7 @@ PyTypeObject *get_python_line_generator_type(void)
             METH_VARARGS,
             "contains_addr($self, addr, index, repeat, /)\n--\n\nTell if the generator contains an address."
         },
+#endif
         {
             "get_flags", py_line_generator_get_flags,
             METH_VARARGS,
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 59fc6b7..394abe2 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -38,6 +38,7 @@
 #include "../../human/asm/lang.h"
 #include "../../../common/array.h"
 #include "../../../common/extstr.h"
+#include "../../../glibext/gbinarycursor.h"
 #include "../../../glibext/linegen-int.h"
 
 
@@ -133,10 +134,10 @@ static void g_db_comment_update_count_lines(GDbComment *);
 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);
+static void g_db_comment_compute_cursor(const GDbComment *, gint, size_t, size_t, GLineCursor **);
 
 /* 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);
+static int g_db_comment_contains_cursor(const GDbComment *, size_t, size_t, const GLineCursor *);
 
 /* 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);
@@ -276,8 +277,8 @@ static void g_db_comment_init(GDbComment *comment)
 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->compute = (linegen_compute_fc)g_db_comment_compute_cursor;
+    iface->contains = (linegen_contains_fc)g_db_comment_contains_cursor;
     iface->get_flags = (linegen_get_flags_fc)g_db_comment_get_flags;
     iface->print = (linegen_print_fc)g_db_comment_print;
 
@@ -1310,9 +1311,9 @@ static size_t g_db_comment_count_lines(const GDbComment *comment)
 *                                                                             *
 *  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.   *
+*                cursor  = emplacement à constituer. [OUT]                    *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position donnée.  *
 *                                                                             *
@@ -1322,9 +1323,11 @@ static size_t g_db_comment_count_lines(const GDbComment *comment)
 *                                                                             *
 ******************************************************************************/
 
-static void g_db_comment_compute_addr(const GDbComment *comment, gint x, vmpa2t *addr, size_t index, size_t repeat)
+static void g_db_comment_compute_cursor(const GDbComment *comment, gint x, size_t index, size_t repeat, GLineCursor **cursor)
 {
-    copy_vmpa(addr, &comment->addr);
+    *cursor = g_binary_cursor_new();
+
+    g_binary_cursor_update(G_BINARY_CURSOR(*cursor), &comment->addr);
 
 }
 
@@ -1332,9 +1335,9 @@ static void g_db_comment_compute_addr(const GDbComment *comment, gint x, vmpa2t
 /******************************************************************************
 *                                                                             *
 *  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.   *
+*                cursor  = emplacement à analyser.                            *
 *                                                                             *
 *  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
 *                                                                             *
@@ -1344,11 +1347,16 @@ static void g_db_comment_compute_addr(const GDbComment *comment, gint x, vmpa2t
 *                                                                             *
 ******************************************************************************/
 
-static int g_db_comment_contains_addr(const GDbComment *comment, const vmpa2t *addr, size_t index, size_t repeat)
+static int g_db_comment_contains_cursor(const GDbComment *comment, size_t index, size_t repeat, const GLineCursor *cursor)
 {
     int result;                             /* Conclusion à retourner      */
+    vmpa2t addr;                            /* Autre emplacement à comparer*/
+
+    assert(G_IS_BINARY_CURSOR(cursor));
+
+    g_binary_cursor_get_info(G_BINARY_CURSOR(cursor), &addr);
 
-    result = cmp_vmpa(addr, &comment->addr);
+    result = cmp_vmpa(&addr, &comment->addr);
 
     return result;
 
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 212b5b5..1fe83b5 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -31,6 +31,7 @@
 
 #include "instruction-int.h"
 #include "storage.h"
+#include "../glibext/gbinarycursor.h"
 #include "../glibext/linegen-int.h"
 
 
@@ -70,10 +71,10 @@ static bool g_arch_instruction_serialize(GArchInstruction *, GAsmStorage *, pack
 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);
+static void g_arch_instruction_compute_cursor(const GArchInstruction *, gint, size_t, size_t, GLineCursor **);
 
 /* 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);
+static int g_arch_instruction_contains_cursor(const GArchInstruction *, size_t, size_t, const GLineCursor *);
 
 /* 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);
@@ -160,8 +161,8 @@ static void g_arch_instruction_init(GArchInstruction *instr)
 static void g_arch_instruction_generator_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->compute = (linegen_compute_fc)g_arch_instruction_compute_cursor;
+    iface->contains = (linegen_contains_fc)g_arch_instruction_contains_cursor;
     iface->get_flags = (linegen_get_flags_fc)g_arch_instruction_get_flags2;
     iface->print = (linegen_print_fc)g_arch_instruction_print;
 
@@ -1452,9 +1453,9 @@ static size_t g_arch_instruction_count_lines(const GArchInstruction *instr)
 *                                                                             *
 *  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.    *
+*                cursor = emplacement à constituer. [OUT]                     *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position donnée.  *
 *                                                                             *
@@ -1464,9 +1465,11 @@ static size_t g_arch_instruction_count_lines(const GArchInstruction *instr)
 *                                                                             *
 ******************************************************************************/
 
-static void g_arch_instruction_compute_addr(const GArchInstruction *instr, gint x, vmpa2t *addr, size_t index, size_t repeat)
+static void g_arch_instruction_compute_cursor(const GArchInstruction *instr, gint x, size_t index, size_t repeat, GLineCursor **cursor)
 {
-    copy_vmpa(addr, get_mrange_addr(&instr->range));
+    *cursor = g_binary_cursor_new();
+
+    g_binary_cursor_update(G_BINARY_CURSOR(*cursor), get_mrange_addr(&instr->range));
 
 }
 
@@ -1474,9 +1477,9 @@ static void g_arch_instruction_compute_addr(const GArchInstruction *instr, gint
 /******************************************************************************
 *                                                                             *
 *  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.    *
+*                cursor = emplacement à analyser.                             *
 *                                                                             *
 *  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
 *                                                                             *
@@ -1486,11 +1489,16 @@ static void g_arch_instruction_compute_addr(const GArchInstruction *instr, gint
 *                                                                             *
 ******************************************************************************/
 
-static int g_arch_instruction_contains_addr(const GArchInstruction *instr, const vmpa2t *addr, size_t index, size_t repeat)
+static int g_arch_instruction_contains_cursor(const GArchInstruction *instr, size_t index, size_t repeat, const GLineCursor *cursor)
 {
     int result;                             /* Conclusion à retourner      */
+    vmpa2t addr;                            /* Autre emplacement à comparer*/
+
+    assert(G_IS_BINARY_CURSOR(cursor));
+
+    g_binary_cursor_get_info(G_BINARY_CURSOR(cursor), &addr);
 
-    result = cmp_mrange_with_vmpa(&instr->range, addr);
+    result = cmp_mrange_with_vmpa(&instr->range, &addr);
 
     return result;
 
diff --git a/src/format/symbol.c b/src/format/symbol.c
index 3f8e808..9c8a6e0 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -30,6 +30,7 @@
 
 
 #include "symbol-int.h"
+#include "../glibext/gbinarycursor.h"
 #include "../glibext/linegen-int.h"
 
 
@@ -61,10 +62,10 @@ static void g_binary_symbol_finalize(GBinSymbol *);
 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);
+static void g_binary_symbol_compute_cursor(const GBinSymbol *, gint, size_t, size_t, GLineCursor **);
 
 /* 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);
+static int g_binary_symbol_contains_cursor(const GBinSymbol *, size_t, size_t, const GLineCursor *);
 
 /* 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);
@@ -144,8 +145,8 @@ static void g_binary_symbol_init(GBinSymbol *symbol)
 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->compute = (linegen_compute_fc)g_binary_symbol_compute_cursor;
+    iface->contains = (linegen_contains_fc)g_binary_symbol_contains_cursor;
     iface->get_flags = (linegen_get_flags_fc)g_binary_symbol_get_flags;
     iface->print = (linegen_print_fc)g_binary_symbol_print;
 
@@ -503,9 +504,9 @@ static size_t g_binary_symbol_count_lines(const GBinSymbol *symbol)
 *                                                                             *
 *  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.    *
+*                cursor = emplacement à constituer. [OUT]                     *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position donnée.  *
 *                                                                             *
@@ -515,9 +516,11 @@ static size_t g_binary_symbol_count_lines(const GBinSymbol *symbol)
 *                                                                             *
 ******************************************************************************/
 
-void g_binary_symbol_compute_addr(const GBinSymbol *symbol, gint x, vmpa2t *addr, size_t index, size_t repeat)
+void g_binary_symbol_compute_cursor(const GBinSymbol *symbol, gint x, size_t index, size_t repeat, GLineCursor **cursor)
 {
-    copy_vmpa(addr, get_mrange_addr(&symbol->range));
+    *cursor = g_binary_cursor_new();
+
+    g_binary_cursor_update(G_BINARY_CURSOR(*cursor), get_mrange_addr(&symbol->range));
 
 }
 
@@ -525,9 +528,9 @@ void g_binary_symbol_compute_addr(const GBinSymbol *symbol, gint x, vmpa2t *addr
 /******************************************************************************
 *                                                                             *
 *  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.    *
+*                cursor = emplacement à analyser.                             *
 *                                                                             *
 *  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
 *                                                                             *
@@ -537,9 +540,14 @@ void g_binary_symbol_compute_addr(const GBinSymbol *symbol, gint x, vmpa2t *addr
 *                                                                             *
 ******************************************************************************/
 
-static int g_binary_symbol_contains_addr(const GBinSymbol *symbol, const vmpa2t *addr, size_t index, size_t repeat)
+static int g_binary_symbol_contains_cursor(const GBinSymbol *symbol, size_t index, size_t repeat, const GLineCursor *cursor)
 {
     int result;                             /* Conclusion à retourner      */
+    vmpa2t addr;                            /* Autre emplacement à comparer*/
+
+    assert(G_IS_BINARY_CURSOR(cursor));
+
+    g_binary_cursor_get_info(G_BINARY_CURSOR(cursor), &addr);
 
     /**
      * En tant que générateur, le symbole ne couvre qu'une ou plusieurs lignes
@@ -552,7 +560,7 @@ static int g_binary_symbol_contains_addr(const GBinSymbol *symbol, const vmpa2t
      *
      */
 
-    result = cmp_vmpa(addr, get_mrange_addr(&symbol->range));
+    result = cmp_vmpa(&addr, get_mrange_addr(&symbol->range));
 
     return result;
 
diff --git a/src/glibext/gbinarycursor.c b/src/glibext/gbinarycursor.c
index 3bd7199..470022c 100644
--- a/src/glibext/gbinarycursor.c
+++ b/src/glibext/gbinarycursor.c
@@ -24,11 +24,14 @@
 #include "gbinarycursor.h"
 
 
+#include "glinecursor-int.h"
+
+
 
 /* Suivi de positions dans un panneau de chargement (instance) */
 struct _GBinaryCursor
 {
-    GObject parent;                         /* A laisser en premier        */
+    GLineCursor parent;                     /* A laisser en premier        */
 
     vmpa2t addr;                            /* Position mémoire du curseur */
 
@@ -37,7 +40,7 @@ struct _GBinaryCursor
 /* Suivi de positions dans un panneau de chargement (classe) */
 struct _GBinaryCursorClass
 {
-    GObjectClass parent;                    /* A laisser en premier        */
+    GLineCursorClass parent;                /* A laisser en premier        */
 
 };
 
@@ -54,10 +57,13 @@ static void g_binary_cursor_dispose(GBinaryCursor *);
 /* Procède à la libération totale de la mémoire. */
 static void g_binary_cursor_finalize(GBinaryCursor *);
 
+/* Compare deux suivis d'emplacements. */
+static int g_binary_cursor_compare(const GBinaryCursor *, const GBinaryCursor *);
+
 
 
 /* Détermine le type du gestionnaire de largeurs associées aux lignes. */
-G_DEFINE_TYPE(GBinaryCursor, g_binary_cursor, G_TYPE_OBJECT);
+G_DEFINE_TYPE(GBinaryCursor, g_binary_cursor, G_TYPE_LINE_CURSOR);
 
 
 /******************************************************************************
@@ -75,12 +81,17 @@ G_DEFINE_TYPE(GBinaryCursor, g_binary_cursor, G_TYPE_OBJECT);
 static void g_binary_cursor_class_init(GBinaryCursorClass *class)
 {
     GObjectClass *object;                   /* Autre version de la classe  */
+    GLineCursorClass *line;                 /* Version parente de la classe*/
 
     object = G_OBJECT_CLASS(class);
 
     object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_cursor_dispose;
     object->finalize = (GObjectFinalizeFunc)g_binary_cursor_finalize;
 
+    line = G_LINE_CURSOR_CLASS(class);
+
+    line->compare = (compare_cursor_fc)g_binary_cursor_compare;
+
 }
 
 
@@ -166,6 +177,30 @@ GLineCursor *g_binary_cursor_new(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : cursor = premier suivi d'emplacement à comparer.             *
+*                other  = second suivi d'emplacement à comparer.              *
+*                                                                             *
+*  Description : Compare deux suivis d'emplacements.                          *
+*                                                                             *
+*  Retour      : Bilan de la comparaison.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int g_binary_cursor_compare(const GBinaryCursor *cursor, const GBinaryCursor *other)
+{
+    int result;                             /* Bilan à renvoyer            */
+
+    result = cmp_vmpa(&cursor->addr, &other->addr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : cursor = suivi de positions à mettre à jour.                 *
 *                addr   = emplacement dans le binaire visé.                   *
 *                                                                             *
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index f99a7cc..2ffe253 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -37,6 +37,7 @@
 #include "../analysis/human/asm/lang.h" // TODO : REMME -> format !
 #include "../common/extstr.h"
 #include "../common/sort.h"
+#include "../glibext/gbinarycursor.h"
 #include "../glibext/linegen-int.h"
 
 
@@ -102,10 +103,10 @@ static bool g_binary_portion_compute_sub_area(const GBinPortion *, phys_t, const
 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);
+static void g_binary_portion_compute_cursor(const GBinPortion *, gint, size_t, size_t, GLineCursor **);
 
 /* 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);
+static int g_binary_portion_contains_cursor(const GBinPortion *, size_t, size_t, const GLineCursor *);
 
 /* 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);
@@ -202,8 +203,8 @@ static void g_binary_portion_init(GBinPortion *portion)
 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->compute = (linegen_compute_fc)g_binary_portion_compute_cursor;
+    iface->contains = (linegen_contains_fc)g_binary_portion_contains_cursor;
     iface->get_flags = (linegen_get_flags_fc)g_binary_portion_get_flags;
     iface->print = (linegen_print_fc)g_binary_portion_print;
 
@@ -1040,9 +1041,9 @@ static size_t g_binary_portion_count_lines(const GBinPortion *portion)
 *                                                                             *
 *  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.   *
+*                cursor  = emplacement à constituer. [OUT]                    *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position donnée.  *
 *                                                                             *
@@ -1052,9 +1053,11 @@ static size_t g_binary_portion_count_lines(const GBinPortion *portion)
 *                                                                             *
 ******************************************************************************/
 
-static void g_binary_portion_compute_addr(const GBinPortion *portion, gint x, vmpa2t *addr, size_t index, size_t repeat)
+static void g_binary_portion_compute_cursor(const GBinPortion *portion, gint x, size_t index, size_t repeat, GLineCursor **cursor)
 {
-    copy_vmpa(addr, get_mrange_addr(&portion->range));
+    *cursor = g_binary_cursor_new();
+
+    g_binary_cursor_update(G_BINARY_CURSOR(*cursor), get_mrange_addr(&portion->range));
 
 }
 
@@ -1062,9 +1065,9 @@ static void g_binary_portion_compute_addr(const GBinPortion *portion, gint x, vm
 /******************************************************************************
 *                                                                             *
 *  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.   *
+*                cursor  = emplacement à analyser.                            *
 *                                                                             *
 *  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
 *                                                                             *
@@ -1074,11 +1077,16 @@ static void g_binary_portion_compute_addr(const GBinPortion *portion, gint x, vm
 *                                                                             *
 ******************************************************************************/
 
-static int g_binary_portion_contains_addr(const GBinPortion *portion, const vmpa2t *addr, size_t index, size_t repeat)
+static int g_binary_portion_contains_cursor(const GBinPortion *portion, size_t index, size_t repeat, const GLineCursor *cursor)
 {
     int result;                             /* Conclusion à retourner      */
+    vmpa2t addr;                            /* Autre emplacement à comparer*/
+
+    assert(G_IS_BINARY_CURSOR(cursor));
+
+    g_binary_cursor_get_info(G_BINARY_CURSOR(cursor), &addr);
 
-    result = cmp_vmpa(addr, get_mrange_addr(&portion->range));
+    result = cmp_vmpa(&addr, get_mrange_addr(&portion->range));
 
     return result;
 
diff --git a/src/glibext/gbuffercache.c b/src/glibext/gbuffercache.c
index 66ecf27..a64ec68 100644
--- a/src/glibext/gbuffercache.c
+++ b/src/glibext/gbuffercache.c
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 
 
+#include "gbinarycursor.h" // REMME
 #include "chrysamarshal.h"
 
 
@@ -78,7 +79,7 @@ static void extend_cache_info(cache_info *, GLineGenerator *);
 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 *);
+static void get_cache_info_cursor(const cache_info *, size_t, gint, GLineCursor **);
 
 /* Suivit les variations du compteur de références d'une ligne. */
 static void on_line_ref_toggle(cache_info *, GBufferLine *, gboolean);
@@ -352,10 +353,10 @@ static void remove_from_cache_info(cache_info *info, GLineGenerator *generator)
 
 /******************************************************************************
 *                                                                             *
-*  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]                          *
+*  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.       *
+*                cursor = emplacement à constituer. [OUT]                     *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position de ligne.*
 *                                                                             *
@@ -365,7 +366,7 @@ static void remove_from_cache_info(cache_info *info, GLineGenerator *generator)
 *                                                                             *
 ******************************************************************************/
 
-static void get_cache_info_addr(const cache_info *info, size_t index, gint x, vmpa2t *addr)
+static void get_cache_info_cursor(const cache_info *info, size_t index, gint x, GLineCursor **cursor)
 {
     const generator_link *generator;        /* Générateur retenu           */
 
@@ -374,7 +375,7 @@ static void get_cache_info_addr(const cache_info *info, size_t index, gint x, vm
     else
         generator = &info->generators[0];
 
-    g_line_generator_compute_addr(generator->instance, x, addr, index, generator->repeat);
+    g_line_generator_compute_cursor(generator->instance, x, index, generator->repeat, cursor);
 
 }
 
@@ -867,8 +868,9 @@ static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t inde
 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        */
+    GLineCursor *gen_cursor;                /* Position du générateur      */
+    GLineCursor *line_cursor;               /* Position de la ligne        */
+    int ret;                                /* Bilan de comparaison        */
 #endif
     size_t needed;                          /* Emplacements nécessaires    */
     size_t i;                               /* Boucle de parcours          */
@@ -879,14 +881,19 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator
 
 #ifndef NDEBUG
 
-    g_line_generator_compute_addr(generator, 0, &gen_addr, index, 0);
+    g_line_generator_compute_cursor(generator, 0, index, 0, &gen_cursor);
+
+    get_cache_info_cursor(&cache->lines[index], index, 0, &line_cursor);
+
+    ret = g_line_cursor_compare(gen_cursor, line_cursor);
 
-    get_cache_info_addr(&cache->lines[index], index, 0, &line_addr);
+    g_object_unref(G_OBJECT(gen_cursor));
+    g_object_unref(G_OBJECT(line_cursor));
 
     ///////////////////////////////////////
-    if (cmp_vmpa(&gen_addr, &line_addr) != 0) return;
+    if (ret != 0) return;
 
-    assert(cmp_vmpa(&gen_addr, &line_addr) == 0);
+    assert(ret == 0);
 
 #endif
 
@@ -1282,10 +1289,10 @@ void g_buffer_cache_truncate(GBufferCache *cache, size_t max)
 
 /******************************************************************************
 *                                                                             *
-*  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]                          *
+*  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.       *
+*                cursor = emplacement à constituer. [OUT]                     *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position de ligne.*
 *                                                                             *
@@ -1295,11 +1302,11 @@ void g_buffer_cache_truncate(GBufferCache *cache, size_t max)
 *                                                                             *
 ******************************************************************************/
 
-void g_buffer_cache_get_line_addr(const GBufferCache *cache, size_t index, gint x, vmpa2t *addr)
+void g_buffer_cache_get_line_cursor(const GBufferCache *cache, size_t index, gint x, GLineCursor **cursor)
 {
     assert(index < cache->used);
 
-    get_cache_info_addr(&cache->lines[index], index, x, addr);
+    get_cache_info_cursor(&cache->lines[index], index, x, cursor);
 
 }
 
@@ -1489,9 +1496,10 @@ void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, s
 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          */
+    GLineCursor *___tmp;
     cache_info *found;                      /* Eventuel élément trouvé     */
 
-    int find_containing_generator(const vmpa2t *a, const cache_info *i)
+    int find_containing_generator(const GLineCursor *c, const cache_info *i)
     {
         const generator_link *generator;    /* Générateur retenu           */
 
@@ -1500,12 +1508,17 @@ size_t _g_buffer_cache_find_index_by_addr(const GBufferCache *cache, const vmpa2
         else
             generator = &i->generators[0];
 
-        return g_line_generator_contains_addr(generator->instance, addr,
-                                              i - cache->lines, generator->repeat);
+        return g_line_generator_contains_cursor(generator->instance,
+                                                i - cache->lines, generator->repeat, c);
 
     }
 
-    found = (cache_info *)bsearch(addr, &cache->lines[start], end - start + 1,
+
+    ___tmp = g_binary_cursor_new();
+    g_binary_cursor_update(G_BINARY_CURSOR(___tmp), addr);
+
+
+    found = (cache_info *)bsearch(___tmp, &cache->lines[start], end - start + 1,
                                   sizeof(cache_info), (__compar_fn_t)find_containing_generator);
 
     if (found == NULL)
@@ -1523,7 +1536,7 @@ size_t _g_buffer_cache_find_index_by_addr(const GBufferCache *cache, const vmpa2
             {
                 found = &cache->lines[result - 1];
 
-                if (find_containing_generator(addr, found) != 0)
+                if (find_containing_generator(___tmp, found) != 0)
                     break;
 
             }
@@ -1533,13 +1546,17 @@ size_t _g_buffer_cache_find_index_by_addr(const GBufferCache *cache, const vmpa2
             {
                 found = &cache->lines[result + 1];
 
-                if (find_containing_generator(addr, found) != 0)
+                if (find_containing_generator(___tmp, found) != 0)
                     break;
 
             }
 
     }
 
+
+    g_object_unref(G_OBJECT(___tmp));
+
+
     return result;
 
 }
@@ -1590,21 +1607,26 @@ size_t g_buffer_cache_find_index_by_addr(const GBufferCache *cache, const vmpa2t
 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      */
+    GLineCursor *init;                      /* Localisation de départ      */
     size_t i;                               /* Boucle de parcours          */
-    vmpa2t addr;                            /* Localisation suivante       */
+    GLineCursor *next;                      /* Localisation suivante       */
+    int ret;                                /* Bilan de comparaison        */
 
     assert(start < cache->used);
 
     result = start;
 
-    get_cache_info_addr(&cache->lines[start], start, 0, &start_addr);
+    get_cache_info_cursor(&cache->lines[start], start, 0, &init);
 
     for (i = start + 1; i < cache->used; i++)
     {
-        get_cache_info_addr(&cache->lines[i], i, 0, &addr);
+        get_cache_info_cursor(&cache->lines[i], i, 0, &next);
+
+        ret = g_line_cursor_compare(init, next);
+
+        g_object_unref(G_OBJECT(next));
 
-        if (cmp_vmpa(&start_addr, &addr) != 0)
+        if (ret != 0)
             break;
 
         if ((g_buffer_cache_get_line_flags(cache, i) & flag) != 0)
@@ -1615,6 +1637,8 @@ size_t g_buffer_cache_look_for_flag(const GBufferCache *cache, size_t start, Buf
 
     }
 
+    g_object_unref(G_OBJECT(init));
+
     return result;
 
 }
@@ -1641,11 +1665,17 @@ size_t g_buffer_cache_look_for_flag(const GBufferCache *cache, size_t start, Buf
 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           */
+    GLineCursor *___tmp;
     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           */
 
+
+    ___tmp = g_binary_cursor_new();
+    g_binary_cursor_update(G_BINARY_CURSOR(___tmp), addr);
+
+
     index = _g_buffer_cache_find_index_by_addr(cache, addr, true, first, last);
 
     result = (index < cache->used);
@@ -1672,7 +1702,7 @@ bool g_buffer_cache_get_address_coordinates(const GBufferCache *cache, const vmp
             else
                 generator = &info->generators[0];
 
-            if (!g_line_generator_contains_addr(generator->instance, addr, index + 1, generator->repeat))
+            if (!g_line_generator_contains_cursor(generator->instance, index + 1, generator->repeat, ___tmp))
                 break;
 
             *y += lheight;
@@ -1681,6 +1711,10 @@ bool g_buffer_cache_get_address_coordinates(const GBufferCache *cache, const vmp
 
     }
 
+
+    g_object_unref(G_OBJECT(___tmp));
+
+
     return result;
 
 }
diff --git a/src/glibext/gbuffercache.h b/src/glibext/gbuffercache.h
index dbd3237..fdf59d7 100644
--- a/src/glibext/gbuffercache.h
+++ b/src/glibext/gbuffercache.h
@@ -90,7 +90,7 @@ void g_buffer_cache_extend_with(GBufferCache *, size_t, GLineGenerator *);
 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 *);
+void g_buffer_cache_get_line_cursor(const GBufferCache *, size_t, gint, GLineCursor **);
 
 /* Détermine l'ensemble des propriétés attachées à une ligne. */
 BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *, size_t);
diff --git a/src/glibext/gbufferview.c b/src/glibext/gbufferview.c
index af7d7ac..0eff4d8 100644
--- a/src/glibext/gbufferview.c
+++ b/src/glibext/gbufferview.c
@@ -77,7 +77,7 @@ static void g_buffer_view_finalize(GBufferView *);
 static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, 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 *, cairo_rectangle_int_t *, vmpa2t *);
+bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const bool *, cairo_rectangle_int_t *, GLineCursor **);
 
 /* Déplace le curseur au sein d'une vue de tampon. */
 static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, cairo_rectangle_int_t *, bool, GdkScrollDirection, const bool *);
@@ -565,7 +565,7 @@ gint g_buffer_view_get_height(const GBufferView *view)
 *                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] *
+*                cursor  = emplacement correspondant à cette position. [OUT]  *
 *                                                                             *
 *  Description : Calcule la position idéale de curseur pour un point donné.   *
 *                                                                             *
@@ -575,7 +575,7 @@ gint g_buffer_view_get_height(const GBufferView *view)
 *                                                                             *
 ******************************************************************************/
 
-bool g_buffer_view_compute_caret_full(GBufferView *view, gint x, gint y, const bool *display, cairo_rectangle_int_t *caret, vmpa2t *addr)
+bool g_buffer_view_compute_caret_full(GBufferView *view, gint x, gint y, const bool *display, cairo_rectangle_int_t *caret, GLineCursor **cursor)
 {
     bool result;                            /* Bilan à retourner           */
     gint lheight;                           /* Hauteur d'une ligne         */
@@ -600,7 +600,7 @@ bool g_buffer_view_compute_caret_full(GBufferView *view, gint x, gint y, const b
 
     /* Calcul d'une position */
 
-    result = _g_buffer_view_compute_caret_full(view, x, line, index, display, caret, addr);
+    result = _g_buffer_view_compute_caret_full(view, x, line, index, display, caret, cursor);
 
     g_object_unref(G_OBJECT(line));
 
@@ -619,7 +619,7 @@ bool g_buffer_view_compute_caret_full(GBufferView *view, gint x, gint y, const b
 *                index   = indice de cette même ligne dans le tampon.         *
 *                display = règles d'affichage des colonnes modulables.        *
 *                caret   = position du curseur à construire. [OUT]            *
-*                addr    = adresse correspondant à cette même position. [OUT] *
+*                cursor  = emplacement correspondant à cette position. [OUT]  *
 *                                                                             *
 *  Description : Calcule la position idéale de curseur pour un point donné.   *
 *                                                                             *
@@ -629,7 +629,7 @@ bool g_buffer_view_compute_caret_full(GBufferView *view, gint x, gint y, const b
 *                                                                             *
 ******************************************************************************/
 
-bool _g_buffer_view_compute_caret_full(GBufferView *view, gint x, GBufferLine *line, size_t index, const bool *display, cairo_rectangle_int_t *caret, vmpa2t *addr)
+bool _g_buffer_view_compute_caret_full(GBufferView *view, gint x, GBufferLine *line, size_t index, const bool *display, cairo_rectangle_int_t *caret, GLineCursor **cursor)
 {
     bool result;                            /* Bilan à retourner           */
     gint text_pos;                          /* Abscisse de départ du texte */
@@ -670,7 +670,7 @@ bool _g_buffer_view_compute_caret_full(GBufferView *view, gint x, GBufferLine *l
     caret->width = 2;
     caret->height = lheight;
 
-    g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+    g_buffer_cache_get_line_cursor(view->cache, index, caret->x, cursor);
 
     result = true;
 
@@ -764,7 +764,7 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
 *                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] *
+*                cursor  = emplacement correspondant à cette position. [OUT]  *
 *                                                                             *
 *  Description : Déplace le curseur au sein d'une vue de tampon.              *
 *                                                                             *
@@ -774,7 +774,7 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
 *                                                                             *
 ******************************************************************************/
 
-bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection dir, const bool *display, cairo_rectangle_int_t *caret, vmpa2t *addr)
+bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection dir, const bool *display, cairo_rectangle_int_t *caret, GLineCursor **cursor)
 {
     bool result;                            /* Bilan à retourner           */
     size_t index;                           /* Indice de ligne de tampon   */
@@ -802,7 +802,7 @@ bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection d
                 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);
+                result = _g_buffer_view_compute_caret_full(view, caret->x, other, index, display, caret, cursor);
                 g_object_unref(G_OBJECT(other));
 
             }
@@ -816,7 +816,7 @@ bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection d
                 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);
+                result = _g_buffer_view_compute_caret_full(view, caret->x, other, index, display, caret, cursor);
                 g_object_unref(G_OBJECT(other));
 
             }
@@ -829,7 +829,7 @@ bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection d
 
             if (moved)
             {
-                g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+                g_buffer_cache_get_line_cursor(view->cache, index, caret->x, cursor);
                 result = true;
             }
 
@@ -838,7 +838,7 @@ bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection d
                 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);
+                result = _g_buffer_view_compute_caret_full(view, INT_MAX, other, index, display, caret, cursor);
                 g_object_unref(G_OBJECT(other));
 
             }
@@ -851,7 +851,7 @@ bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection d
 
             if (moved)
             {
-                g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+                g_buffer_cache_get_line_cursor(view->cache, index, caret->x, cursor);
                 result = true;
             }
 
@@ -862,7 +862,7 @@ bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection d
                 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);
+                result = _g_buffer_view_compute_caret_full(view, text_pos, other, index, display, caret, cursor);
                 g_object_unref(G_OBJECT(other));
 
             }
diff --git a/src/glibext/gbufferview.h b/src/glibext/gbufferview.h
index ee77212..facc3b7 100644
--- a/src/glibext/gbufferview.h
+++ b/src/glibext/gbufferview.h
@@ -78,10 +78,10 @@ gint g_buffer_view_get_height(const GBufferView *);
 
 
 /* Calcule la position idéale de curseur pour un point donné. */
-bool g_buffer_view_compute_caret_full(GBufferView *, gint, gint, const bool *, cairo_rectangle_int_t *, vmpa2t *);
+bool g_buffer_view_compute_caret_full(GBufferView *, gint, gint, const bool *, cairo_rectangle_int_t *, GLineCursor **);
 
 /* Déplace le curseur au sein d'une vue de tampon. */
-bool g_buffer_view_move_caret(GBufferView *, bool, GdkScrollDirection, const bool *, cairo_rectangle_int_t *, vmpa2t *);
+bool g_buffer_view_move_caret(GBufferView *, bool, GdkScrollDirection, const bool *, cairo_rectangle_int_t *, GLineCursor **);
 
 
 
diff --git a/src/glibext/generators/prologue.c b/src/glibext/generators/prologue.c
index 2f4075e..63d326b 100644
--- a/src/glibext/generators/prologue.c
+++ b/src/glibext/generators/prologue.c
@@ -28,6 +28,7 @@
 #include <malloc.h>
 
 
+#include "../gbinarycursor.h"
 #include "../gbufferline.h"
 #include "../linegen-int.h"
 #include "../linesegment.h"
@@ -74,10 +75,10 @@ static void g_intro_generator_finalize(GIntroGenerator *);
 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);
+static void g_intro_generator_compute_cursor(const GIntroGenerator *, gint, size_t, size_t, GLineCursor **);
 
 /* 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);
+static int g_intro_generator_contains_cursor(const GIntroGenerator *, size_t, size_t, const GLineCursor *);
 
 /* 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);
@@ -151,8 +152,8 @@ static void g_intro_generator_init(GIntroGenerator *generator)
 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->compute = (linegen_compute_fc)g_intro_generator_compute_cursor;
+    iface->contains = (linegen_contains_fc)g_intro_generator_contains_cursor;
     iface->get_flags = (linegen_get_flags_fc)g_intro_generator_get_flags;
     iface->print = (linegen_print_fc)g_intro_generator_print;
 
@@ -284,9 +285,9 @@ static size_t g_intro_generator_count_lines(const GIntroGenerator *generator)
 *                                                                             *
 *  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. *
+*                cursor    = emplacement à constituer. [OUT]                  *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position donnée.  *
 *                                                                             *
@@ -296,9 +297,11 @@ static size_t g_intro_generator_count_lines(const GIntroGenerator *generator)
 *                                                                             *
 ******************************************************************************/
 
-static void g_intro_generator_compute_addr(const GIntroGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+static void g_intro_generator_compute_cursor(const GIntroGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor)
 {
-    copy_vmpa(addr, &generator->addr);
+    *cursor = g_binary_cursor_new();
+
+    g_binary_cursor_update(G_BINARY_CURSOR(*cursor), &generator->addr);
 
 }
 
@@ -306,9 +309,9 @@ static void g_intro_generator_compute_addr(const GIntroGenerator *generator, gin
 /******************************************************************************
 *                                                                             *
 *  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. *
+*                cursor    = emplacement à analyser.                          *
 *                                                                             *
 *  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
 *                                                                             *
@@ -318,9 +321,18 @@ static void g_intro_generator_compute_addr(const GIntroGenerator *generator, gin
 *                                                                             *
 ******************************************************************************/
 
-static int g_intro_generator_contains_addr(const GIntroGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+static int g_intro_generator_contains_cursor(const GIntroGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor)
 {
-    return cmp_vmpa(addr, &generator->addr);
+    int result;                             /* Conclusion à retourner      */
+    vmpa2t addr;                            /* Autre emplacement à comparer*/
+
+    assert(G_IS_BINARY_CURSOR(cursor));
+
+    g_binary_cursor_get_info(G_BINARY_CURSOR(cursor), &addr);
+
+    result = cmp_vmpa(&addr, &generator->addr);
+
+    return result;
 
 }
 
diff --git a/src/glibext/generators/rborder.c b/src/glibext/generators/rborder.c
index a440377..62c374d 100644
--- a/src/glibext/generators/rborder.c
+++ b/src/glibext/generators/rborder.c
@@ -29,6 +29,7 @@
 #include <string.h>
 
 
+#include "../gbinarycursor.h"
 #include "../gbufferline.h"
 #include "../linegen-int.h"
 #include "../linesegment.h"
@@ -81,10 +82,10 @@ static void g_border_generator_finalize(GBorderGenerator *);
 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);
+static void g_border_generator_compute_cursor(const GBorderGenerator *, gint, size_t, size_t, GLineCursor **);
 
 /* 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);
+static int g_border_generator_contains_cursor(const GBorderGenerator *, size_t, size_t, const GLineCursor *);
 
 /* 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);
@@ -156,8 +157,8 @@ static void g_border_generator_init(GBorderGenerator *generator)
 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->compute = (linegen_compute_fc)g_border_generator_compute_cursor;
+    iface->contains = (linegen_contains_fc)g_border_generator_contains_cursor;
     iface->get_flags = (linegen_get_flags_fc)g_border_generator_get_flags;
     iface->print = (linegen_print_fc)g_border_generator_print;
 
@@ -261,9 +262,9 @@ static size_t g_border_generator_count_lines(const GBorderGenerator *generator)
 *                                                                             *
 *  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. *
+*                cursor    = emplacement à constituer. [OUT]                  *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position donnée.  *
 *                                                                             *
@@ -273,9 +274,11 @@ static size_t g_border_generator_count_lines(const GBorderGenerator *generator)
 *                                                                             *
 ******************************************************************************/
 
-void g_border_generator_compute_addr(const GBorderGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+void g_border_generator_compute_cursor(const GBorderGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor)
 {
-    copy_vmpa(addr, &generator->addr);
+    *cursor = g_binary_cursor_new();
+
+    g_binary_cursor_update(G_BINARY_CURSOR(*cursor), &generator->addr);
 
 }
 
@@ -283,9 +286,9 @@ void g_border_generator_compute_addr(const GBorderGenerator *generator, gint x,
 /******************************************************************************
 *                                                                             *
 *  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. *
+*                cursor    = emplacement à analyser.                          *
 *                                                                             *
 *  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
 *                                                                             *
@@ -295,9 +298,18 @@ void g_border_generator_compute_addr(const GBorderGenerator *generator, gint x,
 *                                                                             *
 ******************************************************************************/
 
-static int g_border_generator_contains_addr(const GBorderGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+static int g_border_generator_contains_cursor(const GBorderGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor)
 {
-    return cmp_vmpa(addr, &generator->addr);
+    int result;                             /* Conclusion à retourner      */
+    vmpa2t addr;                            /* Autre emplacement à comparer*/
+
+    assert(G_IS_BINARY_CURSOR(cursor));
+
+    g_binary_cursor_get_info(G_BINARY_CURSOR(cursor), &addr);
+
+    result = cmp_vmpa(&addr, &generator->addr);
+
+    return result;
 
 }
 
diff --git a/src/glibext/glinecursor-int.h b/src/glibext/glinecursor-int.h
index 411b072..26e5143 100644
--- a/src/glibext/glinecursor-int.h
+++ b/src/glibext/glinecursor-int.h
@@ -29,6 +29,10 @@
 
 
 
+/* Compare deux suivis d'emplacements. */
+typedef int (* compare_cursor_fc) (const GLineCursor *, const GLineCursor *);
+
+
 /* Suivi de positions dans un panneau de chargement (instance) */
 struct _GLineCursor
 {
@@ -41,6 +45,8 @@ struct _GLineCursorClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
+    compare_cursor_fc compare;              /* Comparaison d'emplacements  */
+
 };
 
 
diff --git a/src/glibext/glinecursor.c b/src/glibext/glinecursor.c
index 8ad24bd..52cadea 100644
--- a/src/glibext/glinecursor.c
+++ b/src/glibext/glinecursor.c
@@ -24,6 +24,9 @@
 #include "glinecursor.h"
 
 
+#include <assert.h>
+
+
 #include "glinecursor-int.h"
 
 
@@ -124,3 +127,29 @@ static void g_line_cursor_finalize(GLineCursor *cursor)
     G_OBJECT_CLASS(g_line_cursor_parent_class)->finalize(G_OBJECT(cursor));
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = premier suivi d'emplacement à comparer.             *
+*                other  = second suivi d'emplacement à comparer.              *
+*                                                                             *
+*  Description : Compare deux suivis d'emplacements.                          *
+*                                                                             *
+*  Retour      : Bilan de la comparaison.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int g_line_cursor_compare(const GLineCursor *cursor, const GLineCursor *other)
+{
+    int result;                             /* Bilan à renvoyer            */
+
+    assert(G_OBJECT_TYPE(cursor) == G_OBJECT_TYPE(other));
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->compare(cursor, other);
+
+    return result;
+
+}
diff --git a/src/glibext/glinecursor.h b/src/glibext/glinecursor.h
index e541e66..58bee9c 100644
--- a/src/glibext/glinecursor.h
+++ b/src/glibext/glinecursor.h
@@ -47,6 +47,9 @@ typedef struct _GLineCursorClass GLineCursorClass;
 /* Détermine le type du suivi de positions dans un panneau de chargement. */
 GType g_line_cursor_get_type(void);
 
+/* Compare deux suivis d'emplacements. */
+int g_line_cursor_compare(const GLineCursor *, const GLineCursor *);
+
 
 
 #endif  /* _GLIBEXT_LINECURSOR_H */
diff --git a/src/glibext/linegen-int.h b/src/glibext/linegen-int.h
index 1847eba..b903ed7 100644
--- a/src/glibext/linegen-int.h
+++ b/src/glibext/linegen-int.h
@@ -33,10 +33,10 @@
 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);
+typedef void (* linegen_compute_fc) (const GLineGenerator *, gint, size_t, size_t, GLineCursor **);
 
 /* 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);
+typedef int (* linegen_contains_fc) (const GLineGenerator *, size_t, size_t, const GLineCursor *);
 
 /* Renseigne sur les propriétés liées à un générateur. */
 typedef BufferLineFlags (* linegen_get_flags_fc) (const GLineGenerator *, size_t, size_t);
diff --git a/src/glibext/linegen.c b/src/glibext/linegen.c
index 6675646..c61fa63 100644
--- a/src/glibext/linegen.c
+++ b/src/glibext/linegen.c
@@ -88,9 +88,9 @@ size_t g_line_generator_count_lines(const GLineGenerator *generator)
 *                                                                             *
 *  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. *
+*                cursor    = emplacement à constituer. [OUT]                  *
 *                                                                             *
 *  Description : Retrouve l'emplacement correspondant à une position donnée.  *
 *                                                                             *
@@ -100,7 +100,7 @@ size_t g_line_generator_count_lines(const GLineGenerator *generator)
 *                                                                             *
 ******************************************************************************/
 
-void g_line_generator_compute_addr(const GLineGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat)
+void g_line_generator_compute_cursor(const GLineGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor)
 {
     GLineGeneratorIface *iface;             /* Interface utilisée          */
 
@@ -111,7 +111,7 @@ void g_line_generator_compute_addr(const GLineGenerator *generator, gint x, vmpa
         assert(repeat < g_line_generator_count_lines(generator));
 #endif
 
-    iface->compute(generator, x, addr, index, repeat);
+    iface->compute(generator, x, index, repeat, cursor);
 
 }
 
@@ -119,9 +119,9 @@ void g_line_generator_compute_addr(const GLineGenerator *generator, gint x, vmpa
 /******************************************************************************
 *                                                                             *
 *  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. *
+*                cursor    = emplacement à analyser.                          *
 *                                                                             *
 *  Description : Détermine si le conteneur s'inscrit dans une plage donnée.   *
 *                                                                             *
@@ -131,7 +131,7 @@ void g_line_generator_compute_addr(const GLineGenerator *generator, gint x, vmpa
 *                                                                             *
 ******************************************************************************/
 
-int g_line_generator_contains_addr(const GLineGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat)
+int g_line_generator_contains_cursor(const GLineGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor)
 {
     GLineGeneratorIface *iface;             /* Interface utilisée          */
 
@@ -142,7 +142,7 @@ int g_line_generator_contains_addr(const GLineGenerator *generator, const vmpa2t
         assert(repeat < g_line_generator_count_lines(generator));
 #endif
 
-    return iface->contains(generator, addr, index, repeat);
+    return iface->contains(generator, index, repeat, cursor);
 
 }
 
diff --git a/src/glibext/linegen.h b/src/glibext/linegen.h
index 1fa6dbf..31672a2 100644
--- a/src/glibext/linegen.h
+++ b/src/glibext/linegen.h
@@ -29,6 +29,7 @@
 
 
 #include "gbufferline.h"
+#include "glinecursor.h"
 #include "../analysis/content.h"
 
 
@@ -55,10 +56,10 @@ GType g_line_generator_get_type(void) G_GNUC_CONST;
 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);
+void g_line_generator_compute_cursor(const GLineGenerator *, gint, size_t, size_t, GLineCursor **);
 
 /* 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);
+int g_line_generator_contains_cursor(const GLineGenerator *, size_t, size_t, const GLineCursor *);
 
 /* Renseigne sur les propriétés liées à un générateur. */
 BufferLineFlags g_line_generator_get_flags(const GLineGenerator *, size_t, size_t);
diff --git a/src/gtkext/gtkbufferdisplay.c b/src/gtkext/gtkbufferdisplay.c
index 45c7193..3ef77b5 100644
--- a/src/gtkext/gtkbufferdisplay.c
+++ b/src/gtkext/gtkbufferdisplay.c
@@ -31,6 +31,7 @@
 
 
 #include "../core/params.h"
+#include "../glibext/gbinarycursor.h" // REMME
 
 
 
@@ -475,7 +476,8 @@ static gboolean gtk_buffer_display_key_press(GtkWidget *widget, GdkEventKey *eve
     GtkBufferDisplay *display;              /* Autre version du composant  */
     GtkDisplayPanel *panel;                 /* Autre version du composant  */
     bool ctrl;                              /* Statut de la touche Contrôle*/
-    cairo_rectangle_int_t area;             /* Emplacement de curseur      */
+    cairo_rectangle_int_t area;             /* Emplacement de curseur #1   */
+    GLineCursor *cursor;                    /* Emplacement de curseur #2   */
     vmpa2t addr;                            /* Adresse du nouveau curseur  */
     bool status;                            /* Validité d'un déplacement   */
 
@@ -515,10 +517,15 @@ static gboolean gtk_buffer_display_key_press(GtkWidget *widget, GdkEventKey *eve
         ctrl = (event->state & GDK_CONTROL_MASK);
         area = display->caret;
 
-        status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display_options, &area, &addr);
+        status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display_options, &area, &cursor);
 
         if (status)
         {
+            ////////////////////////
+            g_binary_cursor_get_info(G_BINARY_CURSOR(cursor), &addr);
+            g_object_unref(G_OBJECT(cursor));
+            ////////////////////////
+
             gtk_buffer_display_relocate_caret(display, &area, &addr);
             _gtk_display_panel_scroll_to_address(panel, &addr, SPT_RAW, false);
         }
@@ -843,12 +850,21 @@ static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, gint x,
 {
     bool result;                            /* Bilan à retourner           */
     GtkDisplayPanel *panel;                 /* Autre version du composant  */
-    vmpa2t addr;                            /* Position mémoire associée   */
     cairo_rectangle_int_t new;              /* Nouvel emplacement calculé  */
+    GLineCursor *cursor;                    /* Emplacement de curseur      */
+    vmpa2t addr;                            /* Position mémoire associée   */
 
     panel = GTK_DISPLAY_PANEL(display);
 
-    result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display_options, &new, &addr);
+    result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display_options, &new, &cursor);
+
+    ////////////////////////
+    if (result)
+    {
+            g_binary_cursor_get_info(G_BINARY_CURSOR(cursor), &addr);
+            g_object_unref(G_OBJECT(cursor));
+    }
+    ////////////////////////
 
     if (result)
         gtk_buffer_display_relocate_caret(display, &new, &addr);
-- 
cgit v0.11.2-87-g4458