summaryrefslogtreecommitdiff
path: root/src/glibext/gbufferview.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glibext/gbufferview.c')
-rw-r--r--src/glibext/gbufferview.c810
1 files changed, 311 insertions, 499 deletions
diff --git a/src/glibext/gbufferview.c b/src/glibext/gbufferview.c
index 20d60ed..cd17191 100644
--- a/src/glibext/gbufferview.c
+++ b/src/glibext/gbufferview.c
@@ -24,14 +24,21 @@
#include "gbufferview.h"
+#include <assert.h>
+
+
/* Vue d'un tampon pour code désassemblé (instance) */
struct _GBufferView
{
GObject parent; /* A laisser en premier */
- GCodeBuffer *buffer; /* Tampon de code visualisé */
+ GBufferCache *cache; /* Tampon du contenu visualisé */
+
+ segcnt_list *highlighted; /* Segments mis en évidence */
+ bool external; /* Note l'origine de la liste */
+ bool unrestricted; /* Validité des informations */
vmpa2t start; /* Première ligne intégrée */
vmpa2t end; /* Dernière ligne intégrée */
@@ -45,11 +52,6 @@ struct _GBufferView
GWidthTracker *tracker; /* Suivi pour usage interne */
};
- bool unrestricted; /* Validité des informations */
-
- segcnt_list *highlighted; /* Segments mis en évidence */
- bool external; /* Note l'origine de la liste */
-
};
/* Vue d'un tampon pour code désassemblé (classe) */
@@ -57,10 +59,6 @@ struct _GBufferViewClass
{
GObjectClass parent; /* A laisser en premier */
- gint line_height; /* Hauteur maximale des lignes */
- gint left_margin; /* Marge gauche + espace */
- gint left_text; /* Début d'impression du code */
-
/* Signaux */
void (* need_redraw) (GBufferView *);
@@ -81,15 +79,23 @@ static void g_buffer_view_dispose(GBufferView *);
static void g_buffer_view_finalize(GBufferView *);
/* Accompagne une variation de la quantité de lignes du tampon. */
-static void on_buffer_size_changed(const GCodeBuffer *, bool, size_t, size_t, GBufferView *);
+static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, GBufferView *);
-/* Réagit à un changement de contenu d'une ligne donnée. */
-static void on_buffer_line_changed(GCodeBuffer *, GBufferLine *, line_segment *, GBufferView *);
+/* Calcule la position idéale de curseur pour un point donné. */
+bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const bool *, GdkRectangle *, vmpa2t *);
/* Déplace le curseur au sein d'une vue de tampon. */
static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, GdkRectangle *, bool, GdkScrollDirection, const bool *);
+/* Fournit la ligne présente à une ordonnée donnée. */
+static GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *);
+
+
+
+
+
+
/* Détermine le type de la vue d'un tampon pour code désassemblé. */
G_DEFINE_TYPE(GBufferView, g_buffer_view, G_TYPE_OBJECT);
@@ -116,10 +122,7 @@ static void g_buffer_view_class_init(GBufferViewClass *class)
object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_view_dispose;
object->finalize = (GObjectFinalizeFunc)g_buffer_view_finalize;
- class->line_height = 17;
- class->left_margin = 2 * class->line_height;
- class->left_text = 2.5 * class->line_height;
-
+ /* Sigaux */
g_signal_new("need-redraw",
G_TYPE_BUFFER_VIEW,
@@ -146,7 +149,10 @@ static void g_buffer_view_class_init(GBufferViewClass *class)
static void g_buffer_view_init(GBufferView *view)
{
- view->unrestricted = true;
+ /**
+ * Inversion du statut pour forcer l'actualisation lors de la création.
+ */
+ view->unrestricted = false;
}
@@ -165,7 +171,10 @@ static void g_buffer_view_init(GBufferView *view)
static void g_buffer_view_dispose(GBufferView *view)
{
- g_object_unref(G_OBJECT(view->buffer));
+ g_object_unref(G_OBJECT(view->cache));
+
+ if (!view->unrestricted)
+ g_object_unref(G_OBJECT(view->int_tracker));
G_OBJECT_CLASS(g_buffer_view_parent_class)->dispose(G_OBJECT(view));
@@ -207,22 +216,17 @@ static void g_buffer_view_finalize(GBufferView *view)
* *
******************************************************************************/
-GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
+GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted)
{
GBufferView *result; /* Composant à retourner */
result = g_object_new(G_TYPE_BUFFER_VIEW, NULL);
- g_object_ref(G_OBJECT(buffer));
- result->buffer = buffer;
+ result->cache = cache;
g_buffer_view_restrict(result, NULL, NULL);
- g_code_buffer_register_view_callback(buffer,
- (buffer_size_changed_cb)on_buffer_size_changed,
- G_OBJECT(result));
-
- g_signal_connect(buffer, "line-changed", G_CALLBACK(on_buffer_line_changed), result);
+ g_signal_connect(cache, "size-changed", G_CALLBACK(on_buffer_cache_size_changed), result);
if (highlighted != NULL)
result->highlighted = highlighted;
@@ -238,11 +242,11 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
/******************************************************************************
* *
-* Paramètres : buffer = tampon de lignes cohérentes à manipuler. *
-* added = indication sur la variation de la taille du tampon. *
-* index = indice de la première ligne à traiter. *
-* count = nombre de lignes à traiter. *
-* view = vue active du tampon de lignes concerné. *
+* Paramètres : cache = tampon de lignes cohérentes à manipuler. *
+* added = indication sur la variation de la taille du tampon. *
+* index = indice de la première ligne à traiter. *
+* count = nombre de lignes à traiter. *
+* view = vue active du tampon de lignes concerné. *
* *
* Description : Accompagne une variation de la quantité de lignes du tampon. *
* *
@@ -252,11 +256,11 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
* *
******************************************************************************/
-static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t index, size_t count, GBufferView *view)
+static void on_buffer_cache_size_changed(const GBufferCache *cache, bool added, size_t index, size_t count, GBufferView *view)
{
- size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne à manipuler */
- const vmpa2t *addr; /* Localisation de ligne */
+ //size_t i; /* Boucle de parcours */
+ //GBufferLine *line; /* Ligne à manipuler */
+ //const vmpa2t *addr; /* Localisation de ligne */
/**
* Il n'y a pas besoin de verrou ici car la fonction est appelée directement par le tampon.
@@ -270,6 +274,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
else
{
+#if 0
+
/* Avant la zone représentée ? */
if (index < view->first)
{
@@ -281,6 +287,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
else if (view->first == index)
for (i = 0; i < count; i++)
{
+ g_buffer_cache_get_line_addr(const GBufferCache *, size_t, gint, vmpa2t *);
+
line = g_code_buffer_find_line_by_index(buffer, index + i);
addr = get_mrange_addr(g_buffer_line_get_range(line));
@@ -302,6 +310,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
else if ((view->last + 1) == index)
for (i = 0; i < count; i++)
{
+ g_buffer_cache_get_line_addr(const GBufferCache *, size_t, gint, vmpa2t *);
+
line = g_code_buffer_find_line_by_index(buffer, index + i);
addr = get_mrange_addr(g_buffer_line_get_range(line));
@@ -312,7 +322,8 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
}
- g_width_tracker_update_added(view->int_tracker, index, count);
+ //g_width_tracker_update_added(view->int_tracker, index, count);
+#endif
}
@@ -338,38 +349,36 @@ static void on_buffer_size_changed(const GCodeBuffer *buffer, bool added, size_t
}
- g_width_tracker_update_deleted(view->int_tracker, index, index + count - 1);
+ //g_width_tracker_update_deleted(view->int_tracker, index, index + count - 1);
}
- g_signal_emit_by_name(view, "need-redraw");
+ //g_signal_emit_by_name(view, "need-redraw");
}
/******************************************************************************
* *
-* Paramètres : buffer = tampon de lignes cohérentes à manipuler. *
-* line = ligne dont la définition vient d'évoluer. *
-* segment = éventuel segment qui vient d'évoluer ou NULL. *
-* view = vue active du tampon de lignes concerné. *
+* Paramètres : view = visualisateur à consulter. *
* *
-* Description : Réagit à un changement de contenu d'une ligne donnée. *
+* Description : Fournit le tampon de code lié à un visualisateur donné. *
* *
-* Retour : - *
+* Retour : Tampon de code associé au gestionnaire d'affichage. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, line_segment *segment, GBufferView *view)
+GBufferCache *g_buffer_view_get_cache(const GBufferView *view)
{
- const vmpa2t *addr; /* Localisation de ligne */
+ GBufferCache *result; /* Instance à retourner */
- addr = get_mrange_addr(g_buffer_line_get_range(line));
+ result = view->cache;
- if (cmp_vmpa(&view->start, addr) <= 0 && cmp_vmpa(addr, &view->end) <= 0)
- g_signal_emit_by_name(view, "need-redraw");
+ g_object_ref(G_OBJECT(result));
+
+ return result;
}
@@ -390,33 +399,41 @@ static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, line_
void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t *end)
{
+ bool state; /* Nouvel état à proclamer */
const GWidthTracker *template; /* Suivi déjà en place */
- if (!view->unrestricted)
- g_object_unref(G_OBJECT(view->int_tracker));
+ state = (start == NULL || end == NULL);
- view->unrestricted = (start == NULL || end == NULL);
+ if (view->unrestricted != state)
+ {
+ view->unrestricted = state;
- template = g_code_buffer_get_width_tracker(view->buffer);
+ template = g_buffer_cache_get_width_tracker(view->cache);
- if (view->unrestricted)
- {
- view->first = 0;
- view->last = g_code_buffer_count_lines(view->buffer) - 1;
+ if (view->unrestricted)
+ {
+ /* Vérification pour le cas particulier du démarrage */
+ if (view->int_tracker != NULL)
+ g_object_unref(G_OBJECT(view->int_tracker));
- view->ext_tracker = template;
+ view->first = 0;
+ view->last = g_buffer_cache_count_lines(view->cache) - 1;
- }
+ view->ext_tracker = template;
- else
- {
- copy_vmpa(&view->start, start);
- copy_vmpa(&view->end, end);
+ }
+
+ else
+ {
+ copy_vmpa(&view->start, start);
+ copy_vmpa(&view->end, end);
+
+ view->first = g_buffer_cache_find_index_by_addr(view->cache, start, true);
+ view->last = g_buffer_cache_find_index_by_addr(view->cache, end, false);
- view->first = g_code_buffer_get_index_from_address(view->buffer, start, true);
- view->last = g_code_buffer_get_index_from_address(view->buffer, end, false);
+ view->ext_tracker = g_width_tracker_new_restricted(template, view->first, view->last);
- view->ext_tracker = g_width_tracker_new_restricted(template, view->first, view->last);
+ }
}
@@ -425,7 +442,7 @@ void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t
/******************************************************************************
* *
-* Paramètres : view = visualisateur à mettre à jour. *
+* Paramètres : view = visualisateur à consulter. *
* first = première ligne à imprimer ou NULL. [OUT] *
* last = première ligne hors cadre ou NULL. [OUT] *
* *
@@ -437,7 +454,7 @@ void g_buffer_view_restrict(GBufferView *view, const vmpa2t *start, const vmpa2t
* *
******************************************************************************/
-bool g_buffer_view_get_restrictions(GBufferView *view, vmpa2t *start, vmpa2t *end)
+bool g_buffer_view_get_restrictions(const GBufferView *view, vmpa2t *start, vmpa2t *end)
{
if (!view->unrestricted)
{
@@ -450,44 +467,11 @@ bool g_buffer_view_get_restrictions(GBufferView *view, vmpa2t *start, vmpa2t *en
}
-/******************************************************************************
-* *
-* Paramètres : view = visualisateur à consulter. *
-* *
-* Description : Fournit le tampon de code lié à un visualisateur donné. *
-* *
-* Retour : Tampon de code associé au gestionnaire d'affichage. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *view)
-{
- g_object_ref(G_OBJECT(view->buffer));
-
- return view->buffer;
-}
-/******************************************************************************
-* *
-* Paramètres : view = visualisation à consulter. *
-* *
-* Description : Fournit la hauteur d'impression d'une ligne visualisée. *
-* *
-* Retour : Hauteur de ligne en pixel. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-gint g_buffer_view_get_line_height(GBufferView *view)
-{
- return G_BUFFER_VIEW_GET_CLASS(view)->line_height;
-}
/******************************************************************************
@@ -507,7 +491,7 @@ gint g_buffer_view_get_width(GBufferView *view, const bool *display)
{
gint result; /* Taille à retourner */
- result = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
+ result = g_buffer_cache_get_text_position(view->cache);
result += g_width_tracker_get_width(view->tracker, display);
@@ -533,7 +517,7 @@ gint g_buffer_view_get_margin(GBufferView *view, const bool *display)
{
gint result; /* Taille à retourner */
- result = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
+ result = g_buffer_cache_get_text_position(view->cache);
result += g_width_tracker_get_margin(view->tracker, display);
@@ -558,7 +542,7 @@ gint g_buffer_view_get_height(const GBufferView *view)
{
gint result; /* Taille à retourner */
- result = G_BUFFER_VIEW_GET_CLASS(view)->line_height;
+ result = g_buffer_cache_get_line_height(view->cache);
result *= (view->last - view->first + 1);
@@ -567,50 +551,66 @@ gint g_buffer_view_get_height(const GBufferView *view)
}
+
+
+
+
+
+
+
+
+
+
+
/******************************************************************************
* *
* Paramètres : view = vue de tampon à mettre à jour. *
-* x = abscisse de la zone principale à traiter. *
-* y = ordonnée de la zone principale à traiter. *
+* x = abscisse proposée pour le nouvel emplacement. *
+* y = ordonnée proposée pour le nouvel emplacement. *
* display = règles d'affichage des colonnes modulables. *
* caret = position du curseur à construire. [OUT] *
+* addr = adresse correspondant à cette même position. [OUT] *
* *
* Description : Calcule la position idéale de curseur pour un point donné. *
* *
-* Retour : Adresse si une a pu être déterminée, NULL sinon. *
+* Retour : true si les deux derniers arguments ont pu être constitués. *
* *
* Remarques : - *
* *
******************************************************************************/
-const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, const bool *display, GdkRectangle *caret)
+bool g_buffer_view_compute_caret_full(GBufferView *view, gint x, gint y, const bool *display, GdkRectangle *caret, vmpa2t *addr)
{
- gint remaining; /* Copie de travail modifiable */
+ bool result; /* Bilan à retourner */
+ gint lheight; /* Hauteur d'une ligne */
size_t index; /* Indice de ligne de tampon */
GBufferLine *line; /* Ligne à la position courante*/
- const line_segment *segment; /* Segment présent sur la place*/
- GBufferViewClass *class; /* Classe pour les vues */
- remaining = x;
+ result = false;
- line = g_buffer_view_find_line_and_segment_at(view, &remaining, y, &index, display, &segment);
+ /* Détermination de la ligne courante */
- /* FIXME : unref() ! */
- if (line == NULL) return NULL;
- if (segment == NULL) printf(" -- no segment\n");
- if (segment == NULL) return NULL;
+ lheight = g_buffer_cache_get_line_height(view->cache);
+ index = y / lheight;
+ index += view->first;
- class = G_BUFFER_VIEW_GET_CLASS(view);
+ if (index > view->last)
+ goto gbvccf_done;
- caret->x = /*view->left_text +*/ (x - remaining) + get_caret_position_from_line_segment(segment, remaining);
+ line = g_buffer_cache_find_line_by_index(view->cache, index);
- caret->y = (index - view->first) * class->line_height;
+ assert(line != NULL);
- caret->width = 2;
- caret->height = class->line_height;
+ /* Calcul d'une position */
+
+ result = _g_buffer_view_compute_caret_full(view, x, line, index, display, caret, addr);
+
+ g_object_unref(G_OBJECT(line));
+
+ gbvccf_done:
- return get_mrange_addr(g_buffer_line_get_range(line));
+ return result;
}
@@ -618,50 +618,69 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, con
/******************************************************************************
* *
* Paramètres : view = vue de tampon à mettre à jour. *
+* x = abscisse proposée pour le nouvel emplacement. *
* line = ligne correspondant à la position. *
* index = indice de cette même ligne dans le tampon. *
-* x = abscisse de la zone principale à traiter. *
* display = règles d'affichage des colonnes modulables. *
* caret = position du curseur à construire. [OUT] *
+* addr = adresse correspondant à cette même position. [OUT] *
* *
* Description : Calcule la position idéale de curseur pour un point donné. *
* *
-* Retour : Adresse si une a pu être déterminée, NULL sinon. *
+* Retour : true si les deux derniers arguments ont pu être constitués. *
* *
* Remarques : - *
* *
******************************************************************************/
-const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *line, size_t index, gint x, const bool *display, GdkRectangle *caret)
+bool _g_buffer_view_compute_caret_full(GBufferView *view, gint x, GBufferLine *line, size_t index, const bool *display, GdkRectangle *caret, vmpa2t *addr)
{
- GBufferViewClass *class; /* Classe pour les vues */
- gint offset; /* Point de travail modifiable */
+ bool result; /* Bilan à retourner */
+ gint text_pos; /* Abscisse de départ du texte */
line_width_summary summary; /* Résumé concis des largeurs */
gint base; /* Position absolue de segment */
bool status; /* Bilan de la localisation */
+ gint lheight; /* Hauteur d'une ligne */
- class = G_BUFFER_VIEW_GET_CLASS(view);
+ result = false;
- offset = x;
+ /* Zone d'intervention bornée ! */
- offset -= class->left_text;
- if (offset < 0) return NULL;
+ text_pos = g_buffer_cache_get_text_position(view->cache);
+
+ if (x < text_pos)
+ goto gbvccf_done;
+
+ /* Calcul d'une position */
g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
- /* Traitement pour mise à jour de l'abscisse uniquement */
- status = g_buffer_line_get_coord_at(line, &summary, display, &base, &offset,
+ x -= text_pos;
+
+ status = g_buffer_line_get_coord_at(line, &summary, display, &base, &x,
GDK_SCROLL_LEFT, true, (col_coord_t []) { { 0 } });
- if (!status) return NULL;
- caret->x = class->left_text + base + offset;
+ if (!status)
+ goto gbvccf_done;
+
+ /* Transmission des informations */
+
+ lheight = g_buffer_cache_get_line_height(view->cache);
- caret->y = (index - view->first) * class->line_height;
+ caret->x = text_pos + base + x;
+
+ caret->y = (index - view->first) * lheight;
caret->width = 2;
- caret->height = class->line_height;
+ caret->height = lheight;
+
+ g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+
+ result = true;
- return get_mrange_addr(g_buffer_line_get_range(line));
+ gbvccf_done:
+
+ return result;
}
@@ -687,16 +706,24 @@ const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *l
static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line, size_t index, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display)
{
bool result; /* Bilan à retourner */
+ gint text_pos; /* Abscisse de départ du texte */
gint offset; /* Point de travail modifiable */
line_width_summary summary; /* Résumé concis des largeurs */
gint base; /* Position absolue de segment */
col_coord_t coord; /* Coordonnées en interne */
const line_segment *segment; /* Bribe de texte trouvée */
- offset = caret->x;
- offset -= G_BUFFER_VIEW_GET_CLASS(view)->left_text;
- if (offset < 0) return false;
+ result = false;
+
+ /* Zone d'intervention bornée ! */
+
+ text_pos = g_buffer_cache_get_text_position(view->cache);
+
+ if (caret->x < text_pos)
+ goto gbvmc_done;
+
+ offset = caret->x - text_pos;
g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
@@ -725,7 +752,9 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
/* Mise à jour éventuelle */
if (result)
- caret->x = G_BUFFER_VIEW_GET_CLASS(view)->left_text + base + offset;
+ caret->x = text_pos + base + offset;
+
+ gbvmc_done:
return result;
@@ -735,82 +764,35 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
/******************************************************************************
* *
* Paramètres : view = vue de tampon à mettre à jour. *
-* caret = position du curseur à faire évoluer. *
* ctrl = indique la demande d'un parcours rapide. *
* dir = direction du parcours. *
* display = règles d'affichage des colonnes modulables. *
+* caret = position du curseur à faire évoluer. [OUT] *
+* addr = adresse correspondant à cette même position. [OUT] *
* *
* Description : Déplace le curseur au sein d'une vue de tampon. *
* *
-* Retour : Adresse si une a pu être déterminée, VMPA_INVALID sinon. *
+* Retour : true si les deux derniers arguments ont pu être constitués. *
* *
* Remarques : - *
* *
******************************************************************************/
-const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display)
+bool g_buffer_view_move_caret(GBufferView *view, bool ctrl, GdkScrollDirection dir, const bool *display, GdkRectangle *caret, vmpa2t *addr)
{
- const vmpa2t *result; /* Actualisation à renvoyer */
+ bool result; /* Bilan à retourner */
size_t index; /* Indice de ligne de tampon */
GBufferLine *line; /* Ligne sous le pointeur */
-
-
- line_width_summary summary; /* Résumé concis des largeurs */
- gint left_pos; /* Retour à la ligne */
- gint right_pos; /* Position d'extrème droite */
- BufferLineColumn i; /* Boucle de parcours */
size_t first; /* Première ligne intégrée */
size_t last; /* Dernière ligne intégrée */
-
-
-
-
+ GBufferLine *other; /* Ligne voisine à visiter */
bool moved; /* Mémorisation d'une évolut° */
+ gint text_pos; /* Abscisse de départ du texte */
-
-
-
-
-
-
-
-
- result = NULL;
-
-
+ result = false;
line = g_buffer_view_find_line_at(view, caret->y, &index);
- if (line == NULL) return NULL;
-
- g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
-
- switch (dir)
- {
- case GDK_SCROLL_UP:
- case GDK_SCROLL_DOWN:
- break;
- case GDK_SCROLL_LEFT:
- case GDK_SCROLL_RIGHT:
- left_pos = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
- if (display[BLC_PHYSICAL]) left_pos += summary.max_widths[BLC_PHYSICAL] + COL_MARGIN;
- if (display[BLC_VIRTUAL]) left_pos += summary.max_widths[BLC_VIRTUAL] + COL_MARGIN;
- if (display[BLC_BINARY]) left_pos += summary.max_widths[BLC_BINARY] + COL_MARGIN;
- right_pos = left_pos;
- for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++)
- right_pos += summary.max_widths[i] + COL_MARGIN;
-
- /*
-gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn index, const gint *max_widths)
-
-BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
- */
-
- left_pos = G_BUFFER_VIEW_GET_CLASS(view)->left_text;
-
- break;
- default: /* GDK_SCROLL_SMOOTH */
- break;
- }
+ if (line == NULL) goto gbvmc_done;
first = view->first;
last = view->last;
@@ -821,8 +803,12 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
if (index > first)
{
- line = g_code_buffer_find_line_by_index(view->buffer, index - 1);
- result = g_buffer_view_compute_caret_full(view, line, index - 1, caret->x, display, caret);
+ index--;
+
+ other = g_buffer_cache_find_line_by_index(view->cache, index);
+ result = _g_buffer_view_compute_caret_full(view, caret->x, other, index, display, caret, addr);
+ g_object_unref(G_OBJECT(other));
+
}
break;
@@ -831,48 +817,58 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
if (index < last)
{
- line = g_code_buffer_find_line_by_index(view->buffer, index + 1);
- result = g_buffer_view_compute_caret_full(view, line, index + 1, caret->x, display, caret);
+ index++;
+
+ other = g_buffer_cache_find_line_by_index(view->cache, index);
+ result = _g_buffer_view_compute_caret_full(view, caret->x, other, index, display, caret, addr);
+ g_object_unref(G_OBJECT(other));
+
}
break;
case GDK_SCROLL_LEFT:
- /*
- line = g_buffer_view_find_line_at(view, caret->y, &index);
- if (line == NULL) break;
- */
-
moved = _g_buffer_view_move_caret(view, line, index, caret, ctrl, GDK_SCROLL_LEFT, display);
if (moved)
- result = get_mrange_addr(g_buffer_line_get_range(line));
+ {
+ g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+ result = true;
+ }
else if (index > first)
{
- line = g_code_buffer_find_line_by_index(view->buffer, index - 1);
- result = g_buffer_view_compute_caret_full(view, line, index - 1, INT_MAX, display, caret);
+ index--;
+
+ other = g_buffer_cache_find_line_by_index(view->cache, index);
+ result = _g_buffer_view_compute_caret_full(view, INT_MAX, other, index, display, caret, addr);
+ g_object_unref(G_OBJECT(other));
+
}
break;
case GDK_SCROLL_RIGHT:
- /*
- line = g_buffer_view_find_line_at(view, caret->y, &index);
- if (line == NULL) break;
- */
-
moved = _g_buffer_view_move_caret(view, line, index, caret, ctrl, GDK_SCROLL_RIGHT, display);
if (moved)
- result = get_mrange_addr(g_buffer_line_get_range(line));
+ {
+ g_buffer_cache_get_line_addr(view->cache, index, caret->x, addr);
+ result = true;
+ }
else if (index < last)
{
- line = g_code_buffer_find_line_by_index(view->buffer, index + 1);
- result = g_buffer_view_compute_caret_full(view, line, index + 1, left_pos, display, caret);
+ index++;
+
+ text_pos = g_buffer_cache_get_text_position(view->cache);
+
+ other = g_buffer_cache_find_line_by_index(view->cache, index);
+ result = _g_buffer_view_compute_caret_full(view, text_pos, other, index, display, caret, addr);
+ g_object_unref(G_OBJECT(other));
+
}
break;
@@ -882,11 +878,27 @@ BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line)
}
+ g_object_unref(G_OBJECT(line));
+
+ gbvmc_done:
+
return result;
}
+
+
+
+
+
+
+
+
+
+
+
+
/******************************************************************************
* *
* Paramètres : view = vue de tampon à mettre à jour. *
@@ -927,23 +939,64 @@ bool g_buffer_view_unhighlight_segments(GBufferView *view)
bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const bool *display)
{
- bool need_redraw; /* Besoin d'actualisation ? */
+ bool result; /* Besoin à faire remonter */
+ gint text_pos; /* Abscisse de départ du texte */
+ gint lheight; /* Hauteur d'une ligne */
+ size_t index; /* Indice de ligne de tampon */
+ GBufferLine *line; /* Ligne à la position courante*/
+ line_width_summary summary; /* Résumé concis des largeurs */
const line_segment *segment; /* Segment sélectionnable */
+ /* Réinitialisation */
+
if (view->highlighted != NULL)
- need_redraw = g_buffer_view_unhighlight_segments(view);
+ result = g_buffer_view_unhighlight_segments(view);
else
- need_redraw = false;
+ result = false;
+
+ /* Zone d'intervention bornée ! */
+
+ text_pos = g_buffer_cache_get_text_position(view->cache);
+
+ if (x < text_pos)
+ goto gbvhs_done;
+
+ /* Détermination de la ligne concernée */
- g_buffer_view_find_line_and_segment_at(view, &x, y, NULL, display, &segment);
+ lheight = g_buffer_cache_get_line_height(view->cache);
+ index = y / lheight;
+
+ index += view->first;
+
+ if (index > view->last)
+ goto gbvhs_done;
+
+ line = g_buffer_cache_find_line_by_index(view->cache, index);
+
+ assert(line != NULL);
+
+ /* Recherche d'un segment et de son empreinte */
+
+ g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
+
+ x -= text_pos;
+
+ segment = g_buffer_line_get_segment_at(line, &summary, display,
+ (gint []) { 0 }, &x, GDK_SCROLL_LEFT, true);
- if (segment)
- need_redraw |= add_segment_content_to_selection_list(view->highlighted, segment);
+ g_object_unref(G_OBJECT(line));
- if (need_redraw)
+ /* Conclusion */
+
+ if (segment != NULL)
+ result |= add_segment_content_to_selection_list(view->highlighted, segment);
+
+ if (result)
g_signal_emit_by_name(view, "need-redraw");
- return true;
+ gbvhs_done:
+
+ return result;
}
@@ -952,13 +1005,12 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const b
* *
* Paramètres : view = visualisation à représenter. *
* cr = contexte graphique dédié à la procédure. *
-* fake_x = abscisse réelle du point 0 à l'écran. *
-* fake_y = ordonnée réelle du point 0 à l'écran. *
+* virt_y = ordonnée réelle du point 0 à l'écran. *
* area = position et surface à traiter. *
* display = règles d'affichage des colonnes modulables. *
* selected = ordonnée d'une ligne sélectionnée ou NULL. *
* *
-* Description : Imprime la visualisation du tampon de code désassemblé. *
+* Description : Imprime la visualisation du tampon de lignes quelconques. *
* *
* Retour : - *
* *
@@ -966,148 +1018,57 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const b
* *
******************************************************************************/
-void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint fake_x, gint fake_y, const cairo_rectangle_int_t *area, const bool *display, const gint *selected)
+void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint virt_y, const cairo_rectangle_int_t *area, const bool *display, gint *selected)
{
- GBufferViewClass *class; /* Classe pour les vues */
- gint real_x; /* Abscisse réelle pour tampon */
- gint real_y; /* Ordonnée réelle pour tampon */
+ gint line_height; /* Hauteur d'une ligne */
+ gint cr_y; /* Ordonnée pour le dessin */
size_t first; /* Première ligne visée */
- size_t last; /* Dernière ligne visée + 1 */
- gint y; /* Point de départ + décallage */
- bool wait_selection; /* Sélection déjà passée ? */
- gint rel_selected; /* Position relative de sélect°*/
- size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne à dessiner à l'écran */
- line_width_summary summary; /* Résumé concis des largeurs */
+ size_t last; /* Dernière ligne visée */
- class = G_BUFFER_VIEW_GET_CLASS(view);
+ line_height = g_buffer_cache_get_line_height(view->cache);
- real_x = fake_x + class->left_text;
- real_y = fake_y + area->y;
+ /* Indice et point de départ */
first = view->first;
- first += (real_y / class->line_height);
-
- last = first + (area->height / class->line_height);
- if (area->height % class->line_height > 0) last++;
-
- last = MIN(last, view->last);
-
- y = area->y - (real_y % class->line_height);
-
- wait_selection = true;
+ first += (virt_y / line_height);
- if (selected != NULL)
- rel_selected = *selected - fake_y;
-
- if (g_code_buffer_count_lines(view->buffer) > 0)
- for (i = first; i <= last; i++)
- {
- /* Si sélection, on sousligne la ligne concernée */
- if (wait_selection && selected != NULL && rel_selected == y)
- {
- cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.05);
+ cr_y = area->y - (virt_y % line_height);
- cairo_rectangle(cr, area->x, y, area->width, class->line_height);
- cairo_fill(cr);
+ /* Indice de d'arrivée */
- wait_selection = false;
+ last = first + (area->height / line_height);
+ if (area->height % line_height > 0) last++;
- }
+ last = MIN(last, view->last);
- line = g_code_buffer_find_line_by_index(view->buffer, i);
+ /* Phase de dessin ! */
- if (i == first || (g_buffer_line_get_flags(line) & BLF_WIDTH_MANAGER))
- g_width_tracker_get_local_width_summary(view->tracker, i, &summary);
+ /**
+ * Le contexte n'est pas sauvegardé avant modification ici car
+ * l'appelant l'a fait pour nous avant sa translation sur les abscisses.
+ */
- g_buffer_line_draw(line, cr, &summary, real_x, y, display, view->highlighted);
+ cairo_translate(cr, 0, cr_y);
- y += class->line_height;
+ if (selected != NULL)
+ *selected -= cr_y;
- }
+ g_buffer_cache_draw(view->cache, cr, first, last, area, display, selected, view->highlighted);
}
-/******************************************************************************
-* *
-* Paramètres : view = visualisation à consulter. *
-* addr = adresse où retrouver la ligne recherchée. *
-* flags = propriétés à vérifier en tout ou partie. *
-* idx = indice de la ligne trouvée ou NULL. [OUT] *
-* *
-* Description : Retrouve une ligne au sein d'un tampon avec une adresse. *
-* *
-* Retour : Line retrouvée ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_by_addr(const GBufferView *view, const vmpa2t *addr, BufferLineFlags flags, size_t *idx)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
- phys_t length; /* Taille de la vue */
- mrange_t vrange; /* Couverture de la vue */
- bool allowed; /* Rechercher validée ? */
-
- /* Vérification des bornes */
-
- if (!view->unrestricted)
- {
- length = compute_vmpa_diff(&view->start, &view->end);
- init_mrange(&vrange, &view->start, length);
- allowed = mrange_contains_addr_inclusive(&vrange, addr);
- }
- else allowed = true;
- /* Lancement des recherches ? */
- if (allowed)
- result = g_code_buffer_find_line_by_addr(view->buffer, addr, flags, idx);
- else
- result = NULL;
- return result;
-
-}
-/******************************************************************************
-* *
-* Paramètres : view = visualisation à consulter. *
-* index = indice de la ligne recherchée. *
-* *
-* Description : Retrouve une ligne au sein d'un tampon avec un indice. *
-* *
-* Retour : Line retrouvée ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *view, size_t index)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
- bool allowed; /* Rechercher validée ? */
- /* Vérification des bornes */
- allowed = (view->first <= index && index <= view->last);
- /* Lancement des recherches ? */
-
- if (allowed)
- result = g_code_buffer_find_line_by_index(view->buffer, index);
- else
- result = NULL;
-
- return result;
-
-}
/******************************************************************************
@@ -1124,19 +1085,19 @@ GBufferLine *g_buffer_view_find_line_by_index(const GBufferView *view, size_t in
* *
******************************************************************************/
-GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
+static GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
{
GBufferLine *result; /* Ligne trouvée à retourner */
gint lheight; /* Hauteur d'une ligne */
size_t index; /* Indice attendu */
- lheight = g_buffer_view_get_line_height(view);
+ lheight = g_buffer_cache_get_line_height(view->cache);
index = y / lheight;
index += view->first;
if (index <= view->last)
- result = g_code_buffer_find_line_by_index(view->buffer, index);
+ result = g_buffer_cache_find_line_by_index(view->cache, index);
else
result = NULL;
@@ -1148,125 +1109,26 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
}
-/******************************************************************************
-* *
-* Paramètres : view = visualisation à consulter. *
-* x = abscisse comprise dans le segment recherché. [OUT] *
-* y = ordonnée comprise dans la ligne recherchée. *
-* idx = indice de la ligne trouvée ou NULL. [OUT] *
-* display = règles d'affichage des colonnes modulables. *
-* segment = portion de texte recherchée ou NULL. [OUT] *
-* *
-* Description : Fournit la ligne et son segment présents à une position. *
-* *
-* Retour : Ligne retrouvée ou NULL si aucune. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, const line_segment **segment)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
- size_t index; /* Indice de la ligne trouvée */
- GBufferViewClass *class; /* Classe pour les vues */
- line_width_summary summary; /* Résumé concis des largeurs */
-
- /* Recherche d'une ligne correspondante */
- result = g_buffer_view_find_line_at(view, y, &index);
- if (idx != NULL) *idx = index;
- /* Recherche du segment visé éventuel */
- if (result != NULL && segment != NULL)
- {
- class = G_BUFFER_VIEW_GET_CLASS(view);
- if (*x < class->left_text)
- *segment = NULL;
- else
- {
- g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
- *x -= class->left_text;
- *segment = g_buffer_line_get_segment_at(result, &summary, display,
- (gint []) { 0 }, x, GDK_SCROLL_LEFT, true);
- }
- }
- return result;
-}
/******************************************************************************
* *
-* Paramètres : view = visualisation à consulter. *
-* x = abscisse comprise dans le segment recherché. [OUT] *
-* y = ordonnée comprise dans la ligne recherchée. *
-* idx = indice de la ligne trouvée ou NULL. [OUT] *
-* display = règles d'affichage des colonnes modulables. *
-* creator = instance à l'origine de la représentation. [OUT] *
-* *
-* Description : Fournit la ligne et son segment présents à une position. *
-* *
-* Retour : Ligne retrouvée ou NULL si aucune. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, GObject **creator)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
- size_t index; /* Indice de la ligne trouvée */
- GBufferViewClass *class; /* Classe pour les vues */
- line_width_summary summary; /* Résumé concis des largeurs */
-
- /* Recherche d'une ligne correspondante */
-
- result = g_buffer_view_find_line_at(view, y, &index);
-
- if (idx != NULL) *idx = index;
-
- /* Recherche du segment visé éventuel */
-
- if (result != NULL && creator != NULL)
- {
- class = G_BUFFER_VIEW_GET_CLASS(view);
-
- if (*x < class->left_text)
- *creator = NULL;
-
- else
- {
- g_width_tracker_get_local_width_summary(view->tracker, index, &summary);
-
- *x -= class->left_text;
- *creator = g_buffer_line_get_creator_at(result, &summary, display,
- (gint []) { 0 }, x, GDK_SCROLL_LEFT, true);
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : view = composant GTK à consulter. *
+* Paramètres : view = visualisation à consulter. *
* addr = adresse à présenter à l'écran. *
+* code = s'arrête si possible à une ligne avec code. *
* x = position horizontale au sein du composant. [OUT] *
* y = position verticale au sein du composant. [OUT] *
-* code = s'arrête si possible à une ligne avec code. *
* *
* Description : Indique la position d'affichage d'une adresse donnée. *
* *
@@ -1276,61 +1138,11 @@ GBufferLine *g_buffer_view_find_line_and_creator_at(GBufferView *view, gint *x,
* *
******************************************************************************/
-bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr, gint *x, gint *y, bool code)
+bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr, bool code, gint *x, gint *y)
{
bool result; /* Bilan à retourner */
- gint lheight; /* Hauteur d'une ligne */
- size_t i; /* Boucle de parcours */
- GBufferLine *line; /* Ligne à consulter */
- const mrange_t *range; /* Emplacement parcouru */
-
- result = false;
-
- *x = 0;
- *y = 0;
-
- lheight = g_buffer_view_get_line_height(view);
-
- for (i = view->first; i <= view->last; i++)
- {
- /**
- * Si l'adresse recherchée est plus petite que l'adresse de départ,
- * on va effectuer un parcours complet pour rien.
- *
- * On considère cependant que le seul cas où celà peut arriver
- * est lorsque que des découpages en blocs sont impliqués.
- *
- * Les découpages conduisent alors à la formation de petites zones,
- * rapides à parcourir.
- */
-
- line = g_code_buffer_find_line_by_index(view->buffer, i);
- range = g_buffer_line_get_range(line);
-
- result = mrange_contains_addr(range, addr);
- if (result) break;
-
- *y += lheight;
- }
-
- if (result && code)
- for (; i <= view->last; i++)
- {
- line = g_code_buffer_find_line_by_index(view->buffer, i);
-
- if (g_buffer_line_get_flags(line) & BLF_HAS_CODE) break;
-
- if (i == view->last) break;
-
- line = g_code_buffer_find_line_by_index(view->buffer, i + 1);
-
- range = g_buffer_line_get_range(line);
- if (!mrange_contains_addr(range, addr)) break;
-
- *y += lheight;
-
- }
+ result = g_buffer_cache_get_address_coordinates(view->cache, addr, view->first, view->last, code, x, y);
return result;