From 3f05bacd4fec23824489b51d964a7ce3565bb85b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 23 Oct 2016 13:59:26 +0200
Subject: Memorized all creators of line content at the line level and saved
 memory.

---
 ChangeLog                     |  22 ++
 src/arch/immediate.c          |   4 +-
 src/arch/target.c             |  13 +-
 src/glibext/gbufferline.c     | 508 +++++++++++++++++++++++++++++++-----------
 src/glibext/gbufferline.h     |   8 +-
 src/glibext/gbuffersegment.c  |  51 -----
 src/glibext/gbuffersegment.h  |   6 -
 src/glibext/gbufferview.c     |  56 +++++
 src/glibext/gbufferview.h     |   3 +
 src/glibext/gcodebuffer.c     |  13 +-
 src/gtkext/gtkbufferview.c    |  41 ++--
 src/gtkext/gtkviewpanel-int.h |   2 +-
 src/gtkext/gtkviewpanel.c     |  10 +-
 src/gtkext/gtkviewpanel.h     |   2 +-
 src/gui/menus/edition.c       |  24 +-
 15 files changed, 504 insertions(+), 259 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4be9aa4..11da097 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+16-10-23  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/arch/immediate.c:
+	* src/arch/target.c:
+	Update code.
+
+	* src/glibext/gbufferline.c:
+	* src/glibext/gbufferline.h:
+	* src/glibext/gbuffersegment.c:
+	* src/glibext/gbuffersegment.h:
+	Memorize all creators of line content at the line level and save memory.
+
+	* src/glibext/gbufferview.c:
+	* src/glibext/gbufferview.h:
+	* src/glibext/gcodebuffer.c:
+	* src/gtkext/gtkbufferview.c:
+	* src/gtkext/gtkviewpanel-int.h:
+	* src/gtkext/gtkviewpanel.c:
+	* src/gtkext/gtkviewpanel.h:
+	* src/gui/menus/edition.c:
+	Update code.
+
 16-10-22  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/glibext/gbuffersegment.c:
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index 4594e23..777ae14 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -892,12 +892,10 @@ static void g_imm_operand_print(const GImmOperand *operand, GBufferLine *line, A
 {
     char value[IMM_MAX_SIZE];               /* Chaîne à imprimer           */
     size_t len;                             /* Taille de l'élément inséré  */
-    GBufferSegment *segment;                /* Nouveau segment mis en place*/
 
     len = g_imm_operand_to_string(operand, syntax, value);
 
-    segment = g_buffer_line_insert_text(line, BLC_MAIN, value, len, RTT_IMMEDIATE);
-    g_buffer_segment_set_creator(segment, G_OBJECT(operand));
+    g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_IMMEDIATE, G_OBJECT(operand));
 
 }
 
diff --git a/src/arch/target.c b/src/arch/target.c
index bf4da3a..0517062 100644
--- a/src/arch/target.c
+++ b/src/arch/target.c
@@ -212,7 +212,6 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, virt_t addr)
 static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *line, AsmSyntax syntax)
 {
     const char *label;                      /* Etiquette liée à un symbole */
-    GBufferSegment *segment;                /* Nouveau segment mis en place*/
     vmpa2t tmp;                             /* Coquille vide pour argument */
     VMPA_BUFFER(value);                     /* Adresse brute à imprimer    */
     size_t len;                             /* Taille de l'élément inséré  */
@@ -223,19 +222,16 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
             g_buffer_line_insert_text(line, BLC_MAIN, "<", 1, RTT_LTGT);
 
         label = g_binary_symbol_get_label(operand->symbol);
-        segment = g_buffer_line_insert_text(line, BLC_MAIN, label, strlen(label), RTT_LABEL);
-        g_buffer_segment_set_creator(segment, G_OBJECT(operand));
+        g_buffer_line_append_text(line, BLC_MAIN, label, strlen(label), RTT_LABEL, G_OBJECT(operand));
 
         if (operand->diff > 0)
         {
-            segment = g_buffer_line_insert_text(line, BLC_MAIN, "+", 1, RTT_SIGNS);
-            g_buffer_segment_set_creator(segment, G_OBJECT(operand));
+            g_buffer_line_append_text(line, BLC_MAIN, "+", 1, RTT_SIGNS, G_OBJECT(operand));
 
             init_vmpa(&tmp, operand->diff, VMPA_NO_VIRTUAL);
             vmpa2_phys_to_string(&tmp, MDS_4_BITS, value, &len);
 
-            segment = g_buffer_line_insert_text(line, BLC_MAIN, value, len, RTT_LABEL);
-            g_buffer_segment_set_creator(segment, G_OBJECT(operand));
+            g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand));
 
             g_buffer_line_insert_text(line, BLC_MAIN, ">", 1, RTT_LTGT);
 
@@ -247,8 +243,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
         init_vmpa(&tmp, VMPA_NO_PHYSICAL, operand->addr);
         vmpa2_virt_to_string(&tmp, operand->size, value, &len);
 
-        segment = g_buffer_line_insert_text(line, BLC_MAIN, value, len, RTT_LABEL);
-        g_buffer_segment_set_creator(segment, G_OBJECT(operand));
+        g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand));
 
     }
 
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 0593748..a33817b 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -25,6 +25,7 @@
 
 
 #include <assert.h>
+#include <malloc.h>
 #include <string.h>
 #include <gtk/gtk.h>    /* Récupération du langage par défaut ; FIXME ? */
 
@@ -34,10 +35,6 @@
 #include "../gtkext/support.h"
 
 
-#include <malloc.h> /* FIXME : à virer */
-
-
-
 
 /* ---------------------------- REGROUPEMENT PAR COLONNE ---------------------------- */
 
@@ -63,26 +60,32 @@ static void refresh_column_width(buffer_line_column *);
 static gint get_column_width(const buffer_line_column *);
 
 /* Ajoute un fragment de texte à une colonne de ligne. */
-static void add_segment_to_column(buffer_line_column *, GBufferSegment *);
+static void add_segment_to_column(buffer_line_column *, GBufferSegment *) __attribute__ ((deprecated));
+
+/* Ajoute un fragment de texte à une colonne de ligne. */
+static size_t append_text_to_line_column(buffer_line_column *, const char *, size_t, RenderingTagType);
 
 /* Valide ou non la présence d'un segment dans une colonne. */
 static bool column_has_segment(const buffer_line_column *, const GBufferSegment *, size_t *);
 
+/* Indique l'indice du premier contenu de la colonne. */
+static bool get_column_first_content_index(const buffer_line_column *, size_t *);
+
+/* Indique l'indice du dernier contenu de la colonne. */
+static bool get_column_last_content_index(const buffer_line_column *, size_t *);
+
 #define get_first_segment(col) ((col)->count > 0 ? (col)->segments[0] : NULL)
 #define get_last_segment(col) ((col)->count > 0 ? (col)->segments[(col)->count - 1] : NULL)
 
-/* Donne le segment d'une colonne présent à une abscisse donnée. */
-static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, GdkScrollDirection, gint *);
+/* Indique l'indice du contenu de colonne à une abscisse donnée. */
+static bool get_column_content_index_at(const buffer_line_column *, gint *, GdkScrollDirection, gint *, size_t *);
+
+/* Donne le segment d'une colonne présent à un indice donné. */
+static GBufferSegment *get_column_content_from_index(const buffer_line_column *, size_t);
 
 /* Fournit le segment voisin d'un autre segment identifié. */
 static GBufferSegment *find_near_segment(const buffer_line_column *, GBufferSegment *, GdkScrollDirection);
 
-/* Fournit le segment créé par un objet particulier. */
-static GObject *find_first_segment_creator(const buffer_line_column *);
-
-/* Fournit le segment créé par un objet particulier. */
-static GBufferSegment *find_segment_from_creator(const buffer_line_column *, GObject *);
-
 /* Imprime le contenu d'une colonne de ligne de texte. */
 static void draw_segments_of_column(buffer_line_column *, cairo_t *, gint, gint, const segcnt_list *);
 
@@ -94,6 +97,23 @@ static void export_segments_of_column(buffer_line_column *, buffer_export_contex
 /* ---------------------------- GESTION DE LINE COMPLETE ---------------------------- */
 
 
+/* Identification d'un contenu de colonne */
+typedef struct _col_coord_t
+{
+    BufferLineColumn column;                /* Colonne concernée           */
+    size_t index;                           /* Indice d'insertion          */
+
+} col_coord_t;
+
+/* Mémorisation des origines de texte */
+typedef struct _content_origin
+{
+    col_coord_t coord;                      /* Localisation d'attachement  */
+
+    GObject *creator;                       /* Origine de la création      */
+
+} content_origin;
+
 /* Représentation de fragments de texte en ligne (instance) */
 struct _GBufferLine
 {
@@ -108,6 +128,9 @@ struct _GBufferLine
 
     BufferLineFlags flags;                  /* Drapeaux particuliers       */
 
+    content_origin *origins;                /* Mémorisation des origines   */
+    size_t ocount;                          /* Nombre de ces mémorisations */
+
     union
     {
         struct
@@ -152,6 +175,9 @@ static void g_buffer_line_finalize(GBufferLine *);
 /* Réagit au changement de contenu d'un segment encapsulé. */
 static void on_line_segment_changed(GBufferSegment *, GBufferLine *);
 
+/* Fournit les coordonnées correspondant à une abscisse donnée. */
+static bool g_buffer_line_get_coord_at(const GBufferLine *, const line_width_summary *, const bool *, gint *, gint *, GdkScrollDirection, bool, col_coord_t *);
+
 
 
 /* ---------------------------------------------------------------------------------- */
@@ -266,6 +292,41 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : column  = colonne de ligne à venir compléter.                *
+*                text    = texte à insérer dans l'existant.                   *
+*                length  = taille du texte à traiter.                         *
+*                type    = type de décorateur à utiliser.                     *
+*                                                                             *
+*  Description : Ajoute un fragment de texte à une colonne de ligne.          *
+*                                                                             *
+*  Retour      : Indice du point d'insertion.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t append_text_to_line_column(buffer_line_column *column, const char *text, size_t length, RenderingTagType type)
+{
+    size_t result;                          /* Indice à retourner          */
+    GBufferSegment *content;                /* Contenu à représenter       */
+
+    result = column->count;
+
+    content = g_buffer_segment_new(type, text, length);
+
+    column->segments = (GBufferSegment **)realloc(column->segments, ++column->count * sizeof(GBufferSegment *));
+
+    column->segments[result] = content;
+
+    column->max_width += g_buffer_segment_get_width(content);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : column  = colonne de ligne à venir consulter.                *
 *                segment = fragment de texte à trouver dans la colonne.       *
 *                index   = indice du segment retrouvé ou NULL. [OUT]          *
@@ -296,38 +357,88 @@ static bool column_has_segment(const buffer_line_column *column, const GBufferSe
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : column = colonne de ligne de texte à consulter.              *
+*                index  = indice du contenu enregistré à la position. [OUT]   *
+*                                                                             *
+*  Description : Indique l'indice du premier contenu de la colonne.           *
+*                                                                             *
+*  Retour      : Validité de l'indice renseigné.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool get_column_first_content_index(const buffer_line_column *column, size_t *index)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = (column->count > 0);
+
+    if (result)
+        *index = 0;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : column = colonne de ligne de texte à consulter.              *
+*                index  = indice du contenu enregistré à la position. [OUT]   *
+*                                                                             *
+*  Description : Indique l'indice du dernier contenu de la colonne.           *
+*                                                                             *
+*  Retour      : Validité de l'indice renseigné.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool get_column_last_content_index(const buffer_line_column *column, size_t *index)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = (column->count > 0);
+
+    if (result)
+        *index = column->count - 1;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : column   = colonne de ligne de texte à consulter.            *
 *                x        = position de recherche, puis position locale. [OUT]*
 *                dir      = direction d'un éventuel déplacement en cours.     *
 *                consumed = distance pour arriver à la base du segment. [OUT] *
+*                index    = indice du contenu enregistré à la position. [OUT] *
 *                                                                             *
-*  Description : Donne le segment d'une colonne présent à une abscisse donnée.*
+*  Description : Indique l'indice du contenu de colonne à une abscisse donnée.*
 *                                                                             *
-*  Retour      : Segment trouvé ou NULL si hors borne.                        *
+*  Retour      : Validité de l'indice renseigné.                              *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, GdkScrollDirection dir, gint *consumed)
+static bool get_column_content_index_at(const buffer_line_column *column, gint *x, GdkScrollDirection dir, gint *consumed, size_t *index)
 {
-    GBufferSegment *result;                 /* Trouvaille à retourner      */
+    bool result;                            /* Bilan à retourner           */
     size_t i;                               /* Boucle de parcours          */
     gint width;                             /* Largeur à retirer           */
     bool included;                          /* Appartenance à une largeur ?*/
 
-    result = NULL;
+    result = false;
     *consumed = 0;
 
-    printf(" == gs@ ==   count = %d   width = %d\n",
-           column->count, get_column_width(column));
-
-    for (i = 0; i < column->count && result == NULL; i++)
+    for (i = 0; i < column->count && !result; i++)
     {
         width = g_buffer_segment_get_width(column->segments[i]);
 
-        printf("   -s-  |%d| -> x=%d   w=%d\n", i, *x, width);
-
         /**
          * Soit une limite entre deux segments A et B :
          *
@@ -341,11 +452,15 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x,
         else included = (width > *x);
 
         if (included)
-            result = column->segments[i];
+        {
+            *index = i;
+            result = true;
+        }
 
         else if ((i + 1) == column->count)
         {
-            result = column->segments[i];
+            *index = i;
+            result = true;
             *x = width;
         }
 
@@ -357,7 +472,31 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x,
 
     }
 
-    printf(" == gs@ ==   > segment = %p\n", result);
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : column = colonne de ligne de texte à consulter.              *
+*                index  = indice du contenu à fournir.                        *
+*                                                                             *
+*  Description : Donne le segment d'une colonne présent à un indice donné.    *
+*                                                                             *
+*  Retour      : Segment trouvé ou NULL si hors borne.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GBufferSegment *get_column_content_from_index(const buffer_line_column *column, size_t index)
+{
+    GBufferSegment *result;                 /* Trouvaille à retourner      */
+
+    assert(index < column->count);
+
+    result = column->segments[index];
 
     return result;
 
@@ -413,68 +552,6 @@ static GBufferSegment *find_near_segment(const buffer_line_column *column, GBuff
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : column = colonne de ligne de texte à consulter.              *
-*                                                                             *
-*  Description : Fournit le segment créé par un objet particulier.            *
-*                                                                             *
-*  Retour      : Créateur trouvé à déréférencer par la suite ou NULL si échec.*
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static GObject *find_first_segment_creator(const buffer_line_column *column)
-{
-    GObject *result;                        /* Trouvaille à retourner      */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = NULL;
-
-    for (i = 0; i < column->count && result == NULL; i++)
-        result = g_buffer_segment_get_creator(column->segments[i]);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : column  = colonne de ligne de texte à consulter.             *
-*                creator = créateur à l'origine du segment recherché.         *
-*                                                                             *
-*  Description : Fournit le segment créé par un objet particulier.            *
-*                                                                             *
-*  Retour      : Segment trouvé ou NULL.                                      *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static GBufferSegment *find_segment_from_creator(const buffer_line_column *column, GObject *creator)
-{
-    GBufferSegment *result;                 /* Trouvaille à retourner      */
-    size_t i;                               /* Boucle de parcours #1       */
-    GBufferSegment *iter;                   /* Boucle de parcours #2       */
-
-    result = NULL;
-
-    for (i = 0; i < column->count && result == NULL; i++)
-    {
-        iter = column->segments[i];
-
-        if (g_buffer_segment_get_creator(iter) == creator)
-            result = iter;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : column = colonne de ligne de texte à manipuler.              *
 *                cairo  = contexte graphique à utiliser pour les pinceaux.    *
 *                x_init = abscisse du point d'impression de départ.           *
@@ -660,9 +737,14 @@ static void g_buffer_line_init(GBufferLine *line)
 
 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));
+
     G_OBJECT_CLASS(g_buffer_line_parent_class)->dispose(G_OBJECT(line));
 
 }
@@ -684,6 +766,10 @@ static void g_buffer_line_finalize(GBufferLine *line)
 {
     /* TODO : segments des colonnes... */
 
+
+    if (line->origins != NULL)
+        free(line->origins);
+
     G_OBJECT_CLASS(g_buffer_line_parent_class)->finalize(G_OBJECT(line));
 
 }
@@ -925,10 +1011,17 @@ void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, Memor
 GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *line, BufferLineColumn column)
 {
     GObject *result;                        /* Trouvaille à retourner      */
+    size_t i;                               /* Boucle de parcours          */
 
     assert(column < BLC_COUNT);
 
-    result = find_first_segment_creator(&line->columns[column]);
+    result = NULL;
+
+    for (i = 0; i < line->ocount && result == NULL; i++)
+    {
+        if (line->origins[i].coord.column == column)
+            result = line->origins[i].creator;
+    }
 
     if (result != NULL)
         g_object_ref(G_OBJECT(result));
@@ -954,12 +1047,24 @@ GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *line, Buffe
 GBufferSegment *g_buffer_line_find_segment_from_creator(const GBufferLine *line, GObject *creator)
 {
     GBufferSegment *result;                 /* Trouvaille à retourner      */
-    BufferLineColumn i;                     /* Boucle de parcours          */
+    size_t i;                               /* Boucle de parcours          */
+    const col_coord_t *coord;               /* Emplacement du contenu visé */
 
     result = NULL;
 
-    for (i = 0; i < BLC_COUNT && result == NULL; i++)
-        result = find_segment_from_creator(&line->columns[i], creator);
+    for (i = 0; i < line->ocount; i++)
+    {
+        if (line->origins[i].creator == creator)
+        {
+            coord = &line->origins[i].coord;
+
+            result = get_column_content_from_index(&line->columns[coord->column], coord->index);
+
+            break;
+
+        }
+
+    }
 
     if (result != NULL)
         g_object_ref(G_OBJECT(result));
@@ -1049,6 +1154,57 @@ GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn co
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : line    = ligne à venir compléter.                           *
+*                column  = colonne de la ligne visée par l'insertion.         *
+*                text    = texte à insérer dans l'existant.                   *
+*                length  = taille du texte à traiter.                         *
+*                type    = type de décorateur à utiliser.                     *
+*                creator = instance GLib quelconque à associer.               *
+*                                                                             *
+*  Description : Ajoute du texte à formater dans une ligne donnée.            *
+*                                                                             *
+*  Retour      : Portion de texte mis en place, voire NULL.                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_buffer_line_append_text(GBufferLine *line, BufferLineColumn column, const char *text, size_t length, RenderingTagType type, GObject *creator)
+{
+    size_t index;                           /* Indice d'insertion          */
+    content_origin *origin;                 /* Définition d'une origine    */
+
+    assert(length > 0);
+
+    if (column == BLC_MAIN)
+        column = line->main_column;
+
+    if (column == BLC_LAST_USED)
+        column = line->last_used;
+    else
+        line->last_used = column;
+
+    index = append_text_to_line_column(&line->columns[column], text, length, type);
+
+    if (creator != NULL)
+    {
+        line->origins = (content_origin *)realloc(line->origins, ++line->ocount * sizeof(content_origin));
+
+        origin = &line->origins[line->ocount - 1];
+
+        origin->coord.column = column;
+        origin->coord.index = index;
+
+        origin->creator = creator;
+        g_object_ref(G_OBJECT(creator));
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : line   = ligne à venir consulter.                            *
 *                first  = première colonne à parcourir.                       *
 *                end    = colonne de fin de parcours.                         *
@@ -1444,46 +1600,38 @@ gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn i
 *                offset  = position à la colonne visée. [OUT]                 *
 *                dir     = direction d'un éventuel déplacement en cours.      *
 *                force   = accepte les segments en bordure au pire.           *
+*                coord   = cordonnées à usage interne à renseigner. [OUT]     *
 *                                                                             *
-*  Description : Donne le segment présent à une abscisse donnée.              *
+*  Description : Fournit les coordonnées correspondant à une abscisse donnée. *
 *                                                                             *
-*  Retour      : Segment trouvé ou NULL si hors borne.                        *
+*  Retour      : true si des coordonnées valides ont été renseignées.         *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const line_width_summary *summary, const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force)
+static bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summary *summary, const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force, col_coord_t *coord)
 {
-    GBufferSegment *result;                 /* Trouvaille à retourner      */
+    bool result;                            /* Bilan à retourner           */
     BufferLineColumn last;                  /* Dernière colonne remplie    */
     gint last_base;                         /* Dernière abscisse associée  */
     BufferLineColumn i;                     /* Boucle de parcours          */
     gint width;                             /* Largeur d'une colonne donnée*/
-
-    gint limit;
-
+    gint limit;                             /* Limite d'appartenance       */
     gint consumed;                          /* Distance vers le segment    */
     gint old_base;                          /* Somme de toutes les largeurs*/
 
-    result = NULL;
+    result = false;
 
     *base = 0;
 
     last = BLC_COUNT;
-
-    //sum = 0;
-
-    printf("---------------\n");
+    last_base = 0;
 
     /* On cible déjà la colonne idéale */
 
     for (i = 0; i < BLC_COUNT; i++)
     {
-        printf(" @ (%d) x=%d  width=%d  max=%d  display ? %d\n",
-               i, *offset, get_column_width(&line->columns[i]), summary->max_widths[i], i < BLC_DISPLAY ? display[i] : true);
-
-
         if (i < BLC_DISPLAY && !display[i]) continue;
 
         /* Mémorisation de la dernière colonne contenant quelque chose... */
@@ -1524,19 +1672,11 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const line
 
     }
 
-    printf(" -- get segment at -- found index %u (max=%u)\n", i, BLC_COUNT);
-
-
-    printf("                      last seen = %u\n", last);
-
-
-
-
+    /* Si l'abscisse fournie tombe encore dans une colonne... */
 
     if (i < BLC_COUNT)
     {
-
-        printf(" -- width @ %u : %d\n", i, get_column_width(&line->columns[i]));
+        /* Il y a bien du contenu dans cette colonne */
 
         if (get_column_width(&line->columns[i]) > 0)
         {
@@ -1547,25 +1687,31 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const line
              */
             if (*offset < 0) *offset = 0;
 
-            result = get_segment_at(&line->columns[i], offset, dir, &consumed);
-            *base += consumed;
+            result = get_column_content_index_at(&line->columns[i], offset, dir, &consumed, &coord->index);
+
+            if (result)
+            {
+                coord->column = i;
+
+                *base += consumed;
+
+            }
 
         }
 
         /* La position fournie tombe dans une colonne vide ! */
+
         else
         {
             if (force || get_column_width(&line->columns[i]) == 0)
             {
-                result = NULL;
+                result = false;
                 *offset = 0;
 
                 old_base = *base;
 
-                for (i++; i < BLC_COUNT && result == NULL; i++)
+                for (i++; i < BLC_COUNT && !result; i++)
                 {
-                    printf(" -- update to col %u  -- x = %d\n", i, *offset);
-
                     if ((i - 1) < line->merge_start)
                     {
                         width = g_buffer_line_compute_max_width(line, i - 1, summary);
@@ -1574,13 +1720,14 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const line
                     else
                         *base += get_column_width(&line->columns[i - 1]);
 
-                    result = get_first_segment(&line->columns[i]);
+                    result = get_column_first_content_index(&line->columns[i], &coord->index);
 
-                }
+                    if (result)
+                        coord->column = i;
 
-                printf(" -- final x = %d (result=%p)\n", *offset, result);
+                }
 
-                if (result == NULL)
+                if (!result)
                 {
                     *base = old_base;
                     goto use_right_border;
@@ -1600,16 +1747,109 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const line
 
             if (last != BLC_COUNT)
             {
-                result = get_last_segment(&line->columns[last]);
-                *base = last_base;
-                *offset = get_column_width(&line->columns[last]);
+                result = get_column_last_content_index(&line->columns[last], &coord->index);
+
+                if (result)
+                {
+                    coord->column = last;
+
+                    *base = last_base;
+                    *offset = get_column_width(&line->columns[last]);
+
+                }
+
             }
             else
-                result = NULL;
+                result = false;
 
         }
         else
-            result = NULL;
+            result = false;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line    = ligne à venir consulter.                           *
+*                summary = résumé des largeurs maximales.                     *
+*                display = règles d'affichage des colonnes modulables.        *
+*                base    = position jusqu'au segment trouvé. [OUT]            *
+*                offset  = position à la colonne visée. [OUT]                 *
+*                dir     = direction d'un éventuel déplacement en cours.      *
+*                force   = accepte les segments en bordure au pire.           *
+*                                                                             *
+*  Description : Donne le segment présent à une abscisse donnée.              *
+*                                                                             *
+*  Retour      : Segment trouvé ou NULL si hors borne.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const line_width_summary *summary, const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force)
+{
+    GBufferSegment *result;                 /* Trouvaille à retourner      */
+    col_coord_t coord;                      /* Emplacement du contenu visé */
+    bool status;                            /* Bilan de la localisation    */
+
+    status = g_buffer_line_get_coord_at(line, summary, display, base, offset, dir, force, &coord);
+
+    if (status)
+        result = get_column_content_from_index(&line->columns[coord.column], coord.index);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line    = ligne à venir consulter.                           *
+*                summary = résumé des largeurs maximales.                     *
+*                display = règles d'affichage des colonnes modulables.        *
+*                base    = position jusqu'au segment trouvé. [OUT]            *
+*                offset  = position à la colonne visée. [OUT]                 *
+*                dir     = direction d'un éventuel déplacement en cours.      *
+*                force   = accepte les segments en bordure au pire.           *
+*                                                                             *
+*  Description : Donne le créateur présent à une abscisse donnée.             *
+*                                                                             *
+*  Retour      : Créateur trouvé ou NULL si hors borne.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GObject *g_buffer_line_get_creator_at(const GBufferLine *line, const line_width_summary *summary, const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force)
+{
+    GObject *result;                        /* Trouvaille à retourner      */
+    col_coord_t target;                     /* Emplacement du contenu visé */
+    bool status;                            /* Bilan de la localisation    */
+    size_t i;                               /* Boucle de parcours          */
+    const col_coord_t *coord;               /* Emplacement du contenu visé */
+
+    result = NULL;
+
+    status = g_buffer_line_get_coord_at(line, summary, display, base, offset, dir, force, &target);
+
+    if (status)
+    {
+        for (i = 0; i < line->ocount && result == NULL; i++)
+        {
+            coord = &line->origins[i].coord;
+
+            if (coord->column == target.column && coord->index == target.index)
+                result = line->origins[i].creator;
+
+        }
+
+        if (result != NULL)
+            g_object_ref(G_OBJECT(result));
 
     }
 
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 6b213e3..9403d80 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -121,7 +121,10 @@ GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *, BufferLin
 GBufferSegment *g_buffer_line_find_segment_from_creator(const GBufferLine *, GObject *);
 
 /* Ajoute du texte à formater dans une ligne donnée. */
-GBufferSegment *g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType);
+GBufferSegment *g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType) __attribute__ ((deprecated));
+
+/* Ajoute du texte à formater dans une ligne donnée. */
+void g_buffer_line_append_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType, GObject *);
 
 /* Indique si du texte est présent dans une ligne de tampon. */
 bool g_buffer_line_has_text(const GBufferLine *, BufferLineColumn, BufferLineColumn);
@@ -184,6 +187,9 @@ gint g_buffer_line_compute_max_width(const GBufferLine *, BufferLineColumn, cons
 /* Donne le segment présent à une abscisse donnée. */
 GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const line_width_summary *, const bool *, gint *, gint *, GdkScrollDirection, bool);
 
+/* Donne le créateur présent à une abscisse donnée. */
+GObject *g_buffer_line_get_creator_at(const GBufferLine *, const line_width_summary *, const bool *, gint *, gint *, GdkScrollDirection, bool);
+
 /* Fournit le segment voisin d'un autre segment identifié. */
 GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *, GBufferSegment *, const line_width_summary *, const bool *, GdkScrollDirection, gint *);
 
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
index a2947ae..dfa8c41 100644
--- a/src/glibext/gbuffersegment.c
+++ b/src/glibext/gbuffersegment.c
@@ -141,8 +141,6 @@ struct _GBufferSegment
 
     seg_content *content;                   /* Contenu, partagé ou non     */
 
-    GObject *creator;                       /* Objet à l'origine du segment*/
-
 };
 
 /* Fragment de caractères aux propriétés communes (classe) */
@@ -588,9 +586,6 @@ static void g_buffer_segment_dispose(GBufferSegment *segment)
 {
     release_shared_content(segment->content);
 
-    if (segment->creator != NULL)
-        g_object_unref(segment->creator);
-
     G_OBJECT_CLASS(g_buffer_segment_parent_class)->dispose(G_OBJECT(segment));
 
 }
@@ -647,52 +642,6 @@ GBufferSegment *g_buffer_segment_new(RenderingTagType type, const char *text, si
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : segment = instance de segment à compléter.                   *
-*                obj     = instance GLib quelconque à mémoriser.              *
-*                                                                             *
-*  Description : Associe à un segment un objet GLib identifié comme créateur. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_buffer_segment_set_creator(GBufferSegment *segment, GObject *obj)
-{
-    if (segment->creator != NULL)
-        g_object_unref(segment->creator);
-
-    segment->creator = obj;
-    g_object_ref(obj);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : segment = instance de segment à compléter.                   *
-*                                                                             *
-*  Description : Renvoie vers un éventuel objet lié en tant que créateur.     *
-*                                                                             *
-*  Retour      : Instance GLib quelconque ou NULL si aucune référencée.       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GObject *g_buffer_segment_get_creator(const GBufferSegment *segment)
-{
-    if (segment->creator != NULL)
-        g_object_ref(segment->creator);
-
-    return segment->creator;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : segment = fragment de texte à mettre à jour.                 *
 *                pattern = paramètres d'impression du texte.                  *
 *                text    = chaîne de caractères à traiter.                    *
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
index 911df7b..01fb2ea 100644
--- a/src/glibext/gbuffersegment.h
+++ b/src/glibext/gbuffersegment.h
@@ -115,12 +115,6 @@ GType g_buffer_segment_get_type(void);
 /* Crée un nouveau fragment de texte avec des propriétés. */
 GBufferSegment *g_buffer_segment_new(RenderingTagType, const char *, size_t);
 
-/* Associe à un segment un objet GLib identifié comme créateur. */
-void g_buffer_segment_set_creator(GBufferSegment *, GObject *);
-
-/* Renvoie vers un éventuel objet lié en tant que créateur. */
-GObject *g_buffer_segment_get_creator(const GBufferSegment *);
-
 /* Met à jour le contenu d'un fragment de texte. */
 void g_buffer_segment_update_text(GBufferSegment *, const char *, size_t);
 
diff --git a/src/glibext/gbufferview.c b/src/glibext/gbufferview.c
index cfa521e..2deeffe 100644
--- a/src/glibext/gbufferview.c
+++ b/src/glibext/gbufferview.c
@@ -1266,6 +1266,62 @@ GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *view, gint *x,
 
 /******************************************************************************
 *                                                                             *
+*  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.                            *
 *                addr = adresse à présenter à l'écran.                        *
 *                x    = position horizontale au sein du composant. [OUT]      *
diff --git a/src/glibext/gbufferview.h b/src/glibext/gbufferview.h
index 90c20bb..d5bfd3d 100644
--- a/src/glibext/gbufferview.h
+++ b/src/glibext/gbufferview.h
@@ -104,6 +104,9 @@ 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 *, GBufferSegment **);
 
+/* 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);
 
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index c3c5a78..9961cbc 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -1077,7 +1077,6 @@ static bool _g_code_buffer_write_inlined_comment(GCodeBuffer *buffer, GBufferLin
     char *saveptr;                          /* Sauvegarde pour la sécurité */
     char *token;                            /* Fragment à insérer          */
     size_t len;                             /* Taille dudit fragment       */
-    GBufferSegment *segment;                /* Segment à marquer au fer    */
     GBufferLine *new;                       /* Nouvelle ligne créée        */
     size_t i;                               /* Boucle de parcours          */
 
@@ -1099,17 +1098,13 @@ static bool _g_code_buffer_write_inlined_comment(GCodeBuffer *buffer, GBufferLin
         len = strlen(token);
 
         if (!result)
-        {
-            segment = g_buffer_line_insert_text(line, BLC_COMMENTS, token, len, RTT_COMMENT);
-            g_buffer_segment_set_creator(segment, creator);
-        }
+            g_buffer_line_append_text(line, BLC_COMMENTS, token, len, RTT_COMMENT, creator);
 
         else
         {
             new = g_code_buffer_prepare_new_line(buffer, range);
 
-            segment = g_buffer_line_insert_text(new, BLC_COMMENTS, token, len, RTT_COMMENT);
-            g_buffer_segment_set_creator(segment, creator);
+            g_buffer_line_append_text(new, BLC_COMMENTS, token, len, RTT_COMMENT, creator);
 
             extra = (GBufferLine **)realloc(extra, ++extra_count * sizeof(GBufferLine *));
 
@@ -1201,7 +1196,6 @@ static bool _g_code_buffer_write_comment_area(GCodeBuffer *buffer, GBufferLine *
     char *token;                            /* Fragment à insérer          */
     size_t len;                             /* Taille dudit fragment       */
     GBufferLine *new;                       /* Nouvelle ligne créée        */
-    GBufferSegment *segment;                /* Segment à marquer au fer    */
     size_t i;                               /* Boucle de parcours          */
 
     assert(!g_buffer_line_has_comment(line));
@@ -1224,8 +1218,7 @@ static bool _g_code_buffer_write_comment_area(GCodeBuffer *buffer, GBufferLine *
         new = g_code_buffer_prepare_new_line(buffer, range);
         g_buffer_line_start_merge_at(new, BLC_DISPLAY);
 
-        segment = g_buffer_line_insert_text(new, BLC_DISPLAY, token, len, RTT_COMMENT);
-        g_buffer_segment_set_creator(segment, creator);
+        g_buffer_line_append_text(new, BLC_DISPLAY, token, len, RTT_COMMENT, creator);
 
         extra = (GBufferLine **)realloc(extra, ++extra_count * sizeof(GBufferLine *));
 
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index 2032547..2d1b51c 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -80,7 +80,7 @@ static const vmpa2t *gtk_buffer_view_get_caret_location(const GtkBufferView *);
 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 **, GBufferSegment **);
+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);
@@ -557,11 +557,11 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
 
 static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip *tooltip)
 {
+    gboolean result;                        /* Bilan à retourner           */
     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    */
-    GBufferSegment *segment;                /* Segment actif s'il existe   */
     GObject *creator;                       /* Créateur à l'orgine du seg. */
     virt_t virt;                            /* Adresse virtuelle           */
     vmpa2t addr;                            /* Adresse de destination      */
@@ -579,6 +579,8 @@ static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y,
 
     if (keyboard) return FALSE;
 
+    result = FALSE;
+
     view = GTK_BUFFER_VIEW(widget);
 
     /* Récupération de la destination pointée */
@@ -587,14 +589,11 @@ static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y,
     real_y = y;
     gtk_view_panel_compute_real_coord(GTK_VIEW_PANEL(view), &real_x, &real_y);
 
-    line = g_buffer_view_find_line_and_segment_at(view->buffer_view,
+    line = g_buffer_view_find_line_and_creator_at(view->buffer_view,
                                                   &real_x, real_y, NULL,
-                                                  GTK_VIEW_PANEL(view)->display, &segment);
-
-    if (line == NULL || segment == NULL) goto no_tooltip;
+                                                  GTK_VIEW_PANEL(view)->display, &creator);
 
-    creator = g_buffer_segment_get_creator(segment);
-    if (creator == NULL) goto no_tooltip;
+    if (line == NULL || creator == NULL) goto no_tooltip;
 
     /**
      * On fait le pari de reposer uniquement sur des adresses virtuelles !
@@ -677,14 +676,20 @@ static gboolean gtk_buffer_view_query_tooltip(GtkWidget *widget, gint x, gint y,
 
     /* Impression finale */
 
+    result = TRUE;
+
     gtk_tooltip_set_markup(tooltip, markup);
     free(markup);
 
-    return TRUE;
-
  no_tooltip:
 
-    return FALSE;
+    if (creator != NULL)
+        g_object_unref(creator);
+
+    if (line != NULL)
+        g_object_unref(G_OBJECT(line));
+
+    return result;
 
 }
 
@@ -862,7 +867,7 @@ static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, c
 *                                                                             *
 *  Paramètres  : view    = composant GTK à consulter.                         *
 *                line    = ligne de tampon où se trouve le curseur. [OUT]     *
-*                segment = eventuel segment de ligne actif. [OUT]             *
+*                creator = instance à l'origine de la représentation. [OUT]   *
 *                                                                             *
 *  Description : Fournit des éléments liés à la position courante dans la vue.*
 *                                                                             *
@@ -872,20 +877,20 @@ static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *view, c
 *                                                                             *
 ******************************************************************************/
 
-static bool gtk_buffer_view_get_position(const GtkBufferView *view, GBufferLine **line, GBufferSegment **segment)
+static bool gtk_buffer_view_get_position(const GtkBufferView *view, GBufferLine **line, GObject **creator)
 {
-    GBufferSegment *seg;                    /* Segment à récupérer         */
+    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_segment_at(view->buffer_view,
+    *line = g_buffer_view_find_line_and_creator_at(view->buffer_view,
                                                    (gint []){ view->caret.x }, view->caret.y, NULL,
-                                                   GTK_VIEW_PANEL(view)->display, &seg);
+                                                   GTK_VIEW_PANEL(view)->display, &obj);
 
-    if (segment != NULL)
-        *segment = seg;
+    if (creator != NULL)
+        *creator = obj;
 
     return (line != NULL);
 
diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h
index f827b2c..5e24bec 100644
--- a/src/gtkext/gtkviewpanel-int.h
+++ b/src/gtkext/gtkviewpanel-int.h
@@ -58,7 +58,7 @@ typedef const vmpa2t * (* get_caret_location_fc) (const GtkViewPanel *);
 typedef bool (* get_addr_coordinates_fc) (const GtkViewPanel *, const vmpa2t *, gint *, gint *, ScrollPositionTweak);
 
 /* Fournit des éléments liés à la position courante dans la vue. */
-typedef bool (* get_view_position_fc) (const GtkViewPanel *, GBufferLine **, GBufferSegment **);
+typedef bool (* get_view_position_fc) (const GtkViewPanel *, GBufferLine **, GObject **);
 
 /* Déplace le curseur à un emplacement défini. */
 typedef bool (* move_caret_to_fc) (GtkViewPanel *, gint, gint);
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index a39ea24..b7b58d9 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -1021,24 +1021,24 @@ void gtk_view_panel_request_move(GtkViewPanel *panel, const vmpa2t *addr)
 *                                                                             *
 ******************************************************************************/
 
-bool gtk_view_panel_get_position(const GtkViewPanel *panel, GBufferLine **line, GBufferSegment **segment)
+bool gtk_view_panel_get_position(const GtkViewPanel *panel, GBufferLine **line, GObject **creator)
 {
     bool result;                            /* Bilan de l'opération        */
 
     *line = NULL;
-    if (segment != NULL) *segment = NULL;
+    if (creator != NULL) *creator = NULL;
 
     if (GTK_VIEW_PANEL_GET_CLASS(panel)->get_position == NULL)
         return false;
 
-    result = GTK_VIEW_PANEL_GET_CLASS(panel)->get_position(panel, line, segment);
+    result = GTK_VIEW_PANEL_GET_CLASS(panel)->get_position(panel, line, creator);
 
     if (result)
     {
         g_object_ref(G_OBJECT(*line));
 
-        if (segment != NULL && *segment != NULL)
-            g_object_ref(G_OBJECT(*segment));
+        if (creator != NULL && *creator != NULL)
+            g_object_ref(G_OBJECT(*creator));
 
     }
 
diff --git a/src/gtkext/gtkviewpanel.h b/src/gtkext/gtkviewpanel.h
index 0943dd1..9e198ac 100644
--- a/src/gtkext/gtkviewpanel.h
+++ b/src/gtkext/gtkviewpanel.h
@@ -95,7 +95,7 @@ void _gtk_view_panel_scroll_to_address(GtkViewPanel *, const vmpa2t *, ScrollPos
 void gtk_view_panel_request_move(GtkViewPanel *, const vmpa2t *);
 
 /* Fournit des éléments liés à la position courante dans la vue. */
-bool gtk_view_panel_get_position(const GtkViewPanel *, GBufferLine **, GBufferSegment **);
+bool gtk_view_panel_get_position(const GtkViewPanel *, GBufferLine **, GObject **);
 
 /* Place en cache un rendu destiné à l'aperçu graphique rapide. */
 void gtk_view_panel_cache_glance(GtkViewPanel *, cairo_t *, const GtkAllocation *, double);
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index 0a92e3e..f2742e6 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -246,7 +246,6 @@ void update_access_in_menu_edition(GObject *ref, GtkViewPanel *vpanel, const vmp
     bool state;                             /* Etat principal à considérer */
     gboolean access;                        /* Accès à déterminer          */
     GBufferLine *line;                      /* Ligne de position courante  */
-    GBufferSegment *segment;                /* Segment actif s'il existe   */
     GObject *creator;                       /* Créateur à l'orgine du seg. */
     GtkWidget *item;                        /* Elément de menu à traiter   */
 
@@ -256,15 +255,10 @@ void update_access_in_menu_edition(GObject *ref, GtkViewPanel *vpanel, const vmp
     {
         state = false;
         line = NULL;
-        segment = NULL;
+        creator = NULL;
     }
     else
-        state = gtk_view_panel_get_position(vpanel, &line, &segment);
-
-    if (state)
-        creator = g_buffer_segment_get_creator(segment);
-    else
-        creator = NULL;
+        state = gtk_view_panel_get_position(vpanel, &line, &creator);
 
     /* Bascule des opérandes numériques */
 
@@ -300,8 +294,6 @@ void update_access_in_menu_edition(GObject *ref, GtkViewPanel *vpanel, const vmp
     /* Nettoyage et sortie finale */
 
     if (creator != NULL) g_object_unref(G_OBJECT(creator));
-
-    if (segment != NULL) g_object_unref(G_OBJECT(segment));
     if (line != NULL) g_object_unref(G_OBJECT(line));
 
 }
@@ -365,7 +357,6 @@ static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, GMenuBar *
     GEditorItem *editem;                    /* Autre version de la barre   */
     GtkViewPanel *vpanel;                   /* Afficheur effectif de code  */
     GBufferLine *line;                      /* Ligne de position courante  */
-    GBufferSegment *segment;                /* Segment actif s'il existe   */
     GObject *creator;                       /* Créateur à l'orgine du seg. */
     GDbSwitcher *switcher;                  /* Bascule à mettre en place   */
     const mrange_t *range;                  /* Emplacement de la ligne     */
@@ -379,9 +370,8 @@ static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, GMenuBar *
 
     vpanel = g_editor_item_get_current_view(editem);
 
-    if (gtk_view_panel_get_position(vpanel, &line, &segment))
+    if (gtk_view_panel_get_position(vpanel, &line, &creator))
     {
-        creator = g_buffer_segment_get_creator(segment);
         assert(G_IS_IMM_OPERAND(creator));
 
         range = g_buffer_line_get_range(line);
@@ -399,8 +389,6 @@ static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, GMenuBar *
         g_object_unref(G_OBJECT(proc));
 
         g_object_unref(creator);
-
-        g_object_unref(G_OBJECT(segment));
         g_object_unref(G_OBJECT(line));
 
     }
@@ -444,16 +432,14 @@ static void mcb_edition_follow_ref(GtkMenuItem *menuitem, GMenuBar *bar)
 {
     GtkViewPanel *vpanel;                   /* Afficheur effectif de code  */
     GBufferLine *line;                      /* Ligne de position courante  */
-    GBufferSegment *segment;                /* Segment actif s'il existe   */
     GObject *creator;                       /* Créateur à l'orgine du seg. */
     virt_t virt;                            /* Adresse virtuelle           */
     vmpa2t addr;                            /* Adresse de destination      */
 
     vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar));
 
-    if (gtk_view_panel_get_position(vpanel, &line, &segment))
+    if (gtk_view_panel_get_position(vpanel, &line, &creator))
     {
-        creator = g_buffer_segment_get_creator(segment);
         assert(creator != NULL);
 
         /**
@@ -479,8 +465,6 @@ static void mcb_edition_follow_ref(GtkMenuItem *menuitem, GMenuBar *bar)
         }
 
         g_object_unref(creator);
-
-        g_object_unref(G_OBJECT(segment));
         g_object_unref(G_OBJECT(line));
 
     }
-- 
cgit v0.11.2-87-g4458