diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/glibext/gbufferline.c | 324 | ||||
| -rw-r--r-- | src/glibext/gbufferline.h | 11 | ||||
| -rw-r--r-- | src/glibext/gbuffersegment.c | 64 | ||||
| -rw-r--r-- | src/glibext/gbuffersegment.h | 3 | ||||
| -rw-r--r-- | src/glibext/gcodebuffer.c | 292 | ||||
| -rw-r--r-- | src/glibext/gcodebuffer.h | 4 | ||||
| -rw-r--r-- | src/gtkext/gtkbufferview-int.h | 4 | ||||
| -rw-r--r-- | src/gtkext/gtkbufferview.c | 178 | ||||
| -rw-r--r-- | src/gtkext/gtkviewpanel-int.h | 4 | ||||
| -rw-r--r-- | src/gtkext/gtkviewpanel.c | 72 | ||||
| -rw-r--r-- | src/gui/status.c | 37 | 
11 files changed, 835 insertions, 158 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index cb5c267..6970dac 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -56,13 +56,19 @@ typedef struct _buffer_line_column  static void reset_column(buffer_line_column *);  /* Fournit la quantité de pixels requise pour l'impression. */ -static gint get_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 *); +#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 *, bool); +static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, GdkScrollDirection); + +/* Fournit le segment voisin d'un autre segment identifié. */ +static GBufferSegment *find_near_segment(const buffer_line_column *, GBufferSegment *, GdkScrollDirection, bool *);  /* Met en surbrillance des segments similaires. */  GSList *highlight_all_same_segments(const buffer_line_column *, GSList *, const GBufferSegment *); @@ -129,7 +135,7 @@ static void g_buffer_line_init(GBufferLine *);  static void reset_column(buffer_line_column *column)  { -    column->max_width = -1; +    column->max_width = 0;  } @@ -146,19 +152,8 @@ static void reset_column(buffer_line_column *column)  *                                                                             *  ******************************************************************************/ -static gint get_column_width(buffer_line_column *column) +static gint get_column_width(const buffer_line_column *column)  { -    size_t i;                               /* Boucle de parcours          */ - -    if (column->max_width == -1) -    { -        column->max_width = 0; - -        for (i = 0; i < column->count; i++) -            column->max_width += g_buffer_segment_get_width(column->segments[i]); - -    } -      return column->max_width;  } @@ -189,6 +184,8 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se      column->segments[column->count - 1] = segment; +    column->max_width += g_buffer_segment_get_width(segment); +  } @@ -196,7 +193,7 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se  *                                                                             *  *  Paramètres  : column = colonne de ligne de texte à consulter.              *  *                x      = position de recherche à ajuster. [OUT]              * -*                force  = accepte les segments en bordure au pire.            * +*                dir    = direction d'un éventuel déplacement en cours.       *  *                                                                             *  *  Description : Donne le segment d'une colonne présent à une abscisse donnée.*  *                                                                             * @@ -206,19 +203,37 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se  *                                                                             *  ******************************************************************************/ -static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, bool force) +static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, GdkScrollDirection dir)  {      GBufferSegment *result;                 /* Trouvaille à retourner      */      size_t i;                               /* Boucle de parcours          */      gint width;                             /* Largeur à retirer           */ +    bool included;                          /* Appartenance à une largeur ?*/      result = NULL; +    printf(" == gs@ ==   count = %d   width = %d\n", +           column->count, get_column_width(column)); +      for (i = 0; i < column->count && result == NULL; i++)      {          width = g_buffer_segment_get_width(column->segments[i]); -        if (width > *x || ((i + 1) == column->count && force)) +        printf("   -s-  |%d| -> x=%d   w=%d\n", i, *x, width); + +        /** +         * Soit une limite entre deux segments A et B : +         * +         *  - dans le cas d'un déplacement vers la gauche, on part de cette limite +         *    pour progresser à l'intérieur de A. Donc la limite fait partie de A. +         * +         *  - dans le cas d'un déplacement vers la droite, on part de cette limite +         *    pour progresser à l'intérieur de B. Donc la limite ne fait pas partie de A. +         */ +        if (dir == GDK_SCROLL_LEFT) included = (width >= *x); +        else included = (width > *x); + +        if (included || (i + 1) == column->count)              result = column->segments[i];          else @@ -226,6 +241,59 @@ 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.              * +*                target = segment dont un voisin est à retourner.             * +*                dir    = orientation des recherches.                         * +*                out    = renvoie vers une bordure extérieur au besoin. [OUT] * +*                                                                             * +*  Description : Fournit le segment voisin d'un autre segment identifié.      * +*                                                                             * +*  Retour      : Segment trouvé ou NULL si hors borne ou inconnu.             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBufferSegment *find_near_segment(const buffer_line_column *column, GBufferSegment *target, GdkScrollDirection dir, bool *out) +{ +    GBufferSegment *result;                 /* Trouvaille à retourner      */ +    size_t i;                               /* Boucle de parcours          */ + +    result = NULL; +    *out = false; + +    for (i = 0; i < column->count; i++) +        if (column->segments[i] == target) break; + +    if (i < column->count) +        switch (dir) +        { +            case GDK_SCROLL_LEFT: +                *out = (i == 0); +                if (!*out) +                    result = column->segments[i - 1]; +                break; + +            case GDK_SCROLL_RIGHT: +                *out = ((i + 1) == column->count); +                if (!*out) +                    result = column->segments[i + 1]; +                break; + +            default: +                break; + +        } +      return result;  } @@ -518,7 +586,9 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe  *                                                                             *  *  Paramètres  : line       = ligne à venir consulter.                        *  *                max_widths = largeurs de colonne à respecter.                * +*                display    = règles d'affichage des colonnes modulables.     *  *                x          = 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.              * @@ -529,30 +599,120 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe  *                                                                             *  ******************************************************************************/ -GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], gint *x, bool force) +GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], const bool *display, gint *x, GdkScrollDirection dir, bool force)  {      GBufferSegment *result;                 /* Trouvaille à retourner      */ +    gint old;                               /* Valeur d'origine de position*/ +    BufferLineColumn last;                  /* Dernière colonne remplie    */ +    gint last_x;                            /* Dernière abscisse associée  */      BufferLineColumn i;                     /* Boucle de parcours          */ +    gint width;                             /* Largeur d'une colonne donnée*/      result = NULL; +    old = *x; +    last = BLC_COUNT; +    last_x = *x;    /* Pour GCC */ + +    printf(" {{ ADDR }} 0x%08x\n", line->range.addr.physical); + + + +      for (i = 0; i < BLC_COUNT; i++)      { -        /* FIXME : addr/code */ +        printf(" @ (%d) x=%d  width=%d  max=%d  display ? %d\n", +               i, *x, get_column_width(&line->columns[i]), 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... */ +        if (get_column_width(&line->columns[i]) > 0) +        { +            last = i; +            last_x = *x; +        } + +        if (i < line->merge_start) +        { +            width = max_widths[i]; + +            if (*x <= width) break; +            else *x -= (max_widths[i] + COL_MARGIN); + +        } +        else +        { +            width = get_column_width(&line->columns[i]); + +            if (*x <= width) break; +            else *x -= width; + +        } -        if (*x < max_widths[i]) break; -        else *x -= (max_widths[i] + COL_MARGIN);      } -    if (i == BLC_COUNT && force) +    printf(" -- get segment at -- found index %u (max=%u)\n", i, BLC_COUNT); + + +    printf("                      last seen = %u\n", last); + + + +    if (force)      { -        i = BLC_COUNT - 1; -        *x += (max_widths[i] + COL_MARGIN); +        if (i == BLC_COUNT) +        { + +            /* Re-calcul des largeurs cumulées */ + +            if (last == BLC_COUNT) i = BLC_COUNT; +            else +            { +                *x = old; + +                for (i = 0; i < last; i++) +                { +                    if (i < line->merge_start) +                        *x -= (max_widths[i] + COL_MARGIN); +                    else +                        *x -= get_column_width(&line->columns[i]); +                } + +            } + + +            printf(" -- get segment at -- last index %u (max=%u)   -->>  x = %d\n", i, BLC_COUNT, *x); + + + +        } + +        /* Si on s'est arrêté sur un champ vide... */ +        else if (i != last) +        { +            i = last; +            *x = last_x; +        } +      } + + + +      if (i < BLC_COUNT) -        result = get_segment_at(&line->columns[i], x, force); +        result = get_segment_at(&line->columns[i], x, dir); + + +    if (result == NULL) +        printf(" -- get segment at -- found nothing...\n"); +    else +        printf(" -- get segment at -- found %p '%s'...\n", result, g_buffer_segment_get_text(result)); + +      return result; @@ -561,33 +721,117 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint  /******************************************************************************  *                                                                             * -*  Paramètres  : line  = ligne à venir consulter.                             * -*                caret = position du curseur à faire évoluer.                 * -*                ctrl  = indique la demande d'un parcours rapide.             * -*                dir   = direction du parcours.                               * -*                phys  = indique si les positions doivent être affichées.     * -*                virt  = indique si les adresses doivent être affichées.      * -*                code  = indique si le code binaire doit être affiché.        * +*  Paramètres  : line    = ligne à venir consulter.                           * +*                target  = segment dont un voisin est à retourner.            * +*                max_widths = largeurs de colonne à respecter.            XXXXXXXXXXXXXXX    * +*                display = règles d'affichage des colonnes modulables.        * +*                dir     = orientation des recherches.                        * +*                offset  = décalage pour amener à l'extrémité voisine. [OUT]  *  *                                                                             * -*  Description : Déplace le curseur au sein d'une vue de tampon.              * +*  Description : Fournit le segment voisin d'un autre segment identifié.      *  *                                                                             * -*  Retour      : true si un déplacement a été effectué, false sinon.          * +*  Retour      : Segment trouvé dans la ligne ou NULL.                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool g_buffer_line_move_caret(const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool phys, bool virt, bool code) +GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBufferSegment *target, const gint max_widths[BLC_COUNT], const bool *display, GdkScrollDirection dir, gint *offset)  { +    GBufferSegment *result;                 /* Trouvaille à retourner      */ +    BufferLineColumn i;                     /* Boucle de parcours          */ +    bool out;                               /* Présence de cible en bordure*/ -    /* TODO : utiliser les arguments booléens */ +    result = NULL; +    *offset = 0; + +    for (i = 0; i < BLC_COUNT && result == NULL; i++) +    { +        if (i < BLC_DISPLAY && !display[i]) continue; + +        result = find_near_segment(&line->columns[i], target, dir, &out); + +        printf("   [%d] near seg = %p (out ? %d)\n", i, result, out); + +        if (result != NULL) break; + +        if (out) +        { +            switch (dir) +            { +                case GDK_SCROLL_LEFT: + + gblfns_loop_left: + +                    /* On s'assure que la colonne précédente est visible */ +                    if (i <= BLC_DISPLAY) +                        for (; i > BLC_FIRST; i--) +                            if (display[i - 1]) break; + +                    if (i > BLC_FIRST) result = get_last_segment(&line->columns[i - 1]); + +                    printf("   [near] (%d) %p\n", i, result); + +                    if (result == NULL && i > BLC_FIRST) +                    { +                        printf("   [loop] %u -> %u\n", i, i - 1); +                        i--; +                        *offset -= (max_widths[i] + COL_MARGIN); +                        goto gblfns_loop_left; +                    } + +                    if (result != NULL) +                        *offset += g_buffer_segment_get_width(result) - max_widths[i - 1] - COL_MARGIN; + +                    break; -    caret->x += (dir == GDK_SCROLL_RIGHT ? 10 : -10); +                case GDK_SCROLL_RIGHT: -    return true; + gblfns_loop_right: +                    /* On s'assure que la colonne suivante est visible */ +                    for (; (i + 1) < BLC_DISPLAY; i++) +                        if (display[i + 1]) break; -    return false; +                    if ((i + 1) < BLC_COUNT) result = get_first_segment(&line->columns[i + 1]); + + +                    printf("   [near] (%d) %p\n", i, result); + +                    if (result == NULL && (i + 1) < BLC_COUNT) +                    { +                        printf("   [loop] %u -> %u\n", i, i + 1); +                        *offset += (max_widths[i] + COL_MARGIN); +                        printf("      -- add %d  ~>  %d\n", max_widths[i], *offset); +                        i++; +                        goto gblfns_loop_right; +                    } + +                    if (result != NULL) +                    { +                        *offset -= g_buffer_segment_get_width(target); +                        *offset += max_widths[i] + COL_MARGIN; +                        printf("      -- add %d  ~>  %d\n", max_widths[i], *offset); +                    } + + +                    /* +                    if (result != NULL) +                        *offset += max_widths[i + 1] - g_buffer_segment_get_width(result) + COL_MARGIN; +                        */ + +                    break; + +                default: +                    break; + +            } + +        } + +    } + +    return result;  } diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 8e436d9..5a45fe2 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -69,6 +69,9 @@ typedef enum _BufferLineColumn  } BufferLineColumn; +/* Première colonne de l'ensemble */ +#define BLC_FIRST BLC_PHYSICAL +  /* Première colonne toujours affichée */  #define BLC_DISPLAY BLC_ASSEMBLY_HEAD @@ -96,11 +99,11 @@ void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize,  /* Ajoute un fragment de texte à une colonne de ligne. */  void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *) __attribute__ ((deprecated)); -/* Déplace le curseur au sein d'une vue de tampon. */ -bool g_buffer_line_move_caret(const GBufferLine *, GdkRectangle *, bool, GdkScrollDirection, bool, bool, bool); -  /* Donne le segment présent à une abscisse donnée. */ -GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint *, bool); +GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], const bool *, gint *, GdkScrollDirection, bool); + +/* Fournit le segment voisin d'un autre segment identifié. */ +GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *, GBufferSegment *, const gint [BLC_COUNT], const bool *, GdkScrollDirection, gint *);  /*  Met en surbrillance des segments similaires. */  GSList *g_buffer_line_highlight_all_same_segments(const GBufferLine *, GSList *, const GBufferSegment *); diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c index c96b092..0c31b9c 100644 --- a/src/glibext/gbuffersegment.c +++ b/src/glibext/gbuffersegment.c @@ -406,6 +406,70 @@ gint g_buffer_segment_get_caret_position(const GBufferSegment *segment, gint x)  /******************************************************************************  *                                                                             *  *  Paramètres  : segment = fragment de texte à manipuler.                     * +*                x       = position du curseur à faire évoluer. [OUT]         * +*                ctrl    = indique la demande d'un parcours rapide.           * +*                dir     = direction du parcours.                             * +*                                                                             * +*  Description : Déplace le curseur au sein d'un segment de tampon.           * +*                                                                             * +*  Retour      : true si un déplacement a été effectué, false sinon.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_buffer_segment_move_caret(const GBufferSegment *segment, gint *x, bool ctrl, GdkScrollDirection dir) +{ +    bool result;                            /* Bilan d'opération à renvoyer*/ +    gint width;                             /* Largeur du segment          */ +    gint char_width;                        /* Largeur de police fixe      */ + +    result = false; + +    width = g_buffer_segment_get_width(segment); +    char_width = width / strlen(segment->text); + +    if (dir == GDK_SCROLL_LEFT) +    { +        printf(">>>>> left ::: x=%d  width=%d  char=%d\n", *x, width, char_width); + +        if (*x > width) *x = width + char_width; + +        if (*x == 0) goto gbsmc_done; + +        if (ctrl) *x = 0; +        else *x = MAX(0, *x - char_width); + +        result = true; + +    } + +    else if (dir == GDK_SCROLL_RIGHT) +    { + +        printf(">>>>> right ::: x=%d  width=%d  char=%d\n", *x, width, char_width); + +        if (*x == width) goto gbsmc_done; + +        if (ctrl) *x = width; +        else *x = MIN(width, *x + char_width); + +        result = true; + +    } + + gbsmc_done: + +    printf(">>>>> result ::: %d\n", result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : segment = fragment de texte à manipuler.                     *  *                style   = style de rendu pour le segment.                    *  *                                                                             *  *  Description : Module l'apparence finale du composant.                      * diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h index d570e89..bb82bba 100644 --- a/src/glibext/gbuffersegment.h +++ b/src/glibext/gbuffersegment.h @@ -120,6 +120,9 @@ gint g_buffer_segment_get_width(const GBufferSegment *);  /* Fournit la position idéale pour un marqueur. */  gint g_buffer_segment_get_caret_position(const GBufferSegment *, gint); +/* Déplace le curseur au sein d'un segment de tampon. */ +bool g_buffer_segment_move_caret(const GBufferSegment *, gint *, bool, GdkScrollDirection); +  /* Module l'apparence finale du composant. */  void g_buffer_segment_set_style(GBufferSegment *, SegRenderingStyle); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index 1ea8f69..eab418e 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -24,6 +24,7 @@  #include "gcodebuffer.h" +#include <limits.h>  #include <malloc.h>  #include <string.h> @@ -123,10 +124,10 @@ static void g_code_buffer_class_init(GCodeBufferClass *);  static void g_code_buffer_init(GCodeBuffer *);  /* Convertit une adresse en indice de ligne. */ -static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *, vmpa_t, bool); +static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *, const vmpa2t *, bool);  /* Convertit une adresse en indice de ligne. */ -static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t, bool); +static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, const vmpa2t *, bool); @@ -407,7 +408,7 @@ GCodeBuffer *g_code_buffer_new(BufferLineColumn main)  *                                                                             *  ******************************************************************************/ -static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, vmpa_t addr, bool first) +static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, const vmpa2t *addr, bool first)  {      size_t result;                          /* Indice à retourner          */ @@ -451,7 +452,7 @@ static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, v  *                                                                             *  ******************************************************************************/ -static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t addr, bool first) +static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, const vmpa2t *addr, bool first)  {      size_t result;                          /* Indice à retourner          */ @@ -1074,11 +1075,12 @@ gint g_buffer_view_get_height(const GBufferView *view)  /******************************************************************************  *                                                                             * -*  Paramètres  : view  = vue de tampon à mettre à jour.                       * -*                line  = ligne correspondant à la position.                   * -*                index = indice de cette même ligne dans le tampon.           * -*                x     = abscisse de la zone principale à traiter.            * -*                caret = position du curseur à construire. [OUT]              * +*  Paramètres  : view    = vue de tampon à mettre à jour.                     * +*                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]            *  *                                                                             *  *  Description : Calcule la position idéale de curseur pour un point donné.   *  *                                                                             * @@ -1088,7 +1090,7 @@ gint g_buffer_view_get_height(const GBufferView *view)  *                                                                             *  ******************************************************************************/ -const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, size_t index, gint x, GdkRectangle *caret) +const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, size_t index, gint x, const bool *display, GdkRectangle *caret)  {      gint tmp_x;                             /* Copie de travail modifiable */      GBufferSegment *segment;                /* Segment visé par le pointeur*/ @@ -1099,9 +1101,16 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line,      tmp_x -= view->left_text;      if (tmp_x < 0) return NULL; -    segment = g_buffer_line_get_segment_at(line, view->max_widths, &tmp_x, true); +    segment = g_buffer_line_get_segment_at(line, view->max_widths, display, &tmp_x, GDK_SCROLL_LEFT, true); +    if (segment == NULL) printf(" -- no segment\n");      if (segment == NULL) return NULL; +    printf("\n[BASE]  tronc = %d   reste = %d   dernier = %d   largeur = %d\n", +           x - tmp_x, tmp_x, g_buffer_segment_get_caret_position(segment, tmp_x), +           g_buffer_segment_get_width(segment)); + +    printf("        '%s'\n", g_buffer_segment_get_text(segment)); +      caret->x = (x - tmp_x) + g_buffer_segment_get_caret_position(segment, tmp_x);      first = g_code_buffer_get_index_from_address(view->buffer, view->start, true); @@ -1110,20 +1119,147 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line,      caret->width = 2;      caret->height = view->line_height; -    return NULL;///g_buffer_line_get_address(line); +    return get_mrange_addr(g_buffer_line_get_range(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.                               * -*                phys  = indique si les positions doivent être affichées.     * -*                virt  = indique si les adresses doivent être affichées.      * -*                code  = indique si le code binaire doit être affiché.        * +*  Paramètres  : line    = ligne à venir consulter.                           * +*                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.        * +*                                                                             * +*  Description : Déplace le curseur au sein d'une vue de tampon.              * +*                                                                             * +*  Retour      : true si un déplacement a été effectué, false sinon.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display) +{ +    bool result; + +    gint tmp_x;                             /* Copie de travail modifiable */ +    GBufferSegment *segment;                /* Segment visé par le pointeur*/ +    size_t first;                           /* Première ligne intégrée     */ + +    gint ref_x; + + +    gint offset; + + + +    tmp_x = caret->x; + +    tmp_x -= view->left_text; +    if (tmp_x < 0) return false; + +    segment = g_buffer_line_get_segment_at(line, view->max_widths, display, &tmp_x, dir, false); + +    if (segment == NULL) printf(" ===== NO SEG...\n"); + +    if (segment == NULL) return false; + + +    printf(" ====== FIRST SEG :: %p ('%s')\n", segment, g_buffer_segment_get_text(segment)); + + + +    ref_x = tmp_x; + + + +    //if (dir == GDK_SCROLL_LEFT || dir == GDK_SCROLL_RIGHT) +        result = g_buffer_segment_move_caret(segment, &tmp_x, ctrl, dir); +    //else +        //result = true; + +    printf(" ====== MOVE 1 ? %d\n", result); + + +    if (!result) +    { + + +        segment = g_buffer_line_find_near_segment(line, segment, view->max_widths, display, dir, &offset); + + +        printf(" ====== NEAR SEG :: %p ('%s')\n", segment, segment ? g_buffer_segment_get_text(segment) : NULL); + +        if (segment != NULL) +        { +            //tmp_x = /*ref_x + */g_buffer_segment_get_width(segment); + + +            //ref_x = tmp_x; +            ref_x = tmp_x = 0; + + +            ref_x = 0; +            tmp_x = offset; + + +            result = true; +            //result = g_buffer_segment_move_caret(segment, &tmp_x, ctrl, dir); + +            /* +            if (result) +                caret->x -= COL_MARGIN; +            */ + +            printf(" ====== MOVE 2 ? %d (offset=%d)\n", result, offset); + + +        } + + +    } + + +    if (result) +        printf(" ====== NEW CARET: %d -> %d\n", caret->x, caret->x + (tmp_x - ref_x)); +    else +        printf(" ====== NO NEW CARET!\n"); + + + +    if (result) +        caret->x += (tmp_x - ref_x); + + + +    return result; + + +    //bool g_buffer_segment_move_caret(const GBufferSegment *segment, gint *x, bool ctrl, GdkScrollDirection dir) + + + +    /* TODO : utiliser les arguments booléens */ + +    caret->x += (dir == GDK_SCROLL_RIGHT ? 10 : -10); + +    return true; + + +    return false; + +} + + +/****************************************************************************** +*                                                                             * +*  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.        *  *                                                                             *  *  Description : Déplace le curseur au sein d'une vue de tampon.              *  *                                                                             * @@ -1133,9 +1269,12 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line,  *                                                                             *  ******************************************************************************/ -vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool phys, bool virt, bool code) +const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display)  { -    bool result;                            /* Actualisation à renvoyer    */ +    vmpa2t *result;                         /* Actualisation à renvoyer    */ +    GBufferLine *line;                      /* Ligne sous le pointeur      */ + +      bool computed;                          /* Récursivité pris en compte  */      gint lheight;                           /* Hauteur d'une ligne         */      gint left_pos;                          /* Retour à la ligne           */ @@ -1143,11 +1282,34 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr      BufferLineColumn i;                     /* Boucle de parcours          */      size_t first;                           /* Première ligne intégrée     */      size_t last;                            /* Dernière ligne intégrée     */ -    GBufferLine *line;                      /* Ligne sous le pointeur      */ -    result = VMPA_INVALID; +    size_t index;                           /* Indice de ligne de tampon   */ + + +    bool moved;                             /* Mémorisation d'une évolut°  */ + + + + + + +    gint tmp_x;                             /* Copie de travail modifiable */ +    GBufferSegment *segment;                /* Segment visé par le pointeur*/ + + + +    result = NULL;      computed = false; + + +    line = g_buffer_view_find_line_at(view, caret->y, &index); +    if (line == NULL) return NULL; + + +    lheight = g_buffer_view_get_line_height(view); + +      switch (dir)      {          case GDK_SCROLL_UP: @@ -1157,12 +1319,17 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr          case GDK_SCROLL_LEFT:          case GDK_SCROLL_RIGHT:              left_pos = view->left_text; -            if (phys) left_pos += view->max_widths[BLC_PHYSICAL] + COL_MARGIN; -            if (virt) left_pos += view->max_widths[BLC_VIRTUAL] + COL_MARGIN; -            if (code) left_pos += view->max_widths[BLC_BINARY] + COL_MARGIN; +            if (display[BLC_PHYSICAL]) left_pos += view->max_widths[BLC_PHYSICAL] + COL_MARGIN; +            if (display[BLC_VIRTUAL]) left_pos += view->max_widths[BLC_VIRTUAL] + COL_MARGIN; +            if (display[BLC_BINARY]) left_pos += view->max_widths[BLC_BINARY] + COL_MARGIN;              right_pos = left_pos;              for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++)                  right_pos += view->max_widths[i] + COL_MARGIN; + + + +            left_pos = view->left_text; +              break;          default:    /* GDK_SCROLL_SMOOTH */              break; @@ -1171,58 +1338,56 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr      first = g_code_buffer_get_index_from_address(view->buffer, view->start, true);      last = g_code_buffer_get_index_from_address(view->buffer, view->end, false); +    first = 0; +      switch (dir)      {          case GDK_SCROLL_UP: -            result = (caret->y >= (first * lheight)); -            if (result) -                caret->y -= lheight; + +            if (index > first) +            { +                line = view->buffer->lines[index - 1]; +                result = g_buffer_view_compute_caret(view, line, index - 1, caret->x, display, caret); +            } +              break;          case GDK_SCROLL_DOWN: -            result = ((caret->y + lheight) < (last * lheight)); -            if (result) -                caret->y += lheight; + +            if (index < last) +            { +                line = view->buffer->lines[index + 1]; +                result = g_buffer_view_compute_caret(view, line, index + 1, caret->x, display, caret); +            } +              break;          case GDK_SCROLL_LEFT: -            line = g_buffer_view_find_line_at(view, caret->y, NULL); + +            line = g_buffer_view_find_line_at(view, caret->y, &index);              if (line == NULL) break; -            result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_LEFT, phys, virt, code); +            moved = _g_buffer_view_move_caret(view, line, caret, ctrl, GDK_SCROLL_LEFT, display); -            if (caret->x < left_pos) +            if (!moved && index > first)              { -                caret->x = right_pos; - -                result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_UP, phys, virt, code); - -                if (result == VMPA_INVALID) -                    caret->x = left_pos; -                else -                    computed = true; - +                line = view->buffer->lines[index - 1]; +                result = g_buffer_view_compute_caret(view, line, index - 1, INT_MAX, display, caret);              }              break;          case GDK_SCROLL_RIGHT: -            line = g_buffer_view_find_line_at(view, caret->y, NULL); + +            line = g_buffer_view_find_line_at(view, caret->y, &index);              if (line == NULL) break; -            result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_RIGHT, phys, virt, code); +            moved = _g_buffer_view_move_caret(view, line, caret, ctrl, GDK_SCROLL_RIGHT, display); -            if (!result) +            if (!moved && index < last)              { -                caret->x = left_pos; - -                result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_DOWN, phys, virt, code); - -                if (result == VMPA_INVALID) -                    caret->x = right_pos; -                else -                    computed = true; - +                line = view->buffer->lines[index + 1]; +                result = g_buffer_view_compute_caret(view, line, index + 1, left_pos, display, caret);              }              break; @@ -1232,8 +1397,16 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr      } + +    printf(" --- CARET ---   moved = %d   index = %d   result = %p\n", +           moved, index, result); + + + +    /*      if (result && !computed) -        /*result = g_buffer_view_compute_caret(view, caret->x, caret->y, caret, NULL)*/; +        result = g_buffer_view_compute_caret(view, caret->x, caret->y, caret, display, NULL); +    */      return result; @@ -1292,6 +1465,7 @@ bool g_buffer_view_unhighlight_segments(GBufferView *view)  void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y)  { +#if 0   /* FIXME : inclusion des champs adresses/code */      GBufferLine *line;                      /* Ligne sous le pointeur      */      GBufferSegment *segment;                /* Segment visé par le pointeur*/      bool need_redraw;                       /* Besoin d'actualisation ?    */ @@ -1305,7 +1479,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y)      x -= view->left_text;      if (x < 0) return; -    segment = g_buffer_line_get_segment_at(line, view->max_widths, &x, false); +    segment = g_buffer_line_get_segment_at(line, view->max_widths, &x, GDK_SCROLL_LEFT, false);      printf(" ... seg @%d ? %p\n", x, segment);      if (segment == NULL) return; @@ -1330,7 +1504,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y)      if (need_redraw)          g_signal_emit_by_name(view, "need-redraw"); - +#endif  } diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h index 1387eb9..ece7c59 100644 --- a/src/glibext/gcodebuffer.h +++ b/src/glibext/gcodebuffer.h @@ -129,10 +129,10 @@ gint g_buffer_view_get_width(GBufferView *, const bool *);  gint g_buffer_view_get_height(const GBufferView *);  /* Calcule la position idéale de curseur pour un point donné. */ -const vmpa2t *g_buffer_view_compute_caret(GBufferView *, GBufferLine *, size_t, gint, GdkRectangle *); +const vmpa2t *g_buffer_view_compute_caret(GBufferView *, GBufferLine *, size_t, gint, const bool *, GdkRectangle *);  /* Déplace le curseur au sein d'une vue de tampon. */ -vmpa_t g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, bool, bool, bool); +const vmpa2t *g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, const bool *);  /* Supprime toute mise en évidence de segments. */  bool g_buffer_view_unhighlight_segments(GBufferView *); diff --git a/src/gtkext/gtkbufferview-int.h b/src/gtkext/gtkbufferview-int.h index 64d3b0e..4f82757 100644 --- a/src/gtkext/gtkbufferview-int.h +++ b/src/gtkext/gtkbufferview-int.h @@ -45,7 +45,7 @@ struct _GtkBufferView      gint left_text;                         /* Début d'impression du code  */      GdkRectangle caret;                     /* Emplacement du curseur      */ -    vmpa_t caret_addr;                      /* Position mémoire du curseur */ +    const vmpa2t *caret_addr;               /* Position mémoire du curseur */      guint caret_timer;                      /* Identifiant du chronomètre  */      bool show_caret;                        /* Bascule entre les affichages*/ @@ -58,7 +58,7 @@ struct _GtkBufferViewClass      /* Signaux */ -    void (* caret_moved) (GtkBufferView *, vmpa_t); +    void (* caret_moved) (GtkBufferView *, const vmpa2t *);  }; diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c index d5780ed..8b9b83b 100644 --- a/src/gtkext/gtkbufferview.c +++ b/src/gtkext/gtkbufferview.c @@ -55,6 +55,9 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *);  /* Indique les dimensions de travail du composant d'affichage. */  static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint *); +/* Détermine la taille des bonds lors de défilements. */ +static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *, gint, GtkOrientation, gdouble *, gdouble *); +  /* Indique la position d'affichage d'une adresse donnée. */  static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *); @@ -66,6 +69,9 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAl  /* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */ +/* Déplace le curseur en effaçant son éventuelle position. */ +static void gtk_buffer_view_relocate_caret(GtkBufferView *, const GdkRectangle *, const vmpa2t *); +  /* Redémarre l'affichage du curseur à l'emplacement courant. */  static void restart_caret_blinking(GtkBufferView *); @@ -109,6 +115,7 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class)      widget_class->key_press_event = gtk_buffer_view_key_press;      panel_class->compute_size = (compute_requested_size)gtk_buffer_view_compute_requested_size; +    panel_class->compute_inc = (compute_scroll_inc)gtk_buffer_view_compute_scroll_inc;      panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_view_get_address_coordinates;      g_signal_new("caret-moved", @@ -205,14 +212,16 @@ static gboolean gtk_buffer_view_focus(GtkWidget *widget, GtkDirectionType direct  static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *event)  {      GtkBufferView *view;                    /* Autre version du composant  */ +    GtkViewPanel *pview;                    /* Autre version du composant  */      gint real_x;                            /* Abscisse absolue réelle     */      gint real_y;                            /* Ordonnée absolue réelle     */      size_t index;                           /* Indice de ligne de tampon   */      GBufferLine *line;                      /* Ligne à la position courante*/ -    vmpa_t addr;                            /* Position mémoire associée   */ +    const vmpa2t *addr;                     /* Position mémoire associée   */      GdkRectangle new;                       /* Nouvel emplacement calculé  */      view = GTK_BUFFER_VIEW(widget); +    pview = GTK_VIEW_PANEL(widget);      gtk_widget_grab_focus(widget); @@ -230,6 +239,11 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *      if (line == NULL) return FALSE; + +    printf(" [init ] %p - line = %p (y=%d)\n", view->buffer_view, line, real_y); + + +      if (real_x < view->left_margin)      { @@ -241,28 +255,8 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *      }      else      { -        return FALSE; -        /* -        addr = g_buffer_view_compute_caret(view->buffer_view, line, index, real_x, &new); -        if (addr == VMPA_INVALID) return FALSE; -        */ - -        gtk_buffer_view_compute_relative_coords(view, &view->caret.x, &view->caret.y); - -        printf(" mouse --old-- :: (%d ; %d)\n", -               view->caret.x, view->caret.y); - -        printf(" mouse --new-- :: (%d ; %d)\n", -               new.x, new.y); - -        gtk_widget_queue_draw_area(GTK_WIDGET(view), view->caret.x, view->caret.y, -                                   view->caret.width, view->caret.height); - -        view->caret = new; -        view->caret_addr = addr; - -        restart_caret_blinking(view); - +        addr = g_buffer_view_compute_caret(view->buffer_view, line, index, real_x, pview->display, &new); +        gtk_buffer_view_relocate_caret(view, &new, addr);      }      return FALSE; @@ -343,7 +337,6 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)      gint fake_y;                            /* Ordonnée virtuelle          */      view = GTK_BUFFER_VIEW(widget); -    widget = GTK_WIDGET(view);      pview = GTK_VIEW_PANEL(widget);      window = gtk_widget_get_window(widget); @@ -384,6 +377,14 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)      } +    /* Curseur clignotant ? */ + +    if (gtk_widget_is_focus(widget)) +    { +        view->show_caret = !view->show_caret; +        gtk_buffer_view_refresh_caret(view); +    } +      cairo_restore(cr);      return TRUE; @@ -407,32 +408,78 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)  static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)  {      gboolean result;                        /* Suites à renvoyer           */ + +    GtkBufferView *view;                    /* Autre version du composant  */ +    GtkViewPanel *pview;                    /* Autre version du composant  */ + +      bool ctrl;                              /* Statut de la touche Contrôle*/ + +    GdkRectangle area; + +    const vmpa2t *addr; + +      result = FALSE; + + +    view = GTK_BUFFER_VIEW(widget); +    pview = GTK_VIEW_PANEL(widget); + + +    area = view->caret; + +      ctrl = (event->state & GDK_CONTROL_MASK);      switch (event->keyval)      {          case GDK_KEY_Left: +            printf("LEFT\n"); +            addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_LEFT, pview->display); +            gtk_buffer_view_relocate_caret(view, &area, view->caret_addr);              result = TRUE;              break; +          case GDK_KEY_Up: +            printf("UP\n"); +            addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_UP, pview->display); +            gtk_buffer_view_relocate_caret(view, &area, view->caret_addr);              result = TRUE;              break; +          case GDK_KEY_Right: +            printf("RIGHT\n"); +            addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_RIGHT, pview->display); +            gtk_buffer_view_relocate_caret(view, &area, view->caret_addr);              result = TRUE;              break; +          case GDK_KEY_Down: +            printf("DOWN\n"); +            addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_DOWN, pview->display); +            gtk_buffer_view_relocate_caret(view, &area, view->caret_addr);              result = TRUE;              break; + +        default: +            addr = NULL; +            break; +      }      printf("ctrl ? %d -- keyval = %d -->> %d\n", ctrl, event->keyval, result); +    if (addr != NULL) gtk_view_panel_scroll_to_address(pview, addr); + + +    printf("\n"); + +      return result;  } @@ -466,6 +513,38 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *wi  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * +*                size        = taille de l'espace dans la direction donnée.   * +*                orientation = indication sur le défilement à traiter.        * +*                step        = valeur d'un petit pas de défilement. [OUT]     * +*                page        = valeur d'un grand pas de défilement. [OUT]     * +*                                                                             * +*  Description : Détermine la taille des bonds lors de défilements.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, GtkOrientation orientation, gdouble *step, gdouble *page) +{ +    if (orientation == GTK_ORIENTATION_VERTICAL) +    { +        *step = 17; // FIXME g_buffer_view_get_line_height(view->buffer_view); +        *page = *step * 10; +    } + +    else +        GTK_VIEW_PANEL_CLASS(gtk_buffer_view_parent_class)->compute_inc(GTK_VIEW_PANEL(view), +                                                                        size, orientation, step, page); + +} + + + @@ -633,10 +712,43 @@ void gtk_buffer_view_compute_relative_coords(GtkBufferView *view, gint *x, gint  /******************************************************************************  *                                                                             *  *  Paramètres  : view = composant GTK à manipuler.                            * +*                area = emplacement pour le dessin d'un curseur.              * +*                addr = position dans la mémoire représentée du curseur.      * +*                                                                             * +*  Description : Déplace le curseur en effaçant son éventuelle position.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_relocate_caret(GtkBufferView *view, const GdkRectangle *area, const vmpa2t *addr) +{ +    if (view->caret_addr != NULL) +    { +        gtk_buffer_view_compute_relative_coords(view, &view->caret.x, &view->caret.y); + +        gtk_widget_queue_draw_area(GTK_WIDGET(view), view->caret.x, view->caret.y, +                                   view->caret.width, view->caret.height); + +    } + +    view->caret = *area; +    view->caret_addr = addr; + +    restart_caret_blinking(view); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view = composant GTK à manipuler.                            *  *                                                                             *  *  Description : Redémarre l'affichage du curseur à l'emplacement courant.    *  *                                                                             * -*  Retour      : TRUE pour poursuivre les basculements automatiques.          * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             * @@ -644,16 +756,20 @@ void gtk_buffer_view_compute_relative_coords(GtkBufferView *view, gint *x, gint  static void restart_caret_blinking(GtkBufferView *view)  { -    if (view->caret_addr == VMPA_INVALID) -        return; -      if (view->caret_timer != 0) +    {          g_source_remove(view->caret_timer); +        view->caret_timer = 0; +    } + +    if (view->caret_addr != NULL) +    { +        view->show_caret = false; +        gtk_buffer_view_refresh_caret(view); -    view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view); +        view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view); -    view->show_caret = false; -    gtk_buffer_view_refresh_caret(view); +    }      g_signal_emit_by_name(view, "caret-moved", view->caret_addr); diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h index 49b5195..f33499d 100644 --- a/src/gtkext/gtkviewpanel-int.h +++ b/src/gtkext/gtkviewpanel-int.h @@ -36,6 +36,9 @@  /* Indique les dimensions de travail du composant d'affichage. */  typedef void (* compute_requested_size) (GtkViewPanel *, gint *, gint *); +/* Détermine la taille des bonds lors de défilements. */ +typedef void (* compute_scroll_inc) (GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *); +  /* Prend acte de l'association d'un binaire chargé. */  typedef void (* attach_binary_fc) (GtkViewPanel *, GLoadedBinary *); @@ -82,6 +85,7 @@ struct _GtkViewPanelClass      GtkFixedClass parent;                   /* A laisser en premier        */      compute_requested_size compute_size;    /* Calcul de la taille requise */ +    compute_scroll_inc compute_inc;         /* Calcul des bonds            */      get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */  }; diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c index 27799b5..8e41fa1 100644 --- a/src/gtkext/gtkviewpanel.c +++ b/src/gtkext/gtkviewpanel.c @@ -53,6 +53,9 @@ static void gtk_view_panel_size_allocate(GtkWidget *, GtkAllocation *);  /* Met à jour l'affichage du composant d'affichage. */  static gboolean gtk_view_panel_draw(GtkWidget *, cairo_t *); +/* Détermine la taille des bonds lors de défilements. */ +static void gtk_view_panel_compute_scroll_inc(GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *); +  /* Détermine la taille allouée pour le contenu. */  static void gtk_view_panel_compute_allocation(GtkViewPanel *, GtkAllocation *); @@ -94,9 +97,11 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)  {      GObjectClass *gobject_class;            /* Plus haut niveau équivalent */      GtkWidgetClass *widget_class;           /* Classe de haut niveau       */ +    GtkViewPanelClass *panel_class;         /* Classe de lus bas niveau    */      gobject_class = G_OBJECT_CLASS(class);      widget_class = GTK_WIDGET_CLASS(class); +    panel_class = GTK_VIEW_PANEL_CLASS(class);      gobject_class->set_property = gtk_view_panel_set_property;      gobject_class->get_property = gtk_view_panel_get_property; @@ -112,6 +117,8 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)      widget_class->size_allocate = gtk_view_panel_size_allocate;      widget_class->draw = gtk_view_panel_draw; +    panel_class->compute_inc = gtk_view_panel_compute_scroll_inc; +  } @@ -365,6 +372,30 @@ static gboolean gtk_view_panel_draw(GtkWidget *widget, cairo_t *cr)  /******************************************************************************  *                                                                             * +*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * +*                size        = taille de l'espace dans la direction donnée.   * +*                orientation = indication sur le défilement à traiter.        * +*                step        = valeur d'un petit pas de défilement. [OUT]     * +*                page        = valeur d'un grand pas de défilement. [OUT]     * +*                                                                             * +*  Description : Détermine la taille des bonds lors de défilements.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_view_panel_compute_scroll_inc(GtkViewPanel *panel, gint size, GtkOrientation orientation, gdouble *step, gdouble *page) +{ +    *step = size * 0.1; +    *page = size * 0.9; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : panel = composant GTK à consulter.                           *  *                alloc = emplacement à déterminer. [OUT]                      *  *                                                                             * @@ -521,6 +552,8 @@ static void gtk_view_panel_update_adjustment(GtkViewPanel *panel, GtkOrientation      GtkAdjustment *adj;                     /* Ajustement à manipuler      */      gint req;                               /* Dimension requise           */      gint allocated;                         /* Dimension allouée           */ +    gdouble step_inc;                       /* Pas de défilement           */ +    gdouble page_inc;                       /* ENjambée de défilement      */      gtk_view_panel_compute_allocation(panel, &allocation); @@ -541,10 +574,12 @@ static void gtk_view_panel_update_adjustment(GtkViewPanel *panel, GtkOrientation      } +    GTK_VIEW_PANEL_GET_CLASS(panel)->compute_inc(panel, allocated, orientation, &step_inc, &page_inc); +      gtk_adjustment_configure(adj, gtk_adjustment_get_value(adj),                               0, MAX(req, allocated), -                             allocated * 0.1, -                             allocated * 0.9, +                             step_inc, +                             page_inc,                               allocated);  } @@ -736,8 +771,9 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr)      gint y;                                 /* Ordonnée à garantir         */      GtkWidget *viewport;                    /* Parent avec défilement      */      GtkAdjustment *adj;                     /* Défilement à mettre à jour  */ -    double limit;                           /* Limite à ne pas dépasser    */ - +    gdouble step_inc;                       /* Valeur d'un petit pas       */ +    gdouble page_size;                      /* Taille de l'affichage       */ +    double value;                           /* Valeur courante             */      /*      if (panel->define != NULL) @@ -749,21 +785,33 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr)      {          viewport = gtk_widget_get_parent(GTK_WIDGET(panel)); +        /* Eventuel défilement horizontal */ +          g_object_get(G_OBJECT(viewport), "hadjustment", &adj, NULL); -        limit = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj); -        if (x > limit) -            x = limit; +        step_inc = gtk_adjustment_get_step_increment(adj); +        page_size = gtk_adjustment_get_page_size(adj); +        value = gtk_adjustment_get_value(adj); -        gtk_adjustment_set_value(adj, x); +        if (x < value) +            gtk_adjustment_set_value(adj, x); + +        else if ((x + step_inc) > (value + page_size)) +            gtk_adjustment_set_value(adj, x + step_inc - page_size); + +        /* Eventuel défilement vertical */          g_object_get(G_OBJECT(viewport), "vadjustment", &adj, NULL); -        limit = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj); -        if (y > limit) -            y = limit; +        step_inc = gtk_adjustment_get_step_increment(adj); +        page_size = gtk_adjustment_get_page_size(adj); +        value = gtk_adjustment_get_value(adj); + +        if (y < value) +            gtk_adjustment_set_value(adj, y); -        gtk_adjustment_set_value(adj, y); +        else if ((y + step_inc) > (value + page_size)) +            gtk_adjustment_set_value(adj, y + step_inc - page_size);      } diff --git a/src/gui/status.c b/src/gui/status.c index 2633ba6..3a96ea1 100644 --- a/src/gui/status.c +++ b/src/gui/status.c @@ -75,7 +75,7 @@ static void g_status_info_finalize(GStatusInfo *);  static void update_status_info_for_view(GStatusInfo *, GtkViewPanel *);  /* Imprime la position du parcours courant dans le statut. */ -static void track_caret_address_on_buffer_views(GtkBufferView *, vmpa_t, GStatusInfo *); +static void track_caret_address_on_buffer_views(GtkBufferView *, const vmpa2t *, GStatusInfo *);  /* Concentre l'attention de l'ensemble sur une adresse donnée. */  static void focus_address_in_status_info(GStatusInfo *, GLoadedBinary *, const vmpa2t *); @@ -267,24 +267,42 @@ static void update_status_info_for_view(GStatusInfo *info, GtkViewPanel *view)  *                                                                             *  ******************************************************************************/ -static void track_caret_address_on_buffer_views(GtkBufferView *view, vmpa_t addr, GStatusInfo *info) +static void track_caret_address_on_buffer_views(GtkBufferView *view, const vmpa2t *addr, GStatusInfo *info)  {      GEditorItem *item;                      /* Autre version de l'élément  */ -    char *msg;                              /* Message à transmettre       */ -    char tmp[VMPA_MAX_SIZE];                /* Zone de conversion          */      GLoadedBinary *binary;                  /* Binaire courant             */ -    GExeFormat *format;                     /* Format associé au binaire   */ +    GExeFormat *format;                     /* Format du fichier binaire   */ +    GArchProcessor *proc;                   /* Architecture du binaire     */ +    MemoryDataSize msize;                   /* Taille par défaut           */ +    char *msg;                              /* Message à transmettre       */ +    VMPA_BUFFER(conv);                      /* Zone de conversion          */ +      vmpa_t rel;                             /* Adresse relative à un symb. */      const char *label;                      /* Désignation d'un symbole    */      item = G_EDITOR_ITEM(info); +    binary = g_editor_item_get_current_binary(item); +    format = g_loaded_binary_get_format(binary); +    proc = get_arch_processor_from_format(format); +      /* Adresse brute */ -    msg = strdup(_("Address ")); +    msize = g_arch_processor_get_memory_size(proc); -    snprintf(tmp, VMPA_MAX_SIZE, VMPA_FMT_LONG, addr); -    msg = stradd(msg, tmp); +    msg = strdup(_("Location phys:")); + +    vmpa2_phys_to_string(addr, msize, conv, NULL); +    msg = stradd(msg, conv); + +    msg = stradd(msg, " virt:"); + +    vmpa2_virt_to_string(addr, msize, conv, NULL); +    msg = stradd(msg, conv); + + + +#if 0      /* Relation avec les symboles */ @@ -304,6 +322,9 @@ static void track_caret_address_on_buffer_views(GtkBufferView *view, vmpa_t addr      } +#endif + +      /* Impression */      if (info->msg_id > 0)  | 
